[Releng] Workaround broken TrustCertificateDialog API.
diff --git a/features/org.eclipse.oomph.p2-feature/feature.xml b/features/org.eclipse.oomph.p2-feature/feature.xml
index ab396c0..d255c13 100644
--- a/features/org.eclipse.oomph.p2-feature/feature.xml
+++ b/features/org.eclipse.oomph.p2-feature/feature.xml
@@ -12,7 +12,7 @@
 <feature
       id="org.eclipse.oomph.p2"
       label="%featureName"
-      version="1.19.0.qualifier"
+      version="1.20.0.qualifier"
       provider-name="%providerName"
       license-feature="org.eclipse.oomph.license"
       license-feature-version="0.0.0">
diff --git a/features/org.eclipse.oomph.p2-feature/pom.xml b/features/org.eclipse.oomph.p2-feature/pom.xml
index 1522f50..8b80a60 100644
--- a/features/org.eclipse.oomph.p2-feature/pom.xml
+++ b/features/org.eclipse.oomph.p2-feature/pom.xml
@@ -20,6 +20,6 @@
   </parent>
   <groupId>org.eclipse.oomph.features</groupId>
   <artifactId>org.eclipse.oomph.p2</artifactId>
-  <version>1.19.0-SNAPSHOT</version>
+  <version>1.20.0-SNAPSHOT</version>
   <packaging>eclipse-feature</packaging>
 </project>
diff --git a/features/org.eclipse.oomph.setup-feature/feature.xml b/features/org.eclipse.oomph.setup-feature/feature.xml
index 43b73dc..03068a2 100644
--- a/features/org.eclipse.oomph.setup-feature/feature.xml
+++ b/features/org.eclipse.oomph.setup-feature/feature.xml
@@ -12,7 +12,7 @@
 <feature
       id="org.eclipse.oomph.setup"
       label="%featureName"
-      version="1.21.0.qualifier"
+      version="1.22.0.qualifier"
       provider-name="%providerName"
       license-feature="org.eclipse.oomph.license"
       license-feature-version="0.0.0">
diff --git a/features/org.eclipse.oomph.setup-feature/pom.xml b/features/org.eclipse.oomph.setup-feature/pom.xml
index 3cf05b6..7f352f5 100644
--- a/features/org.eclipse.oomph.setup-feature/pom.xml
+++ b/features/org.eclipse.oomph.setup-feature/pom.xml
@@ -20,6 +20,6 @@
   </parent>
   <groupId>org.eclipse.oomph.features</groupId>
   <artifactId>org.eclipse.oomph.setup</artifactId>
-  <version>1.21.0-SNAPSHOT</version>
+  <version>1.22.0-SNAPSHOT</version>
   <packaging>eclipse-feature</packaging>
 </project>
diff --git a/features/org.eclipse.oomph.setup.installer-feature/feature.xml b/features/org.eclipse.oomph.setup.installer-feature/feature.xml
index 3cfb845..46de725 100644
--- a/features/org.eclipse.oomph.setup.installer-feature/feature.xml
+++ b/features/org.eclipse.oomph.setup.installer-feature/feature.xml
@@ -12,7 +12,7 @@
 <feature
       id="org.eclipse.oomph.setup.installer"
       label="%featureName"
-      version="1.21.0.qualifier"
+      version="1.22.0.qualifier"
       provider-name="%providerName"
       license-feature="org.eclipse.oomph.license"
       license-feature-version="0.0.0">
diff --git a/features/org.eclipse.oomph.setup.installer-feature/pom.xml b/features/org.eclipse.oomph.setup.installer-feature/pom.xml
index 3b6f240..727dc0f 100644
--- a/features/org.eclipse.oomph.setup.installer-feature/pom.xml
+++ b/features/org.eclipse.oomph.setup.installer-feature/pom.xml
@@ -22,7 +22,7 @@
 
   <groupId>org.eclipse.oomph.features</groupId>
   <artifactId>org.eclipse.oomph.setup.installer</artifactId>
-  <version>1.21.0-SNAPSHOT</version>
+  <version>1.22.0-SNAPSHOT</version>
   <packaging>eclipse-feature</packaging>
 
   <build>
diff --git a/plugins/org.eclipse.oomph.p2.core/META-INF/MANIFEST.MF b/plugins/org.eclipse.oomph.p2.core/META-INF/MANIFEST.MF
index d779bd4..77a7321 100644
--- a/plugins/org.eclipse.oomph.p2.core/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.oomph.p2.core/META-INF/MANIFEST.MF
@@ -2,14 +2,14 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.oomph.p2.core;singleton:=true
-Bundle-Version: 1.18.0.qualifier
+Bundle-Version: 1.19.0.qualifier
 Bundle-ClassPath: .
 Bundle-Activator: org.eclipse.oomph.p2.internal.core.P2CorePlugin$Implementation
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: J2SE-1.5
-Export-Package: org.eclipse.oomph.p2.core;version="1.18.0";x-internal:=true,
- org.eclipse.oomph.p2.internal.core;version="1.18.0";x-internal:=true
+Export-Package: org.eclipse.oomph.p2.core;version="1.19.0";x-internal:=true,
+ org.eclipse.oomph.p2.internal.core;version="1.19.0";x-internal:=true
 Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)",
  org.eclipse.core.variables;bundle-version="[3.0.0,4.0.0)";resolution:=optional,
  org.eclipse.emf.ecore.xmi;bundle-version="[2.10.0,3.0.0)",
diff --git a/plugins/org.eclipse.oomph.p2.core/pom.xml b/plugins/org.eclipse.oomph.p2.core/pom.xml
index a4be6b8..fcbee88 100644
--- a/plugins/org.eclipse.oomph.p2.core/pom.xml
+++ b/plugins/org.eclipse.oomph.p2.core/pom.xml
@@ -20,7 +20,7 @@
   </parent>
   <groupId>org.eclipse.oomph</groupId>
   <artifactId>org.eclipse.oomph.p2.core</artifactId>
-  <version>1.18.0-SNAPSHOT</version>
+  <version>1.19.0-SNAPSHOT</version>
   <packaging>eclipse-plugin</packaging>
 
   <build>
diff --git a/plugins/org.eclipse.oomph.p2.core/src/org/eclipse/oomph/p2/core/CertificateConfirmer.java b/plugins/org.eclipse.oomph.p2.core/src/org/eclipse/oomph/p2/core/CertificateConfirmer.java
index d08e91f..d8d29ce 100644
--- a/plugins/org.eclipse.oomph.p2.core/src/org/eclipse/oomph/p2/core/CertificateConfirmer.java
+++ b/plugins/org.eclipse.oomph.p2.core/src/org/eclipse/oomph/p2/core/CertificateConfirmer.java
@@ -30,6 +30,7 @@
   {
     private final boolean trustAll;
 
+    @SuppressWarnings("deprecation")
     public TrustInfoWithPolicy(Certificate[] trusted, boolean save, boolean trustUnsigned, boolean trustAll)
     {
       super(trusted, save, trustUnsigned);
diff --git a/plugins/org.eclipse.oomph.p2.core/src/org/eclipse/oomph/p2/core/DelegatingUIServices.java b/plugins/org.eclipse.oomph.p2.core/src/org/eclipse/oomph/p2/core/DelegatingUIServices.java
index 8d5986d..a80b86d 100644
--- a/plugins/org.eclipse.oomph.p2.core/src/org/eclipse/oomph/p2/core/DelegatingUIServices.java
+++ b/plugins/org.eclipse.oomph.p2.core/src/org/eclipse/oomph/p2/core/DelegatingUIServices.java
@@ -10,6 +10,7 @@
  */
 package org.eclipse.oomph.p2.core;
 
+import org.eclipse.oomph.p2.core.CertificateConfirmer.TrustInfoWithPolicy;
 import org.eclipse.oomph.util.Confirmer;
 import org.eclipse.oomph.util.Confirmer.Confirmation;
 
@@ -55,7 +56,7 @@
         Confirmation confirmation = unsignedContentConfirmer.confirm(true, unsignedDetail);
         if (!confirmation.isConfirmed())
         {
-          return new TrustInfo(new Certificate[0], false, false);
+          return new TrustInfoWithPolicy(new Certificate[0], false, false, false);
         }
 
         // We've checked trust in unsigned content already; prevent delegate from checking it again.
@@ -71,7 +72,7 @@
       {
         if (certificateConfirmer.isDecline())
         {
-          return new TrustInfo(new Certificate[0], false, false);
+          return new TrustInfoWithPolicy(new Certificate[0], false, false, false);
         }
 
         for (Certificate[] untrustedChain : untrustedChains)
@@ -130,6 +131,6 @@
       }
     }
 
-    return new TrustInfo(trusted.toArray(new Certificate[trusted.size()]), trustInfo.persistTrust(), true);
+    return new TrustInfoWithPolicy(trusted.toArray(new Certificate[trusted.size()]), trustInfo.persistTrust(), true, false);
   }
 }
diff --git a/plugins/org.eclipse.oomph.p2.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.oomph.p2.ui/META-INF/MANIFEST.MF
index 772a1c9..2ba989a 100644
--- a/plugins/org.eclipse.oomph.p2.ui/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.oomph.p2.ui/META-INF/MANIFEST.MF
@@ -2,13 +2,13 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.oomph.p2.ui;singleton:=true
-Bundle-Version: 1.16.0.qualifier
+Bundle-Version: 1.17.0.qualifier
 Bundle-ClassPath: .
 Bundle-Activator: org.eclipse.oomph.p2.internal.ui.P2UIPlugin$Implementation
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: J2SE-1.5
-Export-Package: org.eclipse.oomph.p2.internal.ui;version="1.16.0";x-internal:=true
+Export-Package: org.eclipse.oomph.p2.internal.ui;version="1.17.0";x-internal:=true
 Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)",
  org.eclipse.core.variables;bundle-version="[3.0.0,4.0.0)";resolution:=optional,
  org.eclipse.equinox.p2.core;bundle-version="[2.0.0,3.0.0)",
@@ -17,8 +17,9 @@
  org.eclipse.equinox.p2.repository;bundle-version="[2.0.0,3.0.0)",
  org.eclipse.equinox.p2.artifact.repository;bundle-version="[1.0.0,2.0.0)",
  org.eclipse.equinox.p2.ui;bundle-version="[2.0.0,3.0.0)",
+ org.eclipse.equinox.security.ui;bundle-version="[1.1.0,2.0.0)",
  org.eclipse.oomph.ui;bundle-version="[1.15.0,2.0.0)",
- org.eclipse.oomph.p2.core;bundle-version="[1.18.0,2.0.0)";visibility:=reexport,
+ org.eclipse.oomph.p2.core;bundle-version="[1.19.0,2.0.0)";visibility:=reexport,
  org.eclipse.oomph.p2.edit;bundle-version="[1.14.0,2.0.0)";visibility:=reexport,
  org.eclipse.ui;bundle-version="[3.5.0,4.0.0)",
  org.eclipse.ui.ide;bundle-version="[3.5.0,4.0.0)";resolution:=optional,
diff --git a/plugins/org.eclipse.oomph.p2.ui/pom.xml b/plugins/org.eclipse.oomph.p2.ui/pom.xml
index cce26b3..d14eb1c 100644
--- a/plugins/org.eclipse.oomph.p2.ui/pom.xml
+++ b/plugins/org.eclipse.oomph.p2.ui/pom.xml
@@ -20,7 +20,7 @@
   </parent>
   <groupId>org.eclipse.oomph</groupId>
   <artifactId>org.eclipse.oomph.p2.ui</artifactId>
-  <version>1.16.0-SNAPSHOT</version>
+  <version>1.17.0-SNAPSHOT</version>
   <packaging>eclipse-plugin</packaging>
 
   <build>
diff --git a/plugins/org.eclipse.oomph.p2.ui/src/org/eclipse/oomph/p2/internal/ui/P2ServiceUI.java b/plugins/org.eclipse.oomph.p2.ui/src/org/eclipse/oomph/p2/internal/ui/P2ServiceUI.java
index 4c8c9b8..f897c3d 100644
--- a/plugins/org.eclipse.oomph.p2.ui/src/org/eclipse/oomph/p2/internal/ui/P2ServiceUI.java
+++ b/plugins/org.eclipse.oomph.p2.ui/src/org/eclipse/oomph/p2/internal/ui/P2ServiceUI.java
@@ -11,8 +11,10 @@
 package org.eclipse.oomph.p2.internal.ui;
 
 import org.eclipse.oomph.p2.core.CertificateConfirmer;
+import org.eclipse.oomph.p2.core.CertificateConfirmer.TrustInfoWithPolicy;
 import org.eclipse.oomph.p2.core.DelegatingUIServices;
 import org.eclipse.oomph.ui.UIUtil;
+import org.eclipse.oomph.util.IOUtil;
 
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.MultiStatus;
@@ -20,33 +22,55 @@
 import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.equinox.internal.p2.ui.ProvUIActivator;
 import org.eclipse.equinox.internal.p2.ui.ProvUIMessages;
-import org.eclipse.equinox.internal.p2.ui.dialogs.TrustCertificateDialog;
 import org.eclipse.equinox.internal.p2.ui.dialogs.UserValidationDialog;
 import org.eclipse.equinox.internal.p2.ui.viewers.CertificateLabelProvider;
+import org.eclipse.equinox.internal.provisional.security.ui.X509CertificateViewDialog;
 import org.eclipse.equinox.p2.core.UIServices;
 import org.eclipse.equinox.p2.ui.LoadMetadataRepositoryJob;
 import org.eclipse.jface.dialogs.Dialog;
 import org.eclipse.jface.dialogs.ErrorDialog;
 import org.eclipse.jface.dialogs.IDialogConstants;
 import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.viewers.AbstractTreeViewer;
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
 import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
 import org.eclipse.jface.viewers.TreeNode;
 import org.eclipse.jface.viewers.TreeNodeContentProvider;
+import org.eclipse.jface.viewers.TreeViewer;
 import org.eclipse.jface.window.Window;
 import org.eclipse.osgi.util.NLS;
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
 import org.eclipse.swt.events.SelectionEvent;
 import org.eclipse.swt.events.SelectionListener;
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.layout.RowLayout;
 import org.eclipse.swt.widgets.Button;
 import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.FileDialog;
 import org.eclipse.swt.widgets.Layout;
 import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.dialogs.SelectionDialog;
 
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
 import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
 import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicBoolean;
 
@@ -207,7 +231,7 @@
     // For now, there is no need to show certificates if there was unsigned content and we don't trust it.
     if (!trustUnsigned)
     {
-      return new TrustInfo(trusted, persistTrust, trustUnsigned);
+      return new TrustInfoWithPolicy(trusted, persistTrust, trustUnsigned, false);
     }
 
     // We've established trust for unsigned content, now examine the untrusted chains.
@@ -388,4 +412,333 @@
       return null;
     }
   }
