Add remediation support to Discovery UI
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.ui.discovery/META-INF/MANIFEST.MF
index 286ffc3..3a804d0 100644
--- a/bundles/org.eclipse.equinox.p2.ui.discovery/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/META-INF/MANIFEST.MF
@@ -24,4 +24,5 @@
  org.eclipse.equinox.internal.p2.ui.discovery.util;x-internal:=true,
  org.eclipse.equinox.internal.p2.ui.discovery.wizards;x-internal:=true
 Bundle-ClassPath: .
-Import-Package: com.ibm.icu.text
+Import-Package: com.ibm.icu.text,
+ org.eclipse.equinox.p2.planner;version="2.0.0"
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/operations/DiscoveryInstallOperation.java b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/operations/DiscoveryInstallOperation.java
index cbeb286..4212a50 100644
--- a/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/operations/DiscoveryInstallOperation.java
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/operations/DiscoveryInstallOperation.java
@@ -16,6 +16,7 @@
 import java.util.*;
 import org.eclipse.core.runtime.*;
 import org.eclipse.equinox.internal.p2.discovery.model.CatalogItem;
+import org.eclipse.equinox.internal.p2.ui.ProvUIMessages;
 import org.eclipse.equinox.internal.p2.ui.discovery.DiscoveryUi;
 import org.eclipse.equinox.internal.p2.ui.discovery.util.WorkbenchUtil;
 import org.eclipse.equinox.internal.p2.ui.discovery.wizards.Messages;
@@ -59,7 +60,7 @@
 
 	public void run(IProgressMonitor progressMonitor) throws InvocationTargetException, InterruptedException {
 		try {
-			SubMonitor monitor = SubMonitor.convert(progressMonitor, Messages.InstallConnectorsJob_task_configuring, 100);
+			SubMonitor monitor = SubMonitor.convert(progressMonitor, Messages.InstallConnectorsJob_task_configuring, 150);
 			try {
 				final IInstallableUnit[] ius = computeInstallableUnits(monitor.newChild(50));
 
@@ -69,11 +70,22 @@
 
 				checkCancelled(monitor);
 
-				Display.getDefault().asyncExec(new Runnable() {
-					public void run() {
-						provisioningUI.openInstallWizard(Arrays.asList(ius), installOperation, null);
-					}
-				});
+				if (installOperation.getResolutionResult().getSeverity() > IStatus.WARNING) {
+					monitor.setTaskName(ProvUIMessages.ProvisioningOperationWizard_Remediation_Operation);
+					final RemediationOperation remediationOperation = new RemediationOperation(provisioningUI.getSession(), installOperation.getProfileChangeRequest());
+					remediationOperation.getResolveJob(monitor.newChild(50));
+					Display.getDefault().asyncExec(new Runnable() {
+						public void run() {
+							provisioningUI.openInstallWizard(Arrays.asList(ius), installOperation, remediationOperation, null);
+						}
+					});
+				} else {
+					Display.getDefault().asyncExec(new Runnable() {
+						public void run() {
+							provisioningUI.openInstallWizard(Arrays.asList(ius), installOperation, null);
+						}
+					});
+				}
 			} finally {
 				monitor.done();
 			}
@@ -92,10 +104,7 @@
 
 	private InstallOperation resolve(IProgressMonitor monitor, final IInstallableUnit[] ius, URI[] repositories) throws CoreException {
 		final InstallOperation installOperation = provisioningUI.getInstallOperation(Arrays.asList(ius), repositories);
-		IStatus operationStatus = installOperation.resolveModal(new SubProgressMonitor(monitor, installableConnectors.size()));
-		if (operationStatus.getSeverity() > IStatus.WARNING) {
-			throw new CoreException(operationStatus);
-		}
+		installOperation.resolveModal(new SubProgressMonitor(monitor, installableConnectors.size()));
 		return installOperation;
 	}
 
diff --git a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/dialogs/PreselectedIUInstallWizard.java b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/dialogs/PreselectedIUInstallWizard.java
index 7d45188..10a548c 100644
--- a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/dialogs/PreselectedIUInstallWizard.java
+++ b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/dialogs/PreselectedIUInstallWizard.java
@@ -21,6 +21,7 @@
 import org.eclipse.equinox.p2.operations.ProfileChangeOperation;
 import org.eclipse.equinox.p2.ui.LoadMetadataRepositoryJob;
 import org.eclipse.equinox.p2.ui.ProvisioningUI;
+import org.eclipse.jface.wizard.IWizardPage;
 
 /**
  * An Install wizard that is invoked when the user has already selected which
@@ -38,6 +39,14 @@
 		setDefaultPageImageDescriptor(ProvUIImages.getImageDescriptor(ProvUIImages.WIZARD_BANNER_INSTALL));
 	}
 
+	@Override
+	public IWizardPage getStartingPage() {
+		if (remediationOperation != null && remediationOperation.hasRemedies()) {
+			return getNextPage(mainPage);
+		}
+		return super.getStartingPage();
+	}
+
 	protected ISelectableIUsPage createMainPage(IUElementListRoot input, Object[] selections) {
 		mainPage = new SelectableIUsPage(ui, this, input, selections);
 		mainPage.setTitle(ProvUIMessages.PreselectedIUInstallWizard_Title);
@@ -88,8 +97,8 @@
 
 	@Override
 	protected RemediationPage createRemediationPage() {
-		// TODO Auto-generated method stub
-		return null;
+		remediationPage = new RemediationPage(ui, this, root, operation);
+		return remediationPage;
 	}
 
 }
diff --git a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/p2/ui/ProvisioningUI.java b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/p2/ui/ProvisioningUI.java
index 670b753..38b45ef 100644
--- a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/p2/ui/ProvisioningUI.java
+++ b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/p2/ui/ProvisioningUI.java
@@ -200,6 +200,23 @@
 	 * @return the wizard return code
 	 */
 	public int openInstallWizard(Collection<IInstallableUnit> initialSelections, InstallOperation operation, LoadMetadataRepositoryJob job) {
+		return openInstallWizard(initialSelections, operation, null, job);
+	}
+
+	/**
+	 * Open an install wizard for installing the specified IInstallableUnits and remediationOperation.
+	 * 
+	 * @param initialSelections the IInstallableUnits that should be selected when the wizard opens.  May be <code>null</code>.
+	 * @param operation the operation describing the proposed install.  If this operation is not <code>null</code>, then a wizard showing
+	 * only the IInstallableUnits described in the operation will be shown.  If the operation is <code>null</code>, then a
+	 * wizard allowing the user to browse the repositories will be opened.
+	 * @param remediationOperation the alternate operations if the proposed update failed.  May be <code>null</code>.
+	 * @param job a repository load job that is loading or has already loaded the repositories.  Can be used to pass along
+	 * an in-memory repository reference to the wizard.
+	 * 
+	 * @return the wizard return code
+	 */
+	public int openInstallWizard(Collection<IInstallableUnit> initialSelections, InstallOperation operation, RemediationOperation remediationOperation, LoadMetadataRepositoryJob job) {
 		if (operation == null) {
 			InstallWizard wizard = new InstallWizard(this, operation, initialSelections, job);
 			WizardDialog dialog = new ProvisioningWizardDialog(ProvUI.getDefaultParentShell(), wizard);
@@ -208,6 +225,7 @@
 			return dialog.open();
 		}
 		PreselectedIUInstallWizard wizard = new PreselectedIUInstallWizard(this, operation, initialSelections, job);
+		wizard.setRemediationOperation(remediationOperation);
 		WizardDialog dialog = new ProvisioningWizardDialog(ProvUI.getDefaultParentShell(), wizard);
 		dialog.create();
 		PlatformUI.getWorkbench().getHelpSystem().setHelp(dialog.getShell(), IProvHelpContextIds.INSTALL_WIZARD);