/*******************************************************************************
 * Copyright (C) 2007 The University of Manchester
 *
 *  Modifications to the initial code base are copyright of their
 *  respective authors, or their employers as appropriate.
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public License
 *  as published by the Free Software Foundation; either version 2.1 of
 *  the License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful, but
 *  WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 ******************************************************************************/
package net.sf.taverna.t2.workbench.ui.credentialmanager;

import static java.awt.BorderLayout.CENTER;
import static java.awt.BorderLayout.NORTH;
import static java.awt.BorderLayout.PAGE_END;
import static java.awt.Dialog.ModalExclusionType.APPLICATION_EXCLUDE;
import static java.awt.Toolkit.getDefaultToolkit;
import static javax.swing.JFileChooser.APPROVE_OPTION;
import static javax.swing.JOptionPane.ERROR_MESSAGE;
import static javax.swing.JOptionPane.INFORMATION_MESSAGE;
import static javax.swing.JOptionPane.NO_OPTION;
import static javax.swing.JOptionPane.WARNING_MESSAGE;
import static javax.swing.JOptionPane.YES_NO_OPTION;
import static javax.swing.JOptionPane.YES_OPTION;
import static javax.swing.JOptionPane.showConfirmDialog;
import static javax.swing.JOptionPane.showMessageDialog;
import static javax.swing.JTable.AUTO_RESIZE_ALL_COLUMNS;
import static javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED;
import static javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED;
import static net.sf.taverna.t2.security.credentialmanager.CredentialManager.KeystoreType.KEYSTORE;
import static net.sf.taverna.t2.security.credentialmanager.CredentialManager.KeystoreType.TRUSTSTORE;
import static net.sf.taverna.t2.workbench.ui.credentialmanager.CMStrings.ALERT_TITLE;
import static net.sf.taverna.t2.workbench.ui.credentialmanager.CMStrings.ERROR_TITLE;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.net.URI;
import java.security.Key;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.prefs.Preferences;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.TableColumn;

import net.sf.taverna.t2.security.credentialmanager.CMException;
import net.sf.taverna.t2.security.credentialmanager.CredentialManager;
import net.sf.taverna.t2.security.credentialmanager.CredentialManager.KeystoreType;
import net.sf.taverna.t2.security.credentialmanager.DistinguishedNameParser;
import net.sf.taverna.t2.security.credentialmanager.UsernamePassword;

import org.apache.log4j.Logger;
import org.bouncycastle.openssl.PEMReader;
import org.bouncycastle.openssl.PEMWriter;

/**
 * Provides a UI for the Credential Manager for users to manage their
 * credentials saved by the Credential Manager in Taverna's Keystore and
 * Trustore. Credentials include username and passwords pairs, key pairs, proxy
 * key pairs and trusted certificates of CA's and s. Credentials are stored in
 * two Bouncy Castle "UBER"-type keystores: the Keystore (containing passwords
 * and (normal and proxy) key pairs) and the Truststore (containing trusted
 * certificates).
 *
 * Inspired by the Portlecle tool (http://portecle.sourceforge.net/)
 * and Firefox's Certificate Manager.
 *
 * @author Alex Nenadic
 */

@SuppressWarnings("serial")
public class CredentialManagerUI extends JFrame {
	private static Logger logger = Logger.getLogger(CredentialManagerUI.class);
	/** Default tabbed pane width */
	private static final int DEFAULT_FRAME_WIDTH = 650;
	/** Default tabbed pane height */
	private static final int DEFAULT_FRAME_HEIGHT = 400;
	/** Credential Manager icon (when frame is minimised)*/
	private static final Image credManagerIconImage = getDefaultToolkit()
			.createImage(
					CredentialManagerUI.class
							.getResource("/images/cred_manager_transparent.png"));

	/**
	 * Credential Manager to manage all operations on the Keystore and
	 * Truststore
	 */
	public final CredentialManager credManager;
	private final DistinguishedNameParser dnParser;
	
	////////////// Tabs //////////////

	/**
	 * Tabbed pane to hold tables containing various entries in the Keystore and
	 * Truststore
	 */
	private JTabbedPane keyStoreTabbedPane;
	/** Tab 1: holds passwords table */
	private JPanel passwordsTab = new JPanel(new BorderLayout(10, 10));
	/** Tab 1: name */
	public static final String PASSWORDS = "Passwords";
	/** Tab 2: holds key pairs (user certificates) table */
	private JPanel keyPairsTab = new JPanel(new BorderLayout(10, 10));
	/** Tab 2: name */
	public static final String KEYPAIRS = "Your Certificates";
	/** Tab 3: holds trusted certificates table */
	private JPanel trustedCertificatesTab = new JPanel(new BorderLayout(10, 10));
	/** Tab 3: name */
	public static final String TRUSTED_CERTIFICATES = "Trusted Certificates";

	////////////// Tables //////////////

	/** Password entries' table */
	private JTable passwordsTable;
	/** Key pair entries' table */
	private JTable keyPairsTable;
	/** Trusted certificate entries' table */
	private JTable trustedCertsTable;
	/** Password entry column type */
	public static final String PASSWORD_ENTRY_TYPE = "Password";
	/** Key pair entry column type */
	public static final String KEY_PAIR_ENTRY_TYPE = "Key Pair";
	/** Trusted cert entry column type */
	public static final String TRUST_CERT_ENTRY_TYPE = "Trusted Certificate";

	/**
	 * Overrides the Object's clone method to prevent the singleton object to be
	 * cloned.
	 */
	@Override
	public Object clone() throws CloneNotSupportedException {
		throw new CloneNotSupportedException();
	}

	/**
	 * Creates a new Credential Manager UI's frame.
	 */
	public CredentialManagerUI(CredentialManager credentialManager,
			DistinguishedNameParser dnParser) {
		credManager = credentialManager;
		this.dnParser = dnParser;
		setModalExclusionType(APPLICATION_EXCLUDE);
		// Initialise the UI components
		initComponents();
	}

	private void initComponents() {
		/*
		 * Initialise the tabbed pane that contains the tabs with tabular
		 * representations of the Keystore's content.
		 */
		keyStoreTabbedPane = new JTabbedPane();
		/*
		 * Initialise the tab containing the table for username/password entries
		 * from the Keystore
		 */
		passwordsTable = initTable(PASSWORDS, passwordsTab);
		/*
		 * Initialise the tab containing the table for key pair entries from the
		 * Keystore
		 */
		keyPairsTable = initTable(KEYPAIRS, keyPairsTab);
		/*
		 * Initialise the tab containing the table for proxy entries from the
		 * Keystore
		 */
		//proxiesTable = initTable(PROXIES, proxiesTab);
		/*
		 * Initialise the tab containing the table for trusted certificate
		 * entries from the Truststore
		 */
		trustedCertsTable = initTable(TRUSTED_CERTIFICATES,
				trustedCertificatesTab);
		/*
		 * Set the size of the tabbed pane to the preferred size - the size of
		 * the main application frame depends on it.
		 */
		keyStoreTabbedPane.setPreferredSize(new Dimension(DEFAULT_FRAME_WIDTH,
				DEFAULT_FRAME_HEIGHT));

		JPanel globalButtons = new JPanel(new FlowLayout(FlowLayout.RIGHT));
		JButton resetJavaAuthCache = new JButton("Clear HTTP authentication");
		resetJavaAuthCache.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				clearAuthenticationCache();
			}
		});
		globalButtons.add(resetJavaAuthCache);

		// Button for changing Credential Manager's master password
		JButton changeMasterPasswordButton = new JButton(
				"Change master password");
		changeMasterPasswordButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				changeMasterPassword();
			}
		});
		globalButtons.add(changeMasterPasswordButton);

		// Add change master password to the main application frame
		getContentPane().add(globalButtons, NORTH);
		// Add tabbed pane to the main application frame
		getContentPane().add(keyStoreTabbedPane, CENTER);

		// Handle application close
		addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent evt) {
				closeFrame();
			}
		});
		setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);

		pack();

		// Centre the frame in the centre of the screen
		setLocationRelativeTo(null);

		// Set the frame's icon
		setIconImage(credManagerIconImage);

		// Set the frame's title
		setTitle("Credential Manager");

		// setModal(true);
		// setVisible(true);
	}

	protected void clearAuthenticationCache() {
		if (!credManager.resetAuthCache())
			showMessageDialog(
					this,
					"Java's internal HTTP authentication cache could not be cleared. \n\n"
							+ "Taverna can only clear the cache using an undocumented Java API \n"
							+ "that might not work if you are using a Java VM other than \n"
							+ "Java 6 from Sun. You can restarting Taverna to clear the cache.",
					"Could not clear authentication cache", ERROR_MESSAGE);
		else
			showMessageDialog(
					this,
					"Java's internal HTTP authentication cache has been cleared. \n\n"
							+ "You might also need to edit or delete individual \n"
							+ "password entries in the credential manager \n"
							+ "if a relevant password has previously been saved.",
					"Cleared authentication cache", INFORMATION_MESSAGE);
	}

	protected void changeMasterPassword() {
		ChangeMasterPasswordDialog changePasswordDialog = new ChangeMasterPasswordDialog(
				this, "Change master password", true,
				"Change master password for Credential Manager", credManager);
		changePasswordDialog.setLocationRelativeTo(null);
		changePasswordDialog.setVisible(true);
		String password = changePasswordDialog.getPassword();
		if (password == null) // user cancelled
			return; // do nothing

		try {
			credManager.changeMasterPassword(password);
			showMessageDialog(this, "Master password changed sucessfully",
					ALERT_TITLE, INFORMATION_MESSAGE);
		} catch (CMException cme) {
			/*
			 * Failed to change the master password for Credential Manager -
			 * warn the user
			 */
			String exMessage = "Failed to change master password for Credential Manager";
			logger.error(exMessage);
			showMessageDialog(this, exMessage, ERROR_TITLE, ERROR_MESSAGE);
		}
	}

	/**
	 * Initialise the tabs and tables with the content from the Keystore and Truststore.
	 */
	private JTable initTable(String tableType, JPanel tab) {
		JTable table = null;

		if (tableType.equals(PASSWORDS)) { // Passwords table
			// The Passwords table's data model
			PasswordsTableModel passwordsTableModel = new PasswordsTableModel(credManager);
			// The table itself
			table = new JTable(passwordsTableModel);

			/*
			 * Set the password and alias columns of the Passwords table to be
			 * invisible by removing them from the column model (they will still
			 * present in the table model)
			 * 
			 * Remove the last column first
			 */
			TableColumn aliasColumn = table.getColumnModel().getColumn(5);
			table.getColumnModel().removeColumn(aliasColumn);
			TableColumn passwordColumn = table.getColumnModel().getColumn(4);
			table.getColumnModel().removeColumn(passwordColumn);
			TableColumn lastModifiedDateColumn = table.getColumnModel().getColumn(3);
			table.getColumnModel().removeColumn(lastModifiedDateColumn);

			// Buttons
			JButton newPasswordButton = new JButton("New");
			newPasswordButton.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					newPassword();
				}
			});

			final JButton viewPasswordButton = new JButton("Details");
			viewPasswordButton.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					viewPassword();
				}
			});
			viewPasswordButton.setEnabled(false);

			final JButton editPasswordButton = new JButton("Edit");
			editPasswordButton.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					editPassword();
				}
			});
			editPasswordButton.setEnabled(false);

			final JButton deletePasswordButton = new JButton("Delete");
			deletePasswordButton.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					deletePassword();
				}
			});
			deletePasswordButton.setEnabled(false);

			/*
			 * Selection listener for passwords table to enable/disable action
			 * buttons accordingly
			 */
			class PasswordsTableSelectionListner implements
					ListSelectionListener {
				@Override
				public void valueChanged(ListSelectionEvent e) {
					if (e.getSource() != passwordsTable.getSelectionModel())
						return;
					if (passwordsTable.getSelectedRow() == -1) {
						// nothing is selected
						viewPasswordButton.setEnabled(false);
						editPasswordButton.setEnabled(false);
						deletePasswordButton.setEnabled(false);
					} else {
						if (!viewPasswordButton.isEnabled())
							viewPasswordButton.setEnabled(true);
						if (!editPasswordButton.isEnabled())
							editPasswordButton.setEnabled(true);
						if (!deletePasswordButton.isEnabled())
							deletePasswordButton.setEnabled(true);
					}
				}
			}
			table.getSelectionModel().addListSelectionListener(new PasswordsTableSelectionListner());

			// Panel to hold the buttons
			JPanel bp = new JPanel();
			bp.add(viewPasswordButton);
			bp.add(editPasswordButton);
			bp.add(newPasswordButton);
			bp.add(deletePasswordButton);

			// Add button panel to the tab
			tab.add(bp, PAGE_END);

		} else if (tableType.equals(KEYPAIRS)) { // Key Pairs tab
			// The Key Pairs table's data model
			KeyPairsTableModel keyPairsTableModel = new KeyPairsTableModel(credManager);
			// The table itself
			table = new JTable(keyPairsTableModel);

			/*
			 * Set the alias and service URIs columns of the KayPairs table to
			 * be invisible by removing them from the column model (they will
			 * still present in the table model)
			 * 
			 * Remove the last column first
			 */
			TableColumn aliasColumn = table.getColumnModel().getColumn(6);
			table.getColumnModel().removeColumn(aliasColumn);
			TableColumn serviceURIsColumn = table.getColumnModel().getColumn(5);
			table.getColumnModel().removeColumn(serviceURIsColumn);
			TableColumn lastModifiedDateColumn = table.getColumnModel().getColumn(4);
			table.getColumnModel().removeColumn(lastModifiedDateColumn);

			// Buttons
			final JButton viewKeyPairButton = new JButton("Details");
			viewKeyPairButton.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					viewCertificate();
				}
			});
			viewKeyPairButton.setEnabled(false);

			JButton importKeyPairButton = new JButton("Import");
			importKeyPairButton.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					importKeyPair();
				}
			});

			final JButton exportKeyPairButton = new JButton("Export");
			exportKeyPairButton.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					exportKeyPair();
				}
			});
			exportKeyPairButton.setEnabled(false);

			final JButton deleteKeyPairButton = new JButton("Delete");
			deleteKeyPairButton.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					deleteKeyPair();
				}
			});
			deleteKeyPairButton.setEnabled(false);

			/*
			 * Selection listener for key pairs table to enable/disable action
			 * buttons accordingly
			 */
			class KeyPairsTableSelectionListner implements
					ListSelectionListener {
				@Override
				public void valueChanged(ListSelectionEvent e) {
					if (e.getSource() != keyPairsTable.getSelectionModel())
						return;
					if (keyPairsTable.getSelectedRow() == -1) {
						// nothing is selected
						viewKeyPairButton.setEnabled(false);
						exportKeyPairButton.setEnabled(false);
						deleteKeyPairButton.setEnabled(false);
					} else {
						if (!viewKeyPairButton.isEnabled())
							viewKeyPairButton.setEnabled(true);
						if (!exportKeyPairButton.isEnabled())
							exportKeyPairButton.setEnabled(true);
						if (!deleteKeyPairButton.isEnabled())
							deleteKeyPairButton.setEnabled(true);
					}
				}
			}
			table.getSelectionModel().addListSelectionListener(
					new KeyPairsTableSelectionListner());

			// Panel to hold the buttons
			JPanel bp = new JPanel();
			bp.add(viewKeyPairButton);
			bp.add(importKeyPairButton);
			bp.add(exportKeyPairButton);
			bp.add(deleteKeyPairButton);

			// Add button panel to the tab
			tab.add(bp, PAGE_END);
		} else if (tableType.equals(TRUSTED_CERTIFICATES)) { // Certificates tab

			// The Trusted Certificate table's data model
			TrustedCertsTableModel trustedCertificatesTableModel = new TrustedCertsTableModel(credManager);
			// The table itself
			table = new JTable(trustedCertificatesTableModel);

			/*
			 * Set the alias columns of the Trusted Certs table to be invisible
			 * by removing them from the column model (they will still be
			 * present in the table model)
			 * 
			 * Remove the last column first
			 */
			TableColumn aliasColumn = table.getColumnModel().getColumn(5);
			table.getColumnModel().removeColumn(aliasColumn);
			TableColumn lastModifiedDateColumn = table.getColumnModel().getColumn(4);
			table.getColumnModel().removeColumn(lastModifiedDateColumn);

			// Buttons
			final JButton viewTrustedCertificateButton = new JButton("Details");
			viewTrustedCertificateButton
					.addActionListener(new ActionListener() {
						@Override
						public void actionPerformed(ActionEvent e) {
							viewCertificate();
						}
					});
			viewTrustedCertificateButton.setEnabled(false);

			JButton importTrustedCertificateButton = new JButton("Import");
			importTrustedCertificateButton
					.addActionListener(new ActionListener() {
						@Override
						public void actionPerformed(ActionEvent e) {
							importTrustedCertificate();
						}
					});

			final JButton exportTrustedCertificateButton = new JButton("Export");
			exportTrustedCertificateButton
					.addActionListener(new ActionListener() {
						@Override
						public void actionPerformed(ActionEvent e) {
							exportTrustedCertificate();
						}
					});
			exportTrustedCertificateButton.setEnabled(false);

			final JButton deleteTrustedCertificateButton = new JButton("Delete");
			deleteTrustedCertificateButton
					.addActionListener(new ActionListener() {
						@Override
						public void actionPerformed(ActionEvent e) {
							deleteTrustedCertificate();
						}
					});
			deleteTrustedCertificateButton.setEnabled(false);

			// Selection listener for trusted certs table to enable/disable action buttons accordingly
			class TrustedCertsTableSelectionListener implements
					ListSelectionListener {
				@Override
				public void valueChanged(ListSelectionEvent e) {
					if (e.getSource() != trustedCertsTable.getSelectionModel())
						return;
					if (trustedCertsTable.getSelectedRow() == -1) {
						// nothing is selected
						viewTrustedCertificateButton.setEnabled(false);
						exportTrustedCertificateButton.setEnabled(false);
						deleteTrustedCertificateButton.setEnabled(false);
					} else {
						if (!viewTrustedCertificateButton.isEnabled())
							viewTrustedCertificateButton.setEnabled(true);
						if (!exportTrustedCertificateButton.isEnabled())
							exportTrustedCertificateButton.setEnabled(true);
						if (!deleteTrustedCertificateButton.isEnabled())
							deleteTrustedCertificateButton.setEnabled(true);
					}
				}
			}
			table.getSelectionModel().addListSelectionListener(
					new TrustedCertsTableSelectionListener());

			// Panel to hold the buttons
			JPanel bp = new JPanel();
			bp.add(viewTrustedCertificateButton);
			bp.add(importTrustedCertificateButton);
			bp.add(exportTrustedCertificateButton);
			bp.add(deleteTrustedCertificateButton);

			// Add button panel to the tab
			tab.add(bp, PAGE_END);
		} else {
			throw new RuntimeException("Unknown table type " + tableType);
		}

		table.setShowGrid(false);
		table.setRowMargin(0);
		table.getColumnModel().setColumnMargin(0);
		table.getTableHeader().setReorderingAllowed(false);
		table.setAutoResizeMode(AUTO_RESIZE_ALL_COLUMNS);
		// Top accommodates entry icons with 2 pixels spare space (images are
		// 16x16 pixels)
		table.setRowHeight(18);

		// Add custom renderrers for the table headers and cells
		for (int iCnt = 0; iCnt < table.getColumnCount(); iCnt++) {
			TableColumn column = table.getColumnModel().getColumn(iCnt);
			column.setHeaderRenderer(new TableHeaderRenderer());
			column.setCellRenderer(new TableCellRenderer());
		}

		// Make the first column small and not resizable (it holds icons to
		// represent different entry types)
		TableColumn typeCol = table.getColumnModel().getColumn(0);
		typeCol.setResizable(false);
		typeCol.setMinWidth(20);
		typeCol.setMaxWidth(20);
		typeCol.setPreferredWidth(20);

		// Set the size for the second column
		// (i.e. Service URI column of Passwords table, and
		// Certificate Name column of the Kay Pairs and Trusted Certificates tables)
		// We do not care about the size of other columns.
		TableColumn secondCol = table.getColumnModel().getColumn(1);
		secondCol.setMinWidth(20);
		secondCol.setMaxWidth(10000);
		secondCol.setPreferredWidth(300);

		// Put the table into a scroll pane
		JScrollPane jspTableScrollPane = new JScrollPane(table,
				VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED);
		jspTableScrollPane.getViewport().setBackground(table.getBackground());

		// Put the scroll pane on the tab panel
		tab.add(jspTableScrollPane, CENTER);
		jspTableScrollPane.setBorder(new EmptyBorder(3, 3, 3, 3));

		/*
		 * Add mouse listeners to show an entry's details if it is
		 * double-clicked
		 */
		table.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent evt) {
				tableDoubleClick(evt);
			}
		});

		// Add the tab to the tabbed pane
		keyStoreTabbedPane.addTab(tableType, tab);

		return table;
	}

	/**
	 * Displays the details of the username/password pair entry - this includes
	 * showing the plaintext password and service URI for this entry.
	 */
	private void viewPassword() {
		// Which username/password pair entry has been selected, if any?
		int iRow = passwordsTable.getSelectedRow();
		if (iRow == -1) // no row currently selected
			return;

		// Get current values for service URI, username and password
		String serviceURI = (String) passwordsTable.getValueAt(iRow, 1); // current entry's service URI

		String username = (String) passwordsTable.getValueAt(iRow, 2); // current entry's username

		/*
		 * Because the password column is not visible we call the getValueAt
		 * method on the table model rather than at the JTable
		 */
		String password = (String) passwordsTable.getModel()
				.getValueAt(iRow, 4); // current entry's password value

		// Let the user view service URI, username and password of the entry
		ViewUsernamePasswordEntryDialog viewServicePassDialog = new ViewUsernamePasswordEntryDialog(
				this, serviceURI, username, password);

		viewServicePassDialog.setLocationRelativeTo(this);
		viewServicePassDialog.setVisible(true);
	}

	/**
	 * Lets a user insert a new username/password/service URI tuple to the
	 * Keystore.
	 */
	private void newPassword() {
		URI serviceURI = null; // service URI
		String username = null; // username
		String password = null; // password

		// Loop until the user cancels or enters everything correctly
		while (true) {
			/*
			 * Let the user insert a new password entry (by specifying service
			 * URI, username and password)
			 */
			NewEditPasswordEntryDialog newPasswordDialog = new NewEditPasswordEntryDialog(
					this, "New username and password for a service", true,
					serviceURI, username, password, credManager);
			newPasswordDialog.setLocationRelativeTo(this);
			newPasswordDialog.setVisible(true);

			serviceURI = newPasswordDialog.getServiceURI(); // get service URI
			username = newPasswordDialog.getUsername(); // get username
			password = newPasswordDialog.getPassword(); // get password

			if (password == null) { // user cancelled - any of the above three
				// fields is null
				// do nothing
				return;
			}

			/*
			 * Check if a password entry with the given service URI already
			 * exists in the Keystore. We ask this here as the user may wish to
			 * overwrite the existing password entry. Checking for key pair
			 * entries' URIs is done in the NewEditPasswordEntry dialog.
			 */

			/*
			 * Get list of service URIs for all the password entries in the
			 * Keystore
			 */
			List<URI> serviceURIs = null;
			try {
				serviceURIs = credManager
						.getServiceURIsForAllUsernameAndPasswordPairs();
			} catch (CMException cme) {
				showMessageDialog(this, "Failed to get service URIs for all username and password pairs "
						+ "to check if the entered service URI already exists",
						ERROR_TITLE, ERROR_MESSAGE);
				return;
			}
			if (serviceURIs.contains(serviceURI)) { // if such a URI already
				// exists
				// Ask if the user wants to overwrite it
				int answer = showConfirmDialog(
								this,
								"Credential Manager already contains a password entry with the same service URI.\n"
										+ "Do you want to overwrite it?",
								ALERT_TITLE,
								YES_NO_OPTION);

				// Add the new password entry in the Keystore
				try {
					if (answer == YES_OPTION) {
						credManager.addUsernameAndPasswordForService(
								new UsernamePassword(username, password),
								serviceURI);
						break;
					}
				} catch (CMException cme) {
					showMessageDialog(
							this,
							"Credential Manager failed to insert a new username and password pair",
							ERROR_TITLE, ERROR_MESSAGE);
				}
				/*
				 * Otherwise show the same window with the entered service URI,
				 * username and password values
				 */
			} else
				// Add the new password entry in the Keystore
				try {
					credManager.addUsernameAndPasswordForService(new UsernamePassword(username,
							password), serviceURI);
					break;
				} catch (CMException cme) {
					showMessageDialog(
							this,
							"Credential Manager failed to insert a new username and password pair",
							ERROR_TITLE, ERROR_MESSAGE);
				}
		}
	}

	/**
	 * Lets a user insert a new username/password pair for a given service URI
	 * to the Keystore.
	 */
	public void newPasswordForService(URI serviceURI) {
		/*
		 * As this method can be called from outside of Credential Manager UI,
		 * e.g. from wsdl-activity-ui or rshell-activity-ui to pop up a dialog
		 * to ask the user for username and password, we also want to make sure
		 * the main Credential Manager UI Dialog is visible as it may be clearer
		 * to the user what is going on
		 */
		if (!isVisible() || getState() == ICONIFIED)
			setVisible(true);

		// Make sure password tab is selected as this method may
		// be called from outside of Credential Manager UI.
		keyStoreTabbedPane.setSelectedComponent(passwordsTab);

		String username = null; // username
		String password = null; // password

		// Loop until the user cancels or enters everything correctly
		while (true) {

//			if(!this.isVisible()){ // if Cred Man UI is already showing but e.g. obscured by another window or minimised
//				// Do not bring it up!
//			} // actually we now want to show it as it makes it clearer to the user what is going on

			// Let the user insert a new password entry for the given service
			// URI (by specifying username and password)
			NewEditPasswordEntryDialog newPasswordDialog = new NewEditPasswordEntryDialog(
					this, "New username and password for a service", true,
					serviceURI, username, password, credManager);
			newPasswordDialog.setLocationRelativeTo(this);
			newPasswordDialog.setVisible(true);

			serviceURI = newPasswordDialog.getServiceURI(); // get service URI
			username = newPasswordDialog.getUsername(); // get username
			password = newPasswordDialog.getPassword(); // get password

			if (password == null) // user cancelled - any of the above three
				// fields is null
				// do nothing
				return;

			/*
			 * Check if a password entry with the given service URI already
			 * exists in the Keystore. We ask this here as the user may wish to
			 * overwrite the existing password entry. Checking for key pair
			 * entries' URIs is done in the NewEditPasswordEntry dialog.
			 */

			// Get list of service URIs for all the password entries in the
			// Keystore
			List<URI> serviceURIs = null;
			try {
				serviceURIs = credManager
						.getServiceURIsForAllUsernameAndPasswordPairs();
			} catch (CMException cme) {
				showMessageDialog(this, "Failed to get service URIs for all username and password pairs "
						+ "to check if the entered service URI already exists",
						ERROR_TITLE, ERROR_MESSAGE);
				return;
			}
			if (serviceURIs.contains(serviceURI)) { // if such a URI already
				// exists
				// Ask if the user wants to overwrite it
				int answer = showConfirmDialog(
						this,
						"Credential Manager already contains a password entry with the same service URI.\n"
								+ "Do you want to overwrite it?", ALERT_TITLE,
						YES_NO_OPTION);

				// Add the new password entry in the Keystore
				try {
					if (answer == YES_OPTION) {
						credManager.addUsernameAndPasswordForService(
								new UsernamePassword(username, password),
								serviceURI);
						break;
					}
				} catch (CMException cme) {
					String exMessage = "Credential Manager failed to insert a new username and password pair";
					showMessageDialog(this, exMessage, ERROR_TITLE,
							ERROR_MESSAGE);
				}
				// Otherwise show the same window with the entered service
				// URI, username and password values
			} else
				// Add the new password entry in the Keystore
				try {
					credManager.addUsernameAndPasswordForService(new UsernamePassword(username,
							password), serviceURI);
					break;
				} catch (CMException cme) {
					showMessageDialog(this, "Credential Manager failed to insert a new username and password pair",
							ERROR_TITLE,
							ERROR_MESSAGE);
				}
		}
	}

	/**
	 * Lets a user edit a username and password entry or their related service
	 * URI to the Keystore.
	 */
	private void editPassword() {
		// Which password entry has been selected?
		int iRow = passwordsTable.getSelectedRow();
		if (iRow == -1) { // no row currently selected
			return;
		}

		// Get current values for service URI, username and password
		URI serviceURI = URI.create((String) passwordsTable.getValueAt(iRow, 1)); // current entry's service URI

		String username = (String) passwordsTable.getValueAt(iRow, 2); // current entry's username

		/*
		 * Because the password column is not visible we call the getValueAt
		 * method on the table model rather than at the JTable
		 */
		String password = (String) passwordsTable.getModel()
				.getValueAt(iRow, 4); // current entry's password value

		while (true) { // loop until user cancels or enters everything correctly
			// Let the user edit service URI, username or password of a password entry
			NewEditPasswordEntryDialog editPasswordDialog = new NewEditPasswordEntryDialog(
					this, "Edit username and password for a service", true,
					serviceURI, username, password, credManager);

			editPasswordDialog.setLocationRelativeTo(this);
			editPasswordDialog.setVisible(true);

			// New values
			URI newServiceURI = editPasswordDialog.getServiceURI(); // get new service URI
			String newUsername = editPasswordDialog.getUsername(); // get new username
			String newPassword = editPasswordDialog.getPassword(); // get new password

			if (newPassword == null) // user cancelled - any of the above three
				// fields is null
				// do nothing
				return;

			// Is anything actually modified?
			boolean isModified = !serviceURI.equals(newServiceURI)
					|| !username.equals(newUsername)
					|| !password.equals(newPassword);

			if (isModified) {
				/*
				 * Check if a different password entry with the new URI (i.e.
				 * alias) already exists in the Keystore We ask this here as the
				 * user may wish to overwrite that other password entry.
				 */

				// Get list of URIs for all passwords in the Keystore
				List<URI> serviceURIs = null;
				try {
					serviceURIs = credManager
							.getServiceURIsForAllUsernameAndPasswordPairs();
				} catch (CMException cme) {
					showMessageDialog(this, "Failed to get service URIs for all username and password pairs "
							+ "to check if the modified entry already exists",
							ERROR_TITLE,
							ERROR_MESSAGE);
					return;
				}

				// If the modified service URI already exists and is not the
				// currently selected one
				if (!newServiceURI.equals(serviceURI)
						&& serviceURIs.contains(newServiceURI)) {
					int answer = showConfirmDialog(
							this,
							"The Keystore already contains username and password pair for the entered service URI.\n"
									+ "Do you want to overwrite it?",
							ALERT_TITLE, YES_NO_OPTION);

					try {
						if (answer == YES_OPTION) {
							/*
							 * Overwrite that other entry entry and save the new
							 * one in its place. Also remove the current one
							 * that we are editing - as it is replacing the
							 * other entry.
							 */
							credManager
									.deleteUsernameAndPasswordForService(serviceURI);
							credManager.addUsernameAndPasswordForService(
									new UsernamePassword(newUsername,
											newPassword), newServiceURI);
							break;
						}
					} catch (CMException cme) {
						showMessageDialog(
								this,
								"Failed to update the username and password pair in the Keystore",
								ERROR_TITLE, ERROR_MESSAGE);
					}
					// Otherwise show the same window with the entered
					// service URI, username and password values
				} else
					try {
						if (!newServiceURI.equals(serviceURI))
							credManager
									.deleteUsernameAndPasswordForService(serviceURI);
						credManager.addUsernameAndPasswordForService(
								new UsernamePassword(newUsername, newPassword), newServiceURI);
						break;
					} catch (CMException cme) {
						showMessageDialog(
								this,
								"Failed to update the username and password pair in the Keystore",
								ERROR_TITLE, ERROR_MESSAGE);
					}
			} else // nothing actually modified
				break;
		}
	}

	/**
	 * Lets the user delete the selected username and password entries from the
	 * Keystore.
	 */
	private void deletePassword() {
		// Which entries have been selected?
		int[] selectedRows = passwordsTable.getSelectedRows();
		if (selectedRows.length == 0) // no password entry selected
			return;

		// Ask user to confirm the deletion
		if (showConfirmDialog(
				null,
				"Are you sure you want to delete the selected username and password entries?",
				ALERT_TITLE, YES_NO_OPTION) != YES_OPTION)
			return;

		String exMessage = null;
		for (int i = selectedRows.length - 1; i >= 0; i--) { // delete from backwards
			// Get service URI for the current entry
			URI serviceURI = URI.create((String) passwordsTable.getValueAt(selectedRows[i], 1));
			// current entry's service URI
			try {
				// Delete the password entry from the Keystore
				credManager.deleteUsernameAndPasswordForService(serviceURI);
			} catch (CMException cme) {
				exMessage = "Failed to delete the username and password pair from the Keystore";
			}
		}
		if (exMessage != null)
			showMessageDialog(this, exMessage, ERROR_TITLE, ERROR_MESSAGE);
	}

	/**
	 * Shows the contents of a (user or trusted) certificate.
	 */
	private void viewCertificate() {
		int selectedRow = -1;
		String alias = null;
		X509Certificate certToView = null;
		ArrayList<String> serviceURIs = null;
		KeystoreType keystoreType = null;

		// Are we showing user's public key certificate?
		if (keyPairsTab.isShowing()) {
			keystoreType = KEYSTORE;
			selectedRow = keyPairsTable.getSelectedRow();

			if (selectedRow != -1)
				/*
				 * Because the alias column is not visible we call the
				 * getValueAt method on the table model rather than at the
				 * JTable
				 */
				alias = (String) keyPairsTable.getModel().getValueAt(selectedRow, 6); // current entry's Keystore alias
		}
		// Are we showing trusted certificate?
		else if (trustedCertificatesTab.isShowing()) {
			keystoreType = TRUSTSTORE;
			selectedRow = trustedCertsTable.getSelectedRow();

			if (selectedRow != -1)
				/*
				 * Get the selected trusted certificate entry's Truststore alias
				 * Alias column is invisible so we get the value from the table
				 * model
				 */
				alias = (String) trustedCertsTable.getModel().getValueAt(
						selectedRow, 5);
		}

		try {
			if (selectedRow != -1) { // something has been selected
				// Get the entry's certificate
				certToView = dnParser.convertCertificate(credManager
						.getCertificate(keystoreType, alias));

				// Show the certificate's contents to the user
				ViewCertDetailsDialog viewCertDetailsDialog = new ViewCertDetailsDialog(
						this, "Certificate details", true, certToView,
						serviceURIs, dnParser);
				viewCertDetailsDialog.setLocationRelativeTo(this);
				viewCertDetailsDialog.setVisible(true);
			}
		} catch (CMException cme) {
			String exMessage = "Failed to get certificate details to display to the user";
			logger.error(exMessage, cme);
			showMessageDialog(this, exMessage, ERROR_TITLE, ERROR_MESSAGE);
		}
	}

	/**
	 * Lets a user import a key pair from a PKCS #12 keystore file to the
	 * Keystore.
	 */
	private void importKeyPair() {
		/*
		 * Let the user choose a PKCS #12 file (keystore) containing a public
		 * and private key pair to import
		 */
		File importFile = selectImportExportFile(
				"PKCS #12 file to import from", // title
				new String[] { ".p12", ".pfx" }, // array of file extensions
				// for the file filter
				"PKCS#12 Files (*.p12, *.pfx)", // description of the filter
				"Import", // text for the file chooser's approve button
				"keyPairDir"); // preference string for saving the last chosen directory

		if (importFile == null)
			return;

		// The PKCS #12 keystore is not a file
		if (!importFile.isFile()) {
			showMessageDialog(this, "Your selection is not a file",
					ALERT_TITLE, WARNING_MESSAGE);
			return;
		}

		// Get the user to enter the password that was used to encrypt the
		// private key contained in the PKCS #12 file
		GetPasswordDialog getPasswordDialog = new GetPasswordDialog(this,
				"Import key pair entry", true,
				"Enter the password that was used to encrypt the PKCS #12 file");
		getPasswordDialog.setLocationRelativeTo(this);
		getPasswordDialog.setVisible(true);

		String pkcs12Password = getPasswordDialog.getPassword();

		if (pkcs12Password == null) // user cancelled
			return;
		else if (pkcs12Password.isEmpty()) // empty password
			// FIXME: Maybe user did not have the password set for the private key???
			return;

		try {
			// Load the PKCS #12 keystore from the file
			// (this is using the BouncyCastle provider !!!)
			KeyStore pkcs12Keystore = credManager.loadPKCS12Keystore(importFile,
					pkcs12Password);

			/*
			 * Display the import key pair dialog supplying all the private keys
			 * stored in the PKCS #12 file (normally there will be only one
			 * private key inside, but could be more as this is a keystore after
			 * all).
			 */
			NewKeyPairEntryDialog importKeyPairDialog = new NewKeyPairEntryDialog(
					this, "Credential Manager", true, pkcs12Keystore, dnParser);
			importKeyPairDialog.setLocationRelativeTo(this);
			importKeyPairDialog.setVisible(true);

			// Get the private key and certificate chain of the key pair
			Key privateKey = importKeyPairDialog.getPrivateKey();
			Certificate[] certChain = importKeyPairDialog.getCertificateChain();

			if (privateKey == null || certChain == null)
				// User did not select a key pair for import or cancelled
				return;

			/*
			 * Check if a key pair entry with the same alias already exists in
			 * the Keystore
			 */
			if (credManager.hasKeyPair(privateKey, certChain)
					&& showConfirmDialog(this,
							"The keystore already contains the key pair entry with the same private key.\n"
									+ "Do you want to overwrite it?",
							ALERT_TITLE, YES_NO_OPTION) != YES_OPTION)
				return;

			// Place the private key and certificate chain into the Keystore
			credManager.addKeyPair(privateKey, certChain);

			// Display success message
			showMessageDialog(this, "Key pair import successful", ALERT_TITLE,
					INFORMATION_MESSAGE);
		} catch (Exception ex) { // too many exceptions to catch separately
			String exMessage = "Failed to import the key pair entry to the Keystore. "
					+ ex.getMessage();
			logger.error(exMessage, ex);
			showMessageDialog(this, exMessage, ERROR_TITLE, ERROR_MESSAGE);
		}
	}

	/**
	 * Lets a user export user's private and public key pair to a PKCS #12
	 * keystore file.
	 */
	private void exportKeyPair() {
		// Which key pair entry has been selected?
		int selectedRow = keyPairsTable.getSelectedRow();
		if (selectedRow == -1) // no row currently selected
			return;

		// Get the key pair entry's Keystore alias
		String alias = (String) keyPairsTable.getModel().getValueAt(selectedRow, 6);

		// Let the user choose a PKCS #12 file (keystore) to export public and
		// private key pair to
		File exportFile = selectImportExportFile("Select a file to export to", // title
				new String[] { ".p12", ".pfx" }, // array of file extensions
				// for the file filter
				"PKCS#12 Files (*.p12, *.pfx)", // description of the filter
				"Export", // text for the file chooser's approve button
				"keyPairDir"); // preference string for saving the last chosen directory

		if (exportFile == null)
			return;

		// If file already exist - ask the user if he wants to overwrite it
		if (exportFile.isFile()
				&& showConfirmDialog(this,
						"The file with the given name already exists.\n"
								+ "Do you want to overwrite it?", ALERT_TITLE,
						YES_NO_OPTION) == NO_OPTION)
			return;

		// Get the user to enter the password for the PKCS #12 keystore file
		GetPasswordDialog getPasswordDialog = new GetPasswordDialog(this,
				"Credential Manager", true,
				"Enter the password for protecting the exported key pair");
		getPasswordDialog.setLocationRelativeTo(this);
		getPasswordDialog.setVisible(true);

		String pkcs12Password = getPasswordDialog.getPassword();

		if (pkcs12Password == null) { // user cancelled or empty password
			// Warn the user
			showMessageDialog(
					this,
					"You must supply a password for protecting the exported key pair.",
					ALERT_TITLE, INFORMATION_MESSAGE);
			return;
		}

		// Export the key pair
		try {
			credManager.exportKeyPair(alias, exportFile, pkcs12Password);
			showMessageDialog(this, "Key pair export successful", ALERT_TITLE,
					INFORMATION_MESSAGE);
		} catch (CMException cme) {
			showMessageDialog(this, cme.getMessage(), ERROR_TITLE,
					ERROR_MESSAGE);
		}
	}

	/**
	 * Lets a user delete selected key pair entries from the Keystore.
	 */
	private void deleteKeyPair() {
		// Which entries have been selected?
		int[] selectedRows = keyPairsTable.getSelectedRows();
		if (selectedRows.length == 0) // no key pair entry selected
			return;

		// Ask user to confirm the deletion
		if (showConfirmDialog(null,
				"Are you sure you want to delete the selected key pairs?",
				ALERT_TITLE, YES_NO_OPTION) != YES_OPTION)
			return;

		String exMessage = null;
		for (int i = selectedRows.length - 1; i >= 0; i--) { // delete from backwards
			// Get the alias for the current entry
			String alias = (String) keyPairsTable.getModel().getValueAt(
					selectedRows[i], 6);
			try {
				// Delete the key pair entry from the Keystore
				credManager.deleteKeyPair(alias);
			} catch (CMException cme) {
				logger.warn("failed to delete " + alias, cme);
				exMessage = "Failed to delete the key pair(s) from the Keystore";
			}
		}
		if (exMessage != null)
			showMessageDialog(this, exMessage, ERROR_TITLE, ERROR_MESSAGE);
	}

	/**
	 * Lets a user import a trusted certificate from a PEM or DER encoded file
	 * into the Truststore.
	 */
	private void importTrustedCertificate() {
		// Let the user choose a file containing trusted certificate(s) to
		// import
		File certFile = selectImportExportFile(
				"Certificate file to import from", // title
				new String[] { ".pem", ".crt", ".cer", ".der", "p7", ".p7c" }, // file extensions filters
				"Certificate Files (*.pem, *.crt, , *.cer, *.der, *.p7, *.p7c)", // filter descriptions
				"Import", // text for the file chooser's approve button
				"trustedCertDir"); // preference string for saving the last chosen directory
		if (certFile == null)
			return;

		// Load the certificate(s) from the file
		ArrayList<X509Certificate> trustCertsList = new ArrayList<>();
		CertificateFactory cf;
		try {
			cf = CertificateFactory.getInstance("X.509");
		} catch (Exception e) {
			// Nothing we can do! Things are badly misconfigured
			cf = null;
		}

		if (cf != null) {
			try (FileInputStream fis = new FileInputStream(certFile)) {
				for (Certificate cert : cf.generateCertificates(fis))
					trustCertsList.add((X509Certificate) cert);
			} catch (Exception cex) {
				// Do nothing
			}

			if (trustCertsList.size() == 0) {
				// Could not load certificates as any of the above types
				try (FileInputStream fis = new FileInputStream(certFile);
						PEMReader pr = new PEMReader(
								new InputStreamReader(fis), null, cf
										.getProvider().getName())) {
					/*
					 * Try as openssl PEM format - which sligtly differs from
					 * the one supported by JCE
					 */
					Object cert;
					while ((cert = pr.readObject()) != null)
						if (cert instanceof X509Certificate)
							trustCertsList.add((X509Certificate) cert);
				} catch (Exception cex) {
					// do nothing
				}
			}
		}

		if (trustCertsList.size() == 0) {
			/* Failed to load certifcate(s) using any of the known encodings */
			showMessageDialog(this,
					"Failed to load certificate(s) using any of the known encodings -\n"
							+ "file format not recognised.", ERROR_TITLE,
					ERROR_MESSAGE);
			return;
		}

		// Show the list of certificates contained in the file for the user to
		// select the ones to import
		NewTrustCertsDialog importTrustCertsDialog = new NewTrustCertsDialog(this,
				"Credential Manager", true, trustCertsList, dnParser);

		importTrustCertsDialog.setLocationRelativeTo(this);
		importTrustCertsDialog.setVisible(true);
		List<X509Certificate> selectedTrustCerts = importTrustCertsDialog
				.getTrustedCertificates(); // user-selected trusted certs to import

		// If user cancelled or did not select any cert to import
		if (selectedTrustCerts == null || selectedTrustCerts.isEmpty())
			return;

		try {
			for (X509Certificate cert : selectedTrustCerts)
				// Import the selected trusted certificates
				credManager.addTrustedCertificate(cert);

			// Display success message
			showMessageDialog(this, "Trusted certificate(s) import successful",
					ALERT_TITLE, INFORMATION_MESSAGE);
		} catch (CMException cme) {
			String exMessage = "Failed to import trusted certificate(s) to the Truststore";
			logger.error(exMessage, cme);
			showMessageDialog(this, exMessage, ERROR_TITLE, ERROR_MESSAGE);
		}
	}

	/**
	 * Lets the user export one (at the moment) or more (in future) trusted
	 * certificate entries to a PEM-encoded file.
	 */
	private boolean exportTrustedCertificate() {
		// Which trusted certificate has been selected?
		int selectedRow = trustedCertsTable.getSelectedRow();
		if (selectedRow == -1) // no row currently selected
			return false;

		// Get the trusted certificate entry's Keystore alias
		String alias = (String) trustedCertsTable.getModel()
				.getValueAt(selectedRow, 3);
		// the alias column is invisible so we get the value from the table
		// model

		// Let the user choose a file to export to
		File exportFile = selectImportExportFile("Select a file to export to", // title
				new String[] { ".pem" }, // array of file extensions for the
				// file filter
				"Certificate Files (*.pem)", // description of the filter
				"Export", // text for the file chooser's approve button
				"trustedCertDir"); // preference string for saving the last chosen directory
		if (exportFile == null)
			return false;

		// If file already exist - ask the user if he wants to overwrite it
		if (exportFile.isFile()
				&& showConfirmDialog(this,
						"The file with the given name already exists.\n"
								+ "Do you want to overwrite it?", ALERT_TITLE,
						YES_NO_OPTION) == NO_OPTION)
			return false;

		// Export the trusted certificate
		try (PEMWriter pw = new PEMWriter(new FileWriter(exportFile))) {
			// Get the trusted certificate
			pw.writeObject(credManager.getCertificate(TRUSTSTORE, alias));
		} catch (Exception ex) {
			String exMessage = "Failed to export the trusted certificate from the Truststore.";
			logger.error(exMessage, ex);
			showMessageDialog(this, exMessage, ERROR_TITLE, ERROR_MESSAGE);
			return false;
		}
		showMessageDialog(this, "Trusted certificate export successful",
				ALERT_TITLE, INFORMATION_MESSAGE);
		return true;
	}

	/**
	 * Lets a user delete the selected trusted certificate entries from the
	 * Truststore.
	 */
	private void deleteTrustedCertificate() {
		// Which entries have been selected?
		int[] selectedRows = trustedCertsTable.getSelectedRows();
		if (selectedRows.length == 0) // no trusted cert entry selected
			return;

		// Ask user to confirm the deletion
		if (showConfirmDialog(
				null,
				"Are you sure you want to delete the selected trusted certificate(s)?",
				ALERT_TITLE, YES_NO_OPTION) != YES_OPTION)
			return;

		String exMessage = null;
		for (int i = selectedRows.length - 1; i >= 0; i--) { // delete from backwards
			// Get the alias for the current entry
			String alias = (String) trustedCertsTable.getModel().getValueAt(
					selectedRows[i], 5);
			try {
				// Delete the trusted certificate entry from the Truststore
				credManager.deleteTrustedCertificate(alias);
			} catch (CMException cme) {
				exMessage = "Failed to delete the trusted certificate(s) from the Truststore";
				logger.error(exMessage, cme);
			}
		}
		if (exMessage != null)
			showMessageDialog(this, exMessage, ERROR_TITLE, ERROR_MESSAGE);
	}

	/**
	 * If double click on a table occured - show the
	 * details of the table entry.
	 */
	private void tableDoubleClick(MouseEvent evt) {
		if (evt.getClickCount() > 1) { // is it a double click?
			// Which row was clicked on (if any)?
			Point point = new Point(evt.getX(), evt.getY());
			int row = ((JTable) evt.getSource()).rowAtPoint(point);
			if (row == -1)
				return;
			// Which table the click occured on?
			if (((JTable) evt.getSource()).getModel() instanceof PasswordsTableModel)
				// Passwords table
				viewPassword();
			else if (((JTable) evt.getSource()).getModel() instanceof KeyPairsTableModel)
				// Key pairs table
				viewCertificate();
			else
				// Trusted certificates table
				viewCertificate();
		}
	}

	/**
	 * Lets the user select a file to export to or import from a key pair or a
	 * certificate.
	 */
	private File selectImportExportFile(String title, String[] filter,
			String description, String approveButtonText, String prefString) {
		Preferences prefs = Preferences
				.userNodeForPackage(CredentialManagerUI.class);
		String keyPairDir = prefs.get(prefString,
				System.getProperty("user.home"));
		JFileChooser fileChooser = new JFileChooser();
		fileChooser.addChoosableFileFilter(new CryptoFileFilter(filter,
				description));
		fileChooser.setDialogTitle(title);
		fileChooser.setMultiSelectionEnabled(false);
		fileChooser.setCurrentDirectory(new File(keyPairDir));

		if (fileChooser.showDialog(this, approveButtonText) != APPROVE_OPTION)
			return null;

		File selectedFile = fileChooser.getSelectedFile();
		prefs.put(prefString, fileChooser.getCurrentDirectory().toString());
		return selectedFile;
	}

	private void closeFrame() {
		setVisible(false);
		dispose();
	}
}