+
+  /**
+   * A dialog that displays a certificate chain and asks the user if they trust the certificate providers.
+   * Copied from org.eclipse.equinox.internal.p2.ui.dialogs.TrustCertificateDialog because it was changed in a way that could not be backward compatible.
+   */
+  private static class TrustCertificateDialog extends SelectionDialog
+  {
+    private Object inputElement;
+
+    private IStructuredContentProvider contentProvider;
+
+    private ILabelProvider labelProvider;
+
+    private final static int SIZING_SELECTION_WIDGET_HEIGHT = 250;
+
+    private final static int SIZING_SELECTION_WIDGET_WIDTH = 300;
+
+    CheckboxTableViewer listViewer;
+
+    private TreeViewer certificateChainViewer;
+
+    private Button detailsButton;
+
+    protected TreeNode parentElement;
+
+    protected Object selectedCertificate;
+
+    public TrustCertificateDialog(Shell parentShell, Object input, ILabelProvider labelProvider, ITreeContentProvider contentProvider)
+    {
+      super(parentShell);
+      inputElement = input;
+      this.contentProvider = contentProvider;
+      this.labelProvider = labelProvider;
+      setTitle(ProvUIMessages.TrustCertificateDialog_Title);
+      setMessage(ProvUIMessages.TrustCertificateDialog_Message);
+      setShellStyle(SWT.DIALOG_TRIM | SWT.MODELESS | SWT.RESIZE | getDefaultOrientation());
+    }
+
+    @Override
+    protected Control createDialogArea(Composite parent)
+    {
+      Composite composite = createUpperDialogArea(parent);
+      certificateChainViewer = new TreeViewer(composite, SWT.BORDER);
+      GridLayout layout = new GridLayout();
+      certificateChainViewer.getTree().setLayout(layout);
+      GridData data = new GridData(GridData.FILL_BOTH);
+      data.grabExcessHorizontalSpace = true;
+      certificateChainViewer.getTree().setLayoutData(data);
+      certificateChainViewer.setAutoExpandLevel(AbstractTreeViewer.ALL_LEVELS);
+      certificateChainViewer.setContentProvider(new TreeNodeContentProvider());
+      certificateChainViewer.setLabelProvider(new CertificateLabelProvider());
+      certificateChainViewer.addSelectionChangedListener(getChainSelectionListener());
+      if (inputElement instanceof Object[])
+      {
+        ISelection selection = null;
+        Object[] nodes = (Object[])inputElement;
+        if (nodes.length > 0)
+        {
+          selection = new StructuredSelection(nodes[0]);
+          certificateChainViewer.setInput(new TreeNode[] { (TreeNode)nodes[0] });
+          selectedCertificate = nodes[0];
+        }
+        listViewer.setSelection(selection);
+      }
+      listViewer.addDoubleClickListener(getDoubleClickListener());
+      listViewer.addSelectionChangedListener(getParentSelectionListener());
+      createButtons(composite);
+      return composite;
+    }
+
+    @Override
+    protected void createButtonsForButtonBar(Composite parent)
+    {
+      createButton(parent, IDialogConstants.OK_ID, ProvUIMessages.TrustCertificateDialog_AcceptSelectedButtonLabel, true);
+      createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false);
+      super.getOkButton().setEnabled(false);
+    }
+
+    private void createButtons(Composite composite)
+    {
+      Composite buttonComposite = new Composite(composite, SWT.NONE);
+      buttonComposite.setLayout(new RowLayout());
+      // Details button to view certificate chain
+      detailsButton = new Button(buttonComposite, SWT.NONE);
+      detailsButton.setText(ProvUIMessages.TrustCertificateDialog_Details);
+      detailsButton.addSelectionListener(new SelectionListener()
+      {
+        public void widgetDefaultSelected(SelectionEvent e)
+        {
+          Object o = selectedCertificate;
+          if (selectedCertificate instanceof TreeNode)
+          {
+            o = ((TreeNode)selectedCertificate).getValue();
+          }
+          if (o instanceof X509Certificate)
+          {
+            X509Certificate cert = (X509Certificate)o;
+            X509CertificateViewDialog certificateDialog = new X509CertificateViewDialog(getShell(), cert);
+            certificateDialog.open();
+          }
+        }
+
+        public void widgetSelected(SelectionEvent e)
+        {
+          widgetDefaultSelected(e);
+        }
+      });
+
+      Button exportButton = new Button(buttonComposite, SWT.NONE);
+      exportButton.setText(ProvUIMessages.TrustCertificateDialog_Export);
+      exportButton.addSelectionListener(new SelectionListener()
+      {
+        public void widgetDefaultSelected(SelectionEvent e)
+        {
+          Object o = selectedCertificate;
+          if (selectedCertificate instanceof TreeNode)
+          {
+            o = ((TreeNode)selectedCertificate).getValue();
+          }
+          if (o instanceof X509Certificate)
+          {
+            X509Certificate cert = (X509Certificate)o;
+            FileDialog destination = new FileDialog(detailsButton.getShell(), SWT.SAVE);
+            destination.setFilterExtensions(new String[] { "*.der" }); //$NON-NLS-1$
+            destination.setText(ProvUIMessages.TrustCertificateDialog_Export);
+            String path = destination.open();
+            if (path == null)
+            {
+              return;
+            }
+            File destinationFile = new File(path);
+            FileOutputStream output = null;
+
+            try
+            {
+              output = new FileOutputStream(destinationFile);
+              output.write(cert.getEncoded());
+            }
+            catch (IOException ex)
+            {
+              ProvUIActivator.getDefault().getLog().log(new Status(IStatus.ERROR, ProvUIActivator.PLUGIN_ID, ex.getMessage(), ex));
+            }
+            catch (CertificateEncodingException ex)
+            {
+              ProvUIActivator.getDefault().getLog().log(new Status(IStatus.ERROR, ProvUIActivator.PLUGIN_ID, ex.getMessage(), ex));
+            }
+            finally
+            {
+              IOUtil.closeSilent(output);
+            }
+          }
+        }
+
+        public void widgetSelected(SelectionEvent e)
+        {
+          widgetDefaultSelected(e);
+        }
+      });
+    }
+
+    private Composite createUpperDialogArea(Composite parent)
+    {
+      Composite composite = (Composite)super.createDialogArea(parent);
+      initializeDialogUnits(composite);
+      createMessageArea(composite);
+
+      listViewer = CheckboxTableViewer.newCheckList(composite, SWT.BORDER);
+      GridData data = new GridData(GridData.FILL_BOTH);
+      data.heightHint = SIZING_SELECTION_WIDGET_HEIGHT;
+      data.widthHint = SIZING_SELECTION_WIDGET_WIDTH;
+      listViewer.getTable().setLayoutData(data);
+
+      listViewer.setLabelProvider(labelProvider);
+      listViewer.setContentProvider(contentProvider);
+
+      addSelectionButtons(composite);
+
+      listViewer.setInput(inputElement);
+
+      if (!getInitialElementSelections().isEmpty())
+      {
+        checkInitialSelections();
+      }
+
+      Dialog.applyDialogFont(composite);
+
+      return composite;
+    }
+
+    /**
+     * Visually checks the previously-specified elements in this dialog's list
+     * viewer.
+     */
+    private void checkInitialSelections()
+    {
+      Iterator<?> itemsToCheck = getInitialElementSelections().iterator();
+      while (itemsToCheck.hasNext())
+      {
+        listViewer.setChecked(itemsToCheck.next(), true);
+      }
+    }
+
+    /**
+     * Add the selection and deselection buttons to the dialog.
+     *
+     * @param composite org.eclipse.swt.widgets.Composite
+     */
+    private void addSelectionButtons(Composite composite)
+    {
+      Composite buttonComposite = new Composite(composite, SWT.NONE);
+      GridLayout layout = new GridLayout();
+      layout.numColumns = 0;
+      layout.marginWidth = 0;
+      layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
+      buttonComposite.setLayout(layout);
+      buttonComposite.setLayoutData(new GridData(SWT.END, SWT.TOP, true, false));
+
+      Button selectButton = createButton(buttonComposite, IDialogConstants.SELECT_ALL_ID, ProvUIMessages.TrustCertificateDialog_SelectAll, false);
+
+      SelectionListener listener = new SelectionAdapter()
+      {
+        @Override
+        public void widgetSelected(SelectionEvent e)
+        {
+          listViewer.setAllChecked(true);
+          getOkButton().setEnabled(true);
+        }
+      };
+      selectButton.addSelectionListener(listener);
+
+      Button deselectButton = createButton(buttonComposite, IDialogConstants.DESELECT_ALL_ID, ProvUIMessages.TrustCertificateDialog_DeselectAll, false);
+
+      listener = new SelectionAdapter()
+      {
+        @Override
+        public void widgetSelected(SelectionEvent e)
+        {
+          listViewer.setAllChecked(false);
+          getOkButton().setEnabled(false);
+        }
+      };
+      deselectButton.addSelectionListener(listener);
+    }
+
+    private ISelectionChangedListener getChainSelectionListener()
+    {
+      return new ISelectionChangedListener()
+      {
+        public void selectionChanged(SelectionChangedEvent event)
+        {
+          ISelection selection = event.getSelection();
+          if (selection instanceof StructuredSelection)
+          {
+            selectedCertificate = ((StructuredSelection)selection).getFirstElement();
+          }
+        }
+      };
+    }
+
+    public TreeViewer getCertificateChainViewer()
+    {
+      return certificateChainViewer;
+    }
+
+    private IDoubleClickListener getDoubleClickListener()
+    {
+      return new IDoubleClickListener()
+      {
+        public void doubleClick(DoubleClickEvent event)
+        {
+          StructuredSelection selection = (StructuredSelection)event.getSelection();
+          Object selectedElement = selection.getFirstElement();
+          if (selectedElement instanceof TreeNode)
+          {
+            TreeNode treeNode = (TreeNode)selectedElement;
+            // create and open dialog for certificate chain
+            X509CertificateViewDialog certificateViewDialog = new X509CertificateViewDialog(getShell(), (X509Certificate)treeNode.getValue());
+            certificateViewDialog.open();
+          }
+        }
+      };
+    }
+
+    private ISelectionChangedListener getParentSelectionListener()
+    {
+      return new ISelectionChangedListener()
+      {
+
+        public void selectionChanged(SelectionChangedEvent event)
+        {
+          ISelection selection = event.getSelection();
+          if (selection instanceof StructuredSelection)
+          {
+            TreeNode firstElement = (TreeNode)((StructuredSelection)selection).getFirstElement();
+            getCertificateChainViewer().setInput(new TreeNode[] { firstElement });
+            getOkButton().setEnabled(listViewer.getChecked(firstElement));
+            getCertificateChainViewer().refresh();
+          }
+        }
+      };
+    }
+
+    /**
+     * The <code>ListSelectionDialog</code> implementation of this
+     * <code>Dialog</code> method builds a list of the selected elements for later
+     * retrieval by the client and closes this dialog.
+     */
+    @Override
+    protected void okPressed()
+    {
+      // Get the input children.
+      Object[] children = contentProvider.getElements(inputElement);
+
+      // Build a list of selected children.
+      if (children != null)
+      {
+        ArrayList<Object> list = new ArrayList<Object>();
+        for (Object element : children)
+        {
+          if (listViewer.getChecked(element))
+          {
+            list.add(element);
+          }
+        }
+        setResult(list);
+      }
+      super.okPressed();
+    }
+  }
 }
diff --git a/products/org.eclipse.oomph.setup.installer.product/Installer.product b/products/org.eclipse.oomph.setup.installer.product/Installer.product
index d0bcfd8..c4b5f5f 100644
--- a/products/org.eclipse.oomph.setup.installer.product/Installer.product
+++ b/products/org.eclipse.oomph.setup.installer.product/Installer.product
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <?pde version="3.5"?>
 
-<product name="Eclipse Installer" uid="org.eclipse.oomph.setup.installer.product" id="org.eclipse.oomph.setup.installer.product" application="org.eclipse.oomph.setup.installer.application" version="1.21.0.qualifier" useFeatures="true" includeLaunchers="true">
+<product name="Eclipse Installer" uid="org.eclipse.oomph.setup.installer.product" id="org.eclipse.oomph.setup.installer.product" application="org.eclipse.oomph.setup.installer.application" version="1.22.0.qualifier" useFeatures="true" includeLaunchers="true">
 
    <configIni use="">
    </configIni>
diff --git a/products/org.eclipse.oomph.setup.installer.product/pom.xml b/products/org.eclipse.oomph.setup.installer.product/pom.xml
index fdf45d7..9d80fd1 100644
--- a/products/org.eclipse.oomph.setup.installer.product/pom.xml
+++ b/products/org.eclipse.oomph.setup.installer.product/pom.xml
@@ -15,7 +15,7 @@
 
   <groupId>org.eclipse.oomph</groupId>
   <artifactId>org.eclipse.oomph.setup.installer.product</artifactId>
-  <version>1.21.0-SNAPSHOT</version>
+  <version>1.22.0-SNAPSHOT</version>
   <packaging>eclipse-repository</packaging>
 
   <parent>