http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-credential-manager-ui/src/main/java/org/apache/taverna/workbench/ui/credentialmanager/ChangeMasterPasswordDialog.java
----------------------------------------------------------------------
diff --git 
a/taverna-credential-manager-ui/src/main/java/org/apache/taverna/workbench/ui/credentialmanager/ChangeMasterPasswordDialog.java
 
b/taverna-credential-manager-ui/src/main/java/org/apache/taverna/workbench/ui/credentialmanager/ChangeMasterPasswordDialog.java
new file mode 100644
index 0000000..686ebc1
--- /dev/null
+++ 
b/taverna-credential-manager-ui/src/main/java/org/apache/taverna/workbench/ui/credentialmanager/ChangeMasterPasswordDialog.java
@@ -0,0 +1,233 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package org.apache.taverna.workbench.ui.credentialmanager;
+
+import static java.awt.BorderLayout.CENTER;
+import static java.awt.BorderLayout.NORTH;
+import static java.awt.BorderLayout.SOUTH;
+import static java.awt.Font.PLAIN;
+import static javax.swing.BoxLayout.Y_AXIS;
+import static javax.swing.JOptionPane.WARNING_MESSAGE;
+import static javax.swing.JOptionPane.showMessageDialog;
+import static 
org.apache.taverna.workbench.ui.credentialmanager.CMStrings.WARN_TITLE;
+
+import java.awt.BorderLayout;
+import java.awt.FlowLayout;
+import java.awt.Font;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JPasswordField;
+import javax.swing.border.CompoundBorder;
+import javax.swing.border.EmptyBorder;
+import javax.swing.border.EtchedBorder;
+
+import org.apache.taverna.security.credentialmanager.CredentialManager;
+import org.apache.taverna.workbench.helper.NonBlockedHelpEnabledDialog;
+
+/**
+ * Dialog used by users to change their master password for the Credential
+ * Manager.
+ */
+@SuppressWarnings("serial")
+public class ChangeMasterPasswordDialog extends NonBlockedHelpEnabledDialog {
+       /** Old password entry field */
+       private JPasswordField oldPasswordField;
+       /** New password entry field */
+       private JPasswordField newPasswordField;
+       /** New password confirmation entry field */
+       private JPasswordField newPasswordConfirmField;
+       /** The entered new password */
+       private String password = null;
+       /** Instructions to the users as to what to do in the dialog */
+       private String instructions;
+       private final CredentialManager credentialManager;
+
+       public ChangeMasterPasswordDialog(JFrame parent, String title,
+                       boolean modal, String instructions,
+                       CredentialManager credentialManager) {
+               super(parent, title, modal, null);
+               this.instructions = instructions;
+               this.credentialManager = credentialManager;
+               initComponents();
+       }
+
+       private void initComponents() {
+               getContentPane().setLayout(new BorderLayout());
+
+               JLabel instructionsLabel = new JLabel(instructions);
+               instructionsLabel.setFont(new Font(null, PLAIN, 11));
+
+               JPanel instructionsPanel = new JPanel();
+               instructionsPanel.setLayout(new BoxLayout(instructionsPanel, 
Y_AXIS));
+               instructionsPanel.add(instructionsLabel);
+               instructionsPanel.setBorder(new EmptyBorder(10, 5, 10, 0));
+
+               JLabel oldPasswordLabel = new JLabel("Old master password");
+               oldPasswordLabel.setBorder(new EmptyBorder(0, 5, 0, 0));
+
+               JLabel newPasswordLabel = new JLabel("New master password");
+               newPasswordLabel.setBorder(new EmptyBorder(0, 5, 0, 0));
+
+               JLabel newPasswordConfirmLabel = new JLabel(
+                               "Confirm new master password");
+               newPasswordConfirmLabel.setBorder(new EmptyBorder(0, 5, 0, 0));
+
+               oldPasswordField = new JPasswordField(15);
+               newPasswordField = new JPasswordField(15);
+               newPasswordConfirmField = new JPasswordField(15);
+
+               JPanel jpPassword = new JPanel(new GridLayout(0, 2, 5, 5));
+               jpPassword.add(oldPasswordLabel);
+               jpPassword.add(oldPasswordField);
+               jpPassword.add(newPasswordLabel);
+               jpPassword.add(newPasswordField);
+               jpPassword.add(newPasswordConfirmLabel);
+               jpPassword.add(newPasswordConfirmField);
+
+               JPanel mainPanel = new JPanel(new BorderLayout());
+               mainPanel.setBorder(new CompoundBorder(new EmptyBorder(10, 10, 
10, 10),
+                               new EtchedBorder()));
+               mainPanel.add(instructionsPanel, NORTH);
+               mainPanel.add(jpPassword, CENTER);
+
+               JButton okButton = new JButton("OK");
+               okButton.addActionListener(new ActionListener() {
+                       @Override
+                       public void actionPerformed(ActionEvent evt) {
+                               okPressed();
+                       }
+               });
+
+               JButton cancelButton = new JButton("Cancel");
+               cancelButton.addActionListener(new ActionListener() {
+                       @Override
+                       public void actionPerformed(ActionEvent evt) {
+                               cancelPressed();
+                       }
+               });
+               JPanel buttonsPanel = new JPanel(new 
FlowLayout(FlowLayout.CENTER));
+               buttonsPanel.add(okButton);
+               buttonsPanel.add(cancelButton);
+
+               getContentPane().add(mainPanel, CENTER);
+               getContentPane().add(buttonsPanel, SOUTH);
+
+               addWindowListener(new WindowAdapter() {
+                       @Override
+                       public void windowClosing(WindowEvent evt) {
+                               closeDialog();
+                       }
+               });
+
+               setResizable(false);
+               getRootPane().setDefaultButton(okButton);
+               pack();
+       }
+
+       /**
+        * Get the password set in the dialog or null if none was set.
+        */
+       public String getPassword() {
+               return password;
+       }
+
+       /**
+        * Check that the user has provided the correct old master password, 
that
+        * the user has supplied the new password and confirmed it and that it 
is
+        * not empty. If all is OK, stores the new password in the password 
field.
+        * 
+        */
+       private boolean checkPassword() {
+               String oldPassword = new String(oldPasswordField.getPassword());
+
+               if (oldPassword.length() == 0) {
+                       // old password must not be empty
+                       showMessageDialog(this,
+                                       "You must provide your current master 
password",
+                                       WARN_TITLE, WARNING_MESSAGE);
+                       return false;
+               }
+
+               try {
+                       if 
(!credentialManager.confirmMasterPassword(oldPassword)) {
+                               showMessageDialog(this,
+                                               "You have provided an incorrect 
master password",
+                                               WARN_TITLE, WARNING_MESSAGE);
+                               return false;
+                       }
+               } catch (Exception e) {
+                       showMessageDialog(
+                                       this,
+                                       "Credential Manager could not verify 
your current master password",
+                                       WARN_TITLE, WARNING_MESSAGE);
+                       return false;
+               }
+
+               String newPassword = new String(newPasswordField.getPassword());
+               String newPasswordConfirm = new String(
+                               newPasswordConfirmField.getPassword());
+
+               if (!newPassword.equals(newPasswordConfirm)) {
+                       // passwords do not match
+                       showMessageDialog(this, "Passwords do not match", 
WARN_TITLE,
+                                       WARNING_MESSAGE);
+                       return false;
+               }
+
+               if (newPassword.isEmpty()) {
+                       // passwords match but are empty
+                       showMessageDialog(this, "The new master password cannot 
be empty",
+                                       WARN_TITLE, WARNING_MESSAGE);
+                       return false;
+               }
+
+               // passwords match and not empty
+               password = newPassword;
+               return true;
+       }
+
+       private void okPressed() {
+               if (checkPassword())
+                       closeDialog();
+       }
+
+       private void cancelPressed() {
+               /*
+                * Set the password to null as it might have changed in the 
meantime if
+                * user entered something then cancelled.
+                */
+               password = null;
+               closeDialog();
+       }
+
+       private void closeDialog() {
+               setVisible(false);
+               dispose();
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-credential-manager-ui/src/main/java/org/apache/taverna/workbench/ui/credentialmanager/ConfirmTrustedCertificateDialog.java
----------------------------------------------------------------------
diff --git 
a/taverna-credential-manager-ui/src/main/java/org/apache/taverna/workbench/ui/credentialmanager/ConfirmTrustedCertificateDialog.java
 
b/taverna-credential-manager-ui/src/main/java/org/apache/taverna/workbench/ui/credentialmanager/ConfirmTrustedCertificateDialog.java
new file mode 100644
index 0000000..c725983
--- /dev/null
+++ 
b/taverna-credential-manager-ui/src/main/java/org/apache/taverna/workbench/ui/credentialmanager/ConfirmTrustedCertificateDialog.java
@@ -0,0 +1,519 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package org.apache.taverna.workbench.ui.credentialmanager;
+
+import static java.awt.BorderLayout.CENTER;
+import static java.awt.BorderLayout.NORTH;
+import static java.awt.BorderLayout.SOUTH;
+import static java.awt.Color.WHITE;
+import static java.awt.Font.BOLD;
+import static java.awt.Font.PLAIN;
+import static java.awt.GridBagConstraints.LINE_START;
+import static javax.security.auth.x500.X500Principal.RFC2253;
+
+import java.awt.BorderLayout;
+import java.awt.Dialog;
+import java.awt.FlowLayout;
+import java.awt.Font;
+import java.awt.Frame;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.math.BigInteger;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.border.CompoundBorder;
+import javax.swing.border.EmptyBorder;
+import javax.swing.border.EtchedBorder;
+
+import org.apache.taverna.lang.ui.DialogTextArea;
+import org.apache.taverna.security.credentialmanager.CMException;
+import org.apache.taverna.security.credentialmanager.DistinguishedNameParser;
+import org.apache.taverna.security.credentialmanager.ParsedDistinguishedName;
+import org.apache.taverna.workbench.helper.NonBlockedHelpEnabledDialog;
+
+import org.apache.log4j.Logger;
+
+/**
+ * Displays the details of a X.509 certificate and asks user if they want to
+ * trust it. This is normally invoked by the Taverna's TrustManager when 
trying 
+ * to confirm the trust in the remote server during SSL handshake.
+ */
+@SuppressWarnings("serial")
+public class ConfirmTrustedCertificateDialog extends 
NonBlockedHelpEnabledDialog {
+       private static Logger logger = 
Logger.getLogger(ConfirmTrustedCertificateDialog.class);
+
+       /** The certificate to display */
+       private X509Certificate cert;
+       /** User's decision as whether to trust this service's certificate or 
not */
+       private boolean shouldTrust;
+       /**
+        * Should the decision also be saved in Credential Manager? Actually - 
it is
+        * always saved now as it was really hard to implement trusting for one
+        * connection only - so we can either "trust" or "not" trust but not
+        * "trust once".
+        */
+       private boolean shouldSave = false;
+       private final DistinguishedNameParser dnParser;
+
+       public ConfirmTrustedCertificateDialog(Frame parent, String title,
+                       boolean modal, X509Certificate crt, 
DistinguishedNameParser dnParser) {
+               super(parent, title, modal);
+               this.cert = crt;
+               this.dnParser = dnParser;
+               initComponents();
+       }
+
+       public ConfirmTrustedCertificateDialog(Dialog parent, String title,
+                       boolean modal, X509Certificate crt, 
DistinguishedNameParser dnParser)
+                       throws CMException {
+               super(parent, title, modal);
+               this.cert = crt;
+               this.dnParser = dnParser;
+               initComponents();
+       }
+
+       private void initComponents(){          
+               // title panel
+               JPanel titlePanel = new JPanel(new BorderLayout());
+               titlePanel.setBackground(WHITE);
+               JLabel titleLabel = new JLabel("View service's certificate");
+               titleLabel.setFont(titleLabel.getFont().deriveFont(BOLD, 
13.5f));
+               titleLabel.setBorder(new EmptyBorder(10, 10, 0, 10));
+
+               DialogTextArea titleMessage = new DialogTextArea();
+               titleMessage.setMargin(new Insets(5, 20, 10, 10));
+               titleMessage.setFont(titleMessage.getFont().deriveFont(11f));
+               titleMessage.setEditable(false);
+               titleMessage.setFocusable(false);
+               titlePanel.setBorder( new EmptyBorder(10, 10, 0, 10));
+               titlePanel.add(titleLabel, NORTH);
+               titlePanel.add(titleMessage, CENTER);
+               
+               // Certificate details:
+
+               ParsedDistinguishedName subjectDN = dnParser.parseDN(cert
+                               .getSubjectX500Principal().getName(RFC2253));
+               ParsedDistinguishedName issuerDN = dnParser.parseDN(cert
+                               .getIssuerX500Principal().getName(RFC2253));
+               JPanel certificatePanel = 
createCertificateDetailsPanel(subjectDN, issuerDN);
+               titleMessage.setText("The service host " + subjectDN.getCN() + 
" requires HTTPS connection and has identified itself with the certificate 
below.\n" +
+                               "Do you want to trust this service? (Refusing 
to trust means you will not be able to invoke services on this host from a 
workflow.)");
+
+               // OK button
+               JPanel buttonsPanel = new JPanel(new 
FlowLayout(FlowLayout.CENTER));
+
+//             final JButton trustButton = new JButton("Trust once");
+//             trustButton.addActionListener(new ActionListener() {
+//                     public void actionPerformed(ActionEvent evt) {
+//                             trustPressed();
+//                     }
+//             });
+               
+               //final JButton trustAlwaysButton = new JButton("Trust always");
+               final JButton trustAlwaysButton = new JButton("Trust");
+               trustAlwaysButton.addActionListener(new ActionListener() {
+                       @Override
+                       public void actionPerformed(ActionEvent evt) {
+                               trustAlwaysPressed();
+                       }
+               });
+               
+               final JButton dontTrustButton = new JButton("Do not trust");
+               dontTrustButton.addActionListener(new ActionListener() {
+                       @Override
+                       public void actionPerformed(ActionEvent evt) {
+                               dontTrustPressed();
+                       }
+               });
+
+               //jpButtons.add(trustButton);
+               buttonsPanel.add(trustAlwaysButton);
+               buttonsPanel.add(dontTrustButton);
+
+               getContentPane().add(titlePanel, NORTH);
+               getContentPane().add(certificatePanel, CENTER);
+               getContentPane().add(buttonsPanel, SOUTH);
+
+               setResizable(false);
+
+               addWindowListener(new WindowAdapter() {
+                       @Override
+                       public void windowClosing(WindowEvent evt) {
+                               closeDialog();
+                       }
+               });
+
+               getRootPane().setDefaultButton(trustAlwaysButton);
+               pack();
+       }
+
+       private JPanel createCertificateDetailsPanel(ParsedDistinguishedName 
subjectDN, ParsedDistinguishedName issuerDN) {
+               /*
+                * Grid Bag Constraints templates for labels (column 1) and 
values
+                * (column 2) of certificate details
+                */
+               GridBagConstraints gbc_labels = new GridBagConstraints();
+               gbc_labels.gridx = 0;
+               gbc_labels.ipadx = 20;
+               gbc_labels.gridwidth = 1;
+               gbc_labels.gridheight = 1;
+               gbc_labels.insets = new Insets(2, 15, 2, 2);
+               gbc_labels.anchor = LINE_START;
+
+               GridBagConstraints gbc_values = new GridBagConstraints();
+               gbc_values.gridx = 1;
+               gbc_values.gridwidth = 1;
+               gbc_values.gridheight = 1;
+               gbc_values.insets = new Insets(2, 5, 2, 2);
+               gbc_values.anchor = LINE_START;
+
+               /*
+                * Netscape Certificate Type non-critical extension (if any) 
defines the
+                * intended uses of the certificate - to make it look like 
Firefox's
+                * view certificate dialog
+                * 
+                * From openssl's documentation: "The [above] extension is non 
standard,
+                * Netscape specific and largely obsolete. Their use in new 
applications
+                * is discouraged."
+                * 
+                * TODO replace with "basicConstraints, keyUsage and extended 
key usage
+                * extensions which are now used instead."
+                */
+//             byte[] intendedUses = 
cert.getExtensionValue("2.16.840.1.113730.1.1"); // Netscape Certificate Type 
OID
+//             JLabel intendedUsesLabel = null;
+//             JTextField intendedUsesTextField = null;
+//             JPanel intendedUsesPanel = null;
+//             GridBagConstraints gbc_intendedUsesLabel = null;
+//             if (intendedUses != null) {
+//                     intendedUsesLabel = new JLabel(
+//                                     "This certificate has been approved for 
the following uses:");
+//                     intendedUsesLabel.setFont(new Font(null, Font.BOLD, 
11));
+//                     intendedUsesLabel.setBorder(new EmptyBorder(5, 5, 5, 
5));
+//
+//                     intendedUsesTextField = new JTextField(45);
+//                     
intendedUsesTextField.setText(CMUtils.getIntendedCertificateUses(intendedUses));
+//                     intendedUsesTextField.setEditable(false);
+//                     intendedUsesTextField.setFont(new Font(null, 
Font.PLAIN, 11));
+//
+//                     intendedUsesPanel = new JPanel(new BorderLayout());
+//                     intendedUsesPanel.add(intendedUsesLabel, 
BorderLayout.NORTH);
+//                     intendedUsesPanel.add(intendedUsesTextField, 
BorderLayout.CENTER);
+//                     JSeparator separator = new 
JSeparator(JSeparator.HORIZONTAL);
+//                     intendedUsesPanel.add(separator, BorderLayout.SOUTH);
+//
+//                     gbc_intendedUsesLabel = (GridBagConstraints) 
gbc_labels.clone();
+//                     gbc_intendedUsesLabel.gridy = 0;
+//                     gbc_intendedUsesLabel.gridwidth = 2; // takes two 
columns
+//                     gbc_intendedUsesLabel.insets = new Insets(5, 5, 5, 
5);// has slightly bigger insets
+//             }
+
+               // Issued To
+               JLabel issuedToLabel = new JLabel("Issued To");
+               issuedToLabel.setFont(new Font(null, BOLD, 11));
+               GridBagConstraints gbc_issuedTo = (GridBagConstraints) 
gbc_labels
+                               .clone();
+               gbc_issuedTo.gridy = 1;
+               gbc_issuedTo.gridwidth = 2; // takes two columns
+               gbc_issuedTo.insets = new Insets(5, 5, 5, 5);// has slightly 
bigger insets
+               // Subject's Distinguished Name (DN)
+               // Extract the CN, O, OU and EMAILADDRESS fields
+               String subjectCN = subjectDN.getCN();
+               String subjectOrg = subjectDN.getO();
+               String subjectOU = subjectDN.getOU();
+               // String sEMAILADDRESS = CMUtils.getEmilAddress();
+               // Subject's Common Name (CN)
+               JLabel subjectCNLabel = new JLabel("Common Name (CN)");
+               subjectCNLabel.setFont(new Font(null, PLAIN, 11));
+               GridBagConstraints gbc_subjectCNLabel = (GridBagConstraints) 
gbc_labels.clone();
+               gbc_subjectCNLabel.gridy = 2;
+               JLabel subjectCNValue = new JLabel(subjectCN);
+               subjectCNValue.setFont(new Font(null, PLAIN, 11));
+               GridBagConstraints gbc_subjectCNValue = (GridBagConstraints) 
gbc_values
+                               .clone();
+               gbc_subjectCNValue.gridy = 2;
+               // Subject's Organisation (O)
+               JLabel subjectOrgLabel = new JLabel("Organisation (O)");
+               subjectOrgLabel.setFont(new Font(null, PLAIN, 11));
+               GridBagConstraints gbc_subjectOrgLabel = (GridBagConstraints) 
gbc_labels.clone();
+               gbc_subjectOrgLabel.gridy = 3;
+               JLabel subjectOrgValue = new JLabel(subjectOrg);
+               subjectOrgValue.setFont(new Font(null, PLAIN, 11));
+               GridBagConstraints gbc_subjectOrgValue = (GridBagConstraints) 
gbc_values
+                               .clone();
+               gbc_subjectOrgValue.gridy = 3;
+               // Subject's Organisation Unit (OU)
+               JLabel subjectOULabel = new JLabel("Organisation Unit (OU)");
+               subjectOULabel.setFont(new Font(null, PLAIN, 11));
+               GridBagConstraints gbc_subjectOULabel = (GridBagConstraints) 
gbc_labels.clone();
+               gbc_subjectOULabel.gridy = 4;
+               JLabel subjectOUValue = new JLabel(subjectOU);
+               subjectOUValue.setFont(new Font(null, PLAIN, 11));
+               GridBagConstraints gbc_subjectOUValue = (GridBagConstraints) 
gbc_values
+                               .clone();
+               gbc_subjectOUValue.gridy = 4;
+               // E-mail Address
+               // JLabel jlEmail = new JLabel("E-mail Address");
+               // jlEmail.setFont(new Font(null, Font.PLAIN, 11));
+               // GridBagConstraints gbc_jlEmail = (GridBagConstraints)
+               // gbcLabel.clone();
+               // gbc_jlEmail.gridy = 5;
+               // JLabel jlEmailValue = new JLabel(sEMAILADDRESS);
+               // jlEmailValue.setFont(new Font(null, Font.PLAIN, 11));
+               // GridBagConstraints gbc_jlEmailValue = (GridBagConstraints)
+               // gbcValue.clone();
+               // gbc_jlEmailValue.gridy = 5;
+               // Serial Number
+               JLabel snLabel = new JLabel("Serial Number");
+               snLabel.setFont(new Font(null, PLAIN, 11));
+               GridBagConstraints gbc_snLabel = (GridBagConstraints) 
gbc_labels.clone();
+               gbc_snLabel.gridy = 6;
+               JLabel snValue = new JLabel();
+               // Get the hexadecimal serial number
+               StringBuilder strBuff = new StringBuilder(new BigInteger(1, cert
+                               
.getSerialNumber().toByteArray()).toString(16).toUpperCase());
+               // Place colons at every two hexadecimal characters
+               if (strBuff.length() > 2)
+                       for (int iCnt = 2; iCnt < strBuff.length(); iCnt += 3)
+                               strBuff.insert(iCnt, ':');
+               snValue.setText(strBuff.toString());
+               snValue.setFont(new Font(null, PLAIN, 11));
+               GridBagConstraints gbc_snValue = (GridBagConstraints) gbc_values
+                               .clone();
+               gbc_snValue.gridy = 6;
+               // Certificate version number
+               JLabel versionLabel = new JLabel("Version");
+               versionLabel.setFont(new Font(null, PLAIN, 11));
+               GridBagConstraints gbc_versionLabel = (GridBagConstraints) 
gbc_labels
+                               .clone();
+               gbc_versionLabel.gridy = 7;
+               JLabel versionValue = new 
JLabel(Integer.toString(cert.getVersion()));
+               versionValue.setFont(new Font(null, PLAIN, 11));
+               GridBagConstraints gbc_versionValue = (GridBagConstraints) 
gbc_values
+                               .clone();
+               gbc_versionValue.gridy = 7;
+
+               // Issued By
+               JLabel issuedByLabel = new JLabel("Issued By");
+               issuedByLabel.setFont(new Font(null, BOLD, 11));
+               GridBagConstraints gbc_issuedByLabel = (GridBagConstraints) 
gbc_labels
+                               .clone();
+               gbc_issuedByLabel.gridy = 8;
+               gbc_issuedByLabel.gridwidth = 2; // takes two columns
+               gbc_issuedByLabel.insets = new Insets(5, 5, 5, 5);// has 
slightly bigger insets
+               // Issuer's Distinguished Name (DN)
+               // Extract the CN, O and OU fields for the issuer
+               String issuerCN = issuerDN.getCN();
+               String issuerOrg = issuerDN.getO();
+               String issuerOU = issuerDN.getOU();
+               // Issuer's Common Name (CN)
+               JLabel issuerCNLabel = new JLabel("Common Name (CN)");
+               issuerCNLabel.setFont(new Font(null, PLAIN, 11));
+               GridBagConstraints gbc_issuerCNLabel = (GridBagConstraints) 
gbc_labels.clone();
+               gbc_issuerCNLabel.gridy = 9;
+               JLabel issuerCNValue = new JLabel(issuerCN);
+               issuerCNValue.setFont(new Font(null, PLAIN, 11));
+               GridBagConstraints gbc_issuerCNValue = (GridBagConstraints) 
gbc_values
+                               .clone();
+               gbc_issuerCNValue.gridy = 9;
+               // Issuer's Organisation (O)
+               JLabel issuerOrgLabel = new JLabel("Organisation (O)");
+               issuerOrgLabel.setFont(new Font(null, PLAIN, 11));
+               GridBagConstraints gbc_issuerOrgLabel = (GridBagConstraints) 
gbc_labels.clone();
+               gbc_issuerOrgLabel.gridy = 10;
+               JLabel issuerOrgValue = new JLabel(issuerOrg);
+               issuerOrgValue.setFont(new Font(null, PLAIN, 11));
+               GridBagConstraints gbc_issuerOrgValue = (GridBagConstraints) 
gbc_values
+                               .clone();
+               gbc_issuerOrgValue.gridy = 10;
+               // Issuer's Organisation Unit (OU)
+               JLabel issuerOULabel = new JLabel("Organisation Unit (OU)");
+               issuerOULabel.setFont(new Font(null, PLAIN, 11));
+               GridBagConstraints gbc_issuerOULabel = (GridBagConstraints) 
gbc_labels.clone();
+               gbc_issuerOULabel.gridy = 11;
+               JLabel issuerOUValue = new JLabel(issuerOU);
+               issuerOUValue.setFont(new Font(null, PLAIN, 11));
+               GridBagConstraints gbc_issuerOUValue = (GridBagConstraints) 
gbc_values
+                               .clone();
+               gbc_issuerOUValue.gridy = 11;
+               
+               // Validity
+               JLabel validityLabel = new JLabel("Validity");
+               validityLabel.setFont(new Font(null, BOLD, 11));
+               GridBagConstraints gbc_validityLabel = (GridBagConstraints) 
gbc_labels
+                               .clone();
+               gbc_validityLabel.gridy = 12;
+               gbc_validityLabel.gridwidth = 2; // takes two columns
+               gbc_validityLabel.insets = new Insets(5, 5, 5, 5);// has 
slightly bigger insets
+               // Issued On
+               JLabel issuedOnLabel = new JLabel("Issued On");
+               issuedOnLabel.setFont(new Font(null, PLAIN, 11));
+               GridBagConstraints gbc_issuedOnLabel = (GridBagConstraints) 
gbc_labels
+                               .clone();
+               gbc_issuedOnLabel.gridy = 13;
+               JLabel issuedOnValue = new 
JLabel(cert.getNotBefore().toString());
+               issuedOnValue.setFont(new Font(null, PLAIN, 11));
+               GridBagConstraints gbc_issuedOnValue = (GridBagConstraints) 
gbc_values
+                               .clone();
+               gbc_issuedOnValue.gridy = 13;
+               // Expires On
+               JLabel expiresOnLabel = new JLabel("Expires On");
+               expiresOnLabel.setFont(new Font(null, PLAIN, 11));
+               GridBagConstraints gbc_expiresOnLabel = (GridBagConstraints) 
gbc_labels
+                               .clone();
+               gbc_expiresOnLabel.gridy = 14;
+               JLabel expiresOnValue = new 
JLabel(cert.getNotAfter().toString());
+               expiresOnValue.setFont(new Font(null, PLAIN, 11));
+               GridBagConstraints gbc_expiresOnValue = (GridBagConstraints) 
gbc_values
+                               .clone();
+               gbc_expiresOnValue.gridy = 14;
+
+               // Fingerprints
+               byte[] binaryCertificateEncoding = new byte[0];
+               try {
+                       // each certificate has one binary encoding; for X.509 
certs it is DER
+                       binaryCertificateEncoding = cert.getEncoded();
+               } catch (CertificateEncodingException ex) {
+                       logger.error("Could not get the encoded form of the 
certificate.", ex);
+               }
+               JLabel fingerprintsLabel = new JLabel("Fingerprints");
+               fingerprintsLabel.setFont(new Font(null, BOLD, 11));
+               GridBagConstraints gbc_fingerprintsLabel = (GridBagConstraints) 
gbc_labels
+                               .clone();
+               gbc_fingerprintsLabel.gridy = 15;
+               gbc_fingerprintsLabel.gridwidth = 2; // takes two columns
+               gbc_fingerprintsLabel.insets = new Insets(5, 5, 5, 5);// has 
slightly bigger insets
+               // SHA-1 Fingerprint
+               JLabel sha1FingerprintLabel = new JLabel("SHA1 Fingerprint");
+               sha1FingerprintLabel.setFont(new Font(null, PLAIN, 11));
+               GridBagConstraints gbc_sha1FingerprintLabel = 
(GridBagConstraints) gbc_labels
+                               .clone();
+               gbc_sha1FingerprintLabel.gridy = 16;
+               JLabel sha1FingerprintValue = new JLabel(
+                               dnParser.getMessageDigestAsFormattedString(
+                                               binaryCertificateEncoding, 
"SHA1"));
+               sha1FingerprintValue.setFont(new Font(null, PLAIN, 11));
+               GridBagConstraints gbc_sha1FingerprintValue = 
(GridBagConstraints) gbc_values
+                               .clone();
+               gbc_sha1FingerprintValue.gridy = 16;
+               // MD5 Fingerprint
+               JLabel md5FingerprintLabel = new JLabel("MD5 Fingerprint");
+               md5FingerprintLabel.setFont(new Font(null, PLAIN, 11));
+               GridBagConstraints gbc_md5FingerprinLabel = 
(GridBagConstraints) gbc_labels
+                               .clone();
+               gbc_md5FingerprinLabel.gridy = 17;
+               JLabel md5FingerprintValue = new JLabel(
+                               dnParser.getMessageDigestAsFormattedString(
+                                               binaryCertificateEncoding, 
"MD5"));
+               md5FingerprintValue.setFont(new Font(null, PLAIN, 11));
+               GridBagConstraints gbc_md5FingerprintValue = 
(GridBagConstraints) gbc_values
+                               .clone();
+               gbc_md5FingerprintValue.gridy = 17;
+
+               /*
+                * Empty label to add a bit space at the bottom of the panel to 
make it
+                * look like Firefox's view certificate dialog
+                */
+               JLabel emptyLabel = new JLabel("");
+               GridBagConstraints gbc_emptyLabel = (GridBagConstraints) 
gbc_labels.clone();
+               gbc_emptyLabel.gridy = 18;
+               gbc_emptyLabel.gridwidth = 2; // takes two columns
+               gbc_emptyLabel.ipady = 40;
+
+               JPanel certificatePanel = new JPanel(new GridBagLayout());
+               certificatePanel.setBorder(new CompoundBorder(new 
EmptyBorder(15, 15, 15,
+                               15), new EtchedBorder()));
+
+//             if (intendedUses != null)
+//                     certificatePanel.add(intendedUsesPanel, 
gbc_intendedUsesLabel);
+               certificatePanel.add(issuedToLabel, gbc_issuedTo); // Issued To
+               certificatePanel.add(subjectCNLabel, gbc_subjectCNLabel);
+               certificatePanel.add(subjectCNValue, gbc_subjectCNValue);
+               certificatePanel.add(subjectOrgLabel, gbc_subjectOrgLabel);
+               certificatePanel.add(subjectOrgValue, gbc_subjectOrgValue);
+               certificatePanel.add(subjectOULabel, gbc_subjectOULabel);
+               certificatePanel.add(subjectOUValue, gbc_subjectOUValue);
+               // jpCertificate.add(jlEmail, gbc_jlEmail);
+               // jpCertificate.add(jlEmailValue, gbc_jlEmailValue);
+               certificatePanel.add(snLabel, gbc_snLabel);
+               certificatePanel.add(snValue, gbc_snValue);
+               certificatePanel.add(versionLabel, gbc_versionLabel);
+               certificatePanel.add(versionValue, gbc_versionValue);
+               certificatePanel.add(issuedByLabel, gbc_issuedByLabel); // 
Issued By
+               certificatePanel.add(issuerCNLabel, gbc_issuerCNLabel);
+               certificatePanel.add(issuerCNValue, gbc_issuerCNValue);
+               certificatePanel.add(issuerOrgLabel, gbc_issuerOrgLabel);
+               certificatePanel.add(issuerOrgValue, gbc_issuerOrgValue);
+               certificatePanel.add(issuerOULabel, gbc_issuerOULabel);
+               certificatePanel.add(issuerOUValue, gbc_issuerOUValue);
+               certificatePanel.add(validityLabel, gbc_validityLabel); // 
Validity
+               certificatePanel.add(issuedOnLabel, gbc_issuedOnLabel);
+               certificatePanel.add(issuedOnValue, gbc_issuedOnValue);
+               certificatePanel.add(expiresOnLabel, gbc_expiresOnLabel);
+               certificatePanel.add(expiresOnValue, gbc_expiresOnValue);
+               certificatePanel.add(fingerprintsLabel, gbc_fingerprintsLabel); 
// Fingerprints
+               certificatePanel.add(sha1FingerprintLabel, 
gbc_sha1FingerprintLabel);
+               certificatePanel.add(sha1FingerprintValue, 
gbc_sha1FingerprintValue);
+               certificatePanel.add(md5FingerprintLabel, 
gbc_md5FingerprinLabel);
+               certificatePanel.add(md5FingerprintValue, 
gbc_md5FingerprintValue);
+               // Empty label to get some vertical space on the frame
+               certificatePanel.add(emptyLabel, gbc_emptyLabel);
+               return certificatePanel;
+       }
+
+//     private void trustPressed() {
+//             shouldTrust = true;
+//             shouldSave = false;
+//             closeDialog();
+//     }
+
+       private void trustAlwaysPressed() {
+               shouldTrust = true;
+               shouldSave = true;
+               closeDialog();
+       }
+
+       private void dontTrustPressed() {
+               shouldTrust = false;
+               shouldSave = false;
+               closeDialog();
+       }
+
+       public void closeDialog() {
+               setVisible(false);
+               dispose();
+       }
+
+       public boolean shouldTrust() {
+               return shouldTrust;
+       }
+
+       public boolean shouldSave() {
+               return shouldSave;
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-credential-manager-ui/src/main/java/org/apache/taverna/workbench/ui/credentialmanager/ConfirmTrustedCertificateUI.java
----------------------------------------------------------------------
diff --git 
a/taverna-credential-manager-ui/src/main/java/org/apache/taverna/workbench/ui/credentialmanager/ConfirmTrustedCertificateUI.java
 
b/taverna-credential-manager-ui/src/main/java/org/apache/taverna/workbench/ui/credentialmanager/ConfirmTrustedCertificateUI.java
new file mode 100644
index 0000000..1207a73
--- /dev/null
+++ 
b/taverna-credential-manager-ui/src/main/java/org/apache/taverna/workbench/ui/credentialmanager/ConfirmTrustedCertificateUI.java
@@ -0,0 +1,70 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package org.apache.taverna.workbench.ui.credentialmanager;
+
+import static javax.swing.JOptionPane.INFORMATION_MESSAGE;
+import static javax.swing.JOptionPane.showMessageDialog;
+
+import java.awt.Frame;
+import java.security.cert.X509Certificate;
+
+import org.apache.taverna.security.credentialmanager.DistinguishedNameParser;
+import org.apache.taverna.security.credentialmanager.TrustConfirmationProvider;
+
+import org.apache.log4j.Logger;
+
+/**
+ * @author Stian Soiland-Reyes
+ */
+public class ConfirmTrustedCertificateUI implements TrustConfirmationProvider {
+       private static Logger logger = Logger
+                       .getLogger(ConfirmTrustedCertificateUI.class);
+
+       private DistinguishedNameParser dnParser;
+
+       @Override
+       public Boolean shouldTrustCertificate(X509Certificate[] chain) {
+               boolean trustConfirm = false;
+               logger.info("Asking the user if they want to trust a 
certificate.");
+               // Ask user if they want to trust this service
+               ConfirmTrustedCertificateDialog confirmCertTrustDialog = new 
ConfirmTrustedCertificateDialog(
+                               (Frame) null, "Untrusted HTTPS connection", 
true,
+                               (X509Certificate) chain[0], dnParser);
+               confirmCertTrustDialog.setLocationRelativeTo(null);
+               confirmCertTrustDialog.setVisible(true);
+               trustConfirm = confirmCertTrustDialog.shouldTrust();
+//             trustConfirm.setShouldSave(confirmCertTrustDialog.shouldSave());
+               if (!confirmCertTrustDialog.shouldTrust())
+                       showMessageDialog(
+                                       null,
+                                       "As you refused to trust this host, you 
will not be able to use its services from a workflow.",
+                                       "Untrusted HTTPS connection", 
INFORMATION_MESSAGE);
+
+               return trustConfirm;
+       }
+
+       /**
+        * @param dnParser
+        *            the dnParser to set
+        */
+       public void setDistinguishedNameParser(DistinguishedNameParser 
dnParser) {
+               this.dnParser = dnParser;
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-credential-manager-ui/src/main/java/org/apache/taverna/workbench/ui/credentialmanager/CredentialManagerUI.java
----------------------------------------------------------------------
diff --git 
a/taverna-credential-manager-ui/src/main/java/org/apache/taverna/workbench/ui/credentialmanager/CredentialManagerUI.java
 
b/taverna-credential-manager-ui/src/main/java/org/apache/taverna/workbench/ui/credentialmanager/CredentialManagerUI.java
new file mode 100644
index 0000000..7547918
--- /dev/null
+++ 
b/taverna-credential-manager-ui/src/main/java/org/apache/taverna/workbench/ui/credentialmanager/CredentialManagerUI.java
@@ -0,0 +1,1511 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package org.apache.taverna.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 
org.apache.taverna.security.credentialmanager.CredentialManager.KeystoreType.KEYSTORE;
+import static 
org.apache.taverna.security.credentialmanager.CredentialManager.KeystoreType.TRUSTSTORE;
+import static 
org.apache.taverna.workbench.ui.credentialmanager.CMStrings.ALERT_TITLE;
+import static 
org.apache.taverna.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 org.apache.taverna.security.credentialmanager.CMException;
+import org.apache.taverna.security.credentialmanager.CredentialManager;
+import 
org.apache.taverna.security.credentialmanager.CredentialManager.KeystoreType;
+import org.apache.taverna.security.credentialmanager.DistinguishedNameParser;
+import org.apache.taverna.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();
+       }
+}

Reply via email to