bug 35402: allow operations on borken config if improvements after
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/ConfigOperation.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/ConfigOperation.java
index 2199ec8..35da0ab 100644
--- a/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/ConfigOperation.java
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/ConfigOperation.java
@@ -35,7 +35,7 @@
 
 		IStatus status =
 			OperationsManager.getValidator().validatePendingConfig(feature);
-		if (status != null) {
+		if (status != null && status.getCode() == IStatus.ERROR) {
 			throw new CoreException(status);
 		}
 
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/OperationValidator.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/OperationValidator.java
index 40797a1..b2cea81 100644
--- a/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/OperationValidator.java
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/OperationValidator.java
@@ -129,7 +129,10 @@
 	}
 	
 	/*
-	 * Called by UI before performing operation
+	 * Called by UI before performing operation.
+	 * Returns null if no errors, a status with IStatus.WARNING code when
+	 * the initial configuration is broken, or a status with IStatus.ERROR
+	 * when there the operation introduces new errors
 	 */
 	public IStatus validatePendingInstall(IFeature oldFeature, IFeature newFeature) {
 		// check initial state
@@ -141,7 +144,7 @@
 		validateInstall(oldFeature, newFeature, status);
 
 		// report status
-		return createReportStatus(beforeStatus, status);
+		return createCombinedReportStatus(beforeStatus, status);
 	}
 	
 	/*
@@ -211,7 +214,7 @@
 		}
 
 		// report status
-		return createReportStatus(beforeStatus, status);
+		return createCombinedReportStatus(beforeStatus, status);
 	}
 
 	/*
@@ -257,7 +260,7 @@
 
 		// report status
 		if (status.size() > 0)
-			return createMultiStatus(KEY_ROOT_MESSAGE, status);
+			return createMultiStatus(KEY_ROOT_MESSAGE, status,IStatus.ERROR);
 		return null;
 	}
 
@@ -1302,13 +1305,14 @@
 
 	private static IStatus createMultiStatus(
 		String rootKey,
-		ArrayList children) {
+		ArrayList children, 
+		int code) {
 		IStatus[] carray =
 			(IStatus[]) children.toArray(new IStatus[children.size()]);
 		String message = UpdateUtils.getString(rootKey);
 		return new MultiStatus(
 			UpdateCore.getPlugin().getDescriptor().getUniqueIdentifier(),
-			IStatus.ERROR,
+			code,
 			carray,
 			message,
 			null);
@@ -1340,33 +1344,38 @@
 		return new FeatureStatus(feature, status);
 	}
 	
-	private static IStatus createReportStatus(ArrayList beforeStatus, ArrayList status) {
-		// report status
-		if (status.size() > 0) {
-			if (beforeStatus.size() > 0)
-				return createMultiStatus(KEY_ROOT_MESSAGE_INIT, beforeStatus);
-			else
-				return createMultiStatus(KEY_ROOT_MESSAGE, status);
-		}
-		return null;
-	}
+//	private static IStatus createReportStatus(ArrayList beforeStatus, ArrayList status) {
+//		// report status
+//		if (status.size() > 0) {
+//			if (beforeStatus.size() > 0)
+//				return createMultiStatus(KEY_ROOT_MESSAGE_INIT, beforeStatus,IStatus.ERROR);
+//			else
+//				return createMultiStatus(KEY_ROOT_MESSAGE, status,IStatus.ERROR);
+//		}
+//		return null;
+//	}
 	
 	private static IStatus createCombinedReportStatus(ArrayList beforeStatus, ArrayList status ) {
-		if (isBetterStatus(beforeStatus, status))
-			return null;
-		
-		// report status
-		if (status.size() > 0) {
-			if (beforeStatus.size() > 0){
-				ArrayList combined = new ArrayList();
-				combined.add(createMultiStatus("ActivityConstraints.beforeMessage", beforeStatus));
-				combined.add(createMultiStatus("ActivityConstraints.afterMessage", status));
-				return createMultiStatus(KEY_ROOT_MESSAGE_INIT, combined);
+		if (beforeStatus.size() == 0) { // good initial config
+			if (status.size() == 0) {
+				return null; // all fine
 			} else {
-				return createMultiStatus(KEY_ROOT_MESSAGE, status);
+				return createMultiStatus(KEY_ROOT_MESSAGE, status,IStatus.ERROR); // error after operation
 			}
-		}
-		return null;		
+		} else { // beforeStatus.size() > 0  : initial config errors
+			if (status.size() == 0) {
+				return null; // errors will be fixed
+			} else {
+				if (isBetterStatus(beforeStatus, status)) {
+					return createMultiStatus("ActivityConstraints.warning", beforeStatus, IStatus.WARNING); // errors may be fixed
+				} else {
+					ArrayList combined = new ArrayList();
+					combined.add(createMultiStatus("ActivityConstraints.beforeMessage", beforeStatus,IStatus.ERROR));
+					combined.add(createMultiStatus("ActivityConstraints.afterMessage", status, IStatus.ERROR));
+					return createMultiStatus(KEY_ROOT_MESSAGE_INIT, combined,IStatus.ERROR);
+				}
+			}
+		} 
 	}
 	
 	private static ArrayList createList(String commaSeparatedList) {
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/RevertConfigurationOperation.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/RevertConfigurationOperation.java
index d2ac446..0b7fe5b 100644
--- a/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/RevertConfigurationOperation.java
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/RevertConfigurationOperation.java
@@ -37,7 +37,7 @@
 		throws CoreException, InvocationTargetException {
 		IStatus status =
 			OperationsManager.getValidator().validatePendingRevert(config);
-		if (status != null) {
+		if (status != null && status.getCode() == IStatus.ERROR) {
 			throw new CoreException(status);
 		}
 
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/UnconfigOperation.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/UnconfigOperation.java
index f8ddd8d..52a62ad 100644
--- a/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/UnconfigOperation.java
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/UnconfigOperation.java
@@ -35,7 +35,7 @@
 
 		IStatus status =
 			OperationsManager.getValidator().validatePendingUnconfig(feature);
-		if (status != null) {
+		if (status != null && status.getCode() == IStatus.ERROR) {
 			throw new CoreException(status);
 		}
 
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/UpdateManagerResources.properties b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/UpdateManagerResources.properties
index 46d8f15..811b59a 100644
--- a/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/UpdateManagerResources.properties
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/UpdateManagerResources.properties
@@ -12,7 +12,7 @@
 #
 #
 
-
+ActivityConstraints.warning=The current configuration contains errors and this operation can have unpredictable results.
 ActivityConstraints.rootMessage = Requested operation cannot be performed because it would invalidate the current configuration. See details for more information.
 ActivityConstraints.rootMessageInitial = Current configuration contains errors that are not corrected by the requested operation and more errors would be introduced. See details for more information.
 ActivityConstraints.beforeMessage = ----- Current configuration problems -----
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/search/UpdatesSearchCategory.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/search/UpdatesSearchCategory.java
index 32b1d66..4056d77 100644
--- a/update/org.eclipse.update.core/src/org/eclipse/update/internal/search/UpdatesSearchCategory.java
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/search/UpdatesSearchCategory.java
@@ -298,7 +298,7 @@
 			if (!UpdateUtils.hasLicense(job.getFeature()))
 				continue;
 			IStatus status = OperationsManager.getValidator().validatePendingInstall(job.getOldFeature(), job.getFeature());
-			if (status == null) {
+			if (status == null || status.getCode() == IStatus.WARNING) {
 				if (hit.isPatch()) {
 					IFeature patch = job.getFeature();
 					// Do not add the patch if already installed
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/standalone/DisableCommand.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/standalone/DisableCommand.java
index 43c026c..aa2ff3a 100644
--- a/update/org.eclipse.update.core/src/org/eclipse/update/internal/standalone/DisableCommand.java
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/standalone/DisableCommand.java
@@ -99,7 +99,9 @@
 			IStatus status =
 				OperationsManager.getValidator().validatePendingUnconfig(
 					feature);
-			return status == null;
+			if (status != null && status.getCode() == IStatus.WARNING)
+				UpdateCore.log(status);
+			return status == null || status.getCode() == IStatus.WARNING;
 		}
 
 		final IUnconfigFeatureOperation configOperation =
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/standalone/EnableCommand.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/standalone/EnableCommand.java
index cba4500..83e14c8 100644
--- a/update/org.eclipse.update.core/src/org/eclipse/update/internal/standalone/EnableCommand.java
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/standalone/EnableCommand.java
@@ -99,7 +99,9 @@
 		if (isVerifyOnly()) {
 			IStatus status =
 				OperationsManager.getValidator().validatePendingConfig(feature);
-			return status == null;
+			if (status != null && status.getCode() == IStatus.WARNING)
+				UpdateCore.log(status);
+			return status == null || status.getCode() == IStatus.WARNING;
 		}
 
 		final IConfigFeatureOperation configOperation =
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/DeltaAdapter.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/DeltaAdapter.java
index 069a995..27f92f5 100644
--- a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/DeltaAdapter.java
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/DeltaAdapter.java
@@ -143,7 +143,7 @@
 	}
 
 	public boolean isValid() {
-		return getStatus() == null;
+		return getStatus() == null || status.getCode() == IStatus.WARNING;
 	}
 
 	private void initializeFeatures() {
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/InstallDeltaWizardPage.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/InstallDeltaWizardPage.java
index a912e2b..23ec253 100644
--- a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/InstallDeltaWizardPage.java
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/InstallDeltaWizardPage.java
@@ -201,7 +201,7 @@
 		if (selection.size() == 1) {
 			Object obj = selection.getFirstElement();
 			if (obj instanceof DeltaAdapter) {
-				enableShowErrors = !((DeltaAdapter) obj).isValid();
+				enableShowErrors = ((DeltaAdapter) obj).getStatus() != null;
 			}
 		}
 		if (enableDelete) {
@@ -236,10 +236,8 @@
 		DeltaAdapter adapter = (DeltaAdapter) sel.getFirstElement();
 		IStatus status = adapter.getStatus();
 
-		if (status != null) {
-			ErrorDialog.openError(getShell(), null, null, status);
-			return;
-		}
+		setPageComplete(status == null || status.getCode() == IStatus.WARNING);
+		ErrorDialog.openError(getShell(), null, null, status);
 	}
 
 	private void handleCheckStateChanged(Object obj, boolean checked) {
@@ -282,6 +280,8 @@
 		int nremoved = 0;
 		int nselected = 0;
 		int errors = 0;
+		int warnings = 0;
+		String message = null;
 
 		for (int i = 0; i < features.size(); i++) {
 			DeltaAdapter adapter = (DeltaAdapter) features.get(i);
@@ -289,15 +289,24 @@
 				nremoved++;
 			else if (adapter.isSelected()) {
 				nselected++;
-				if (adapter.getStatus() != null)
+				IStatus status = adapter.getStatus();
+				if (status != null && status.getCode() == IStatus.WARNING) {
+					warnings++;
+					message = status.getMessage();
+				} else if (status != null && status.getCode() == IStatus.ERROR) {
 					errors++;
+				}
 			}
 		}
 		setPageComplete(errors == 0 && (nremoved > 0 || nselected > 0));
-		String message = null;
-		if (errors > 0)
-			message = UpdateUI.getString("InstallDeltaWizard.message"); //$NON-NLS-1$
-		setErrorMessage(message);
+		if (errors > 0) {
+			setErrorMessage(UpdateUI.getString("InstallDeltaWizard.message")); //$NON-NLS-1$
+		} else if (warnings > 0) {
+			setErrorMessage(null);
+			setMessage(message, IMessageProvider.WARNING);
+		} else {
+			setErrorMessage(null);
+		}
 	}
 
 	public DeltaAdapter[] getDeltaAdapters() {
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/ReplaceFeatureVersionWizardPage.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/ReplaceFeatureVersionWizardPage.java
index 275a4bd..22a2a3c 100644
--- a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/ReplaceFeatureVersionWizardPage.java
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/ReplaceFeatureVersionWizardPage.java
@@ -86,7 +86,22 @@
 
 		tableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
 			public void selectionChanged(SelectionChangedEvent event) {
-				setPageComplete(true);
+				IStructuredSelection ssel = (IStructuredSelection)tableViewer.getSelection();
+				if (ssel == null)
+					return;
+				IFeature chosenFeature = (IFeature)ssel.getFirstElement();
+				IStatus validationStatus =
+					OperationsManager.getValidator().validatePendingReplaceVersion(currentFeature, chosenFeature);
+				setPageComplete(validationStatus == null || validationStatus.getCode() == IStatus.WARNING);
+		
+				if (validationStatus == null) {
+					setErrorMessage(null);
+				} else if (validationStatus.getCode() == IStatus.WARNING) {
+					setErrorMessage(null);
+					setMessage(validationStatus.getMessage(), IMessageProvider.WARNING);
+				} else {
+					setErrorMessage(validationStatus.getMessage());
+				}
 			}
 		});
 		
@@ -105,16 +120,16 @@
 	}
 	
 	private boolean swap(final IFeature currentFeature, final IFeature anotherFeature) {
-		IStatus status =
-			OperationsManager.getValidator().validatePendingReplaceVersion(currentFeature, anotherFeature);
-		if (status != null) {
-			ErrorDialog.openError(
-				UpdateUI.getActiveWorkbenchShell(),
-				null,
-				null,
-				status);
-			return false;
-		}
+//		IStatus status =
+//			OperationsManager.getValidator().validatePendingReplaceVersion(currentFeature, anotherFeature);
+//		if (status != null) {
+//			ErrorDialog.openError(
+//				UpdateUI.getActiveWorkbenchShell(),
+//				null,
+//				null,
+//				status);
+//			return false;
+//		}
 
 		IRunnableWithProgress operation = new IRunnableWithProgress() {
 			public void run(IProgressMonitor monitor)
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/RevertConfigurationWizardPage.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/RevertConfigurationWizardPage.java
index 1b4b1c5..57cd4a3 100644
--- a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/RevertConfigurationWizardPage.java
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/RevertConfigurationWizardPage.java
@@ -194,7 +194,7 @@
 
 		IStatus status =
 			OperationsManager.getValidator().validatePendingRevert(target);
-		if (status != null) {
+		if (status != null && status.getCode() == IStatus.ERROR) {
 			ErrorDialog.openError(
 				UpdateUI.getActiveWorkbenchShell(),
 				null,
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/ReviewPage.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/ReviewPage.java
index cd78241..0b44137 100644
--- a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/ReviewPage.java
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/ReviewPage.java
@@ -17,6 +17,7 @@
 import org.eclipse.jface.dialogs.*;
 import org.eclipse.jface.dialogs.Dialog;
 import org.eclipse.jface.viewers.*;
+import org.eclipse.jface.wizard.*;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.BusyIndicator;
 import org.eclipse.swt.events.*;
@@ -590,14 +591,16 @@
 		IInstallFeatureOperation[] jobs = getSelectedJobs();
 		validationStatus =
 			OperationsManager.getValidator().validatePendingChanges(jobs);
-		setPageComplete(validationStatus == null);
-		String errorMessage = null;
-
-		if (validationStatus != null) {
-			errorMessage =
-				UpdateUI.getString("InstallWizard.ReviewPage.invalid.long"); //$NON-NLS-1$
+		setPageComplete(validationStatus == null || validationStatus.getCode() == IStatus.WARNING);
+		
+		if (validationStatus == null) {
+			setErrorMessage(null);
+		} else if (validationStatus.getCode() == IStatus.WARNING) {
+			setErrorMessage(null);
+			setMessage(validationStatus.getMessage(), IMessageProvider.WARNING);
+		} else {
+			setErrorMessage(UpdateUI.getString("InstallWizard.ReviewPage.invalid.long")); //$NON-NLS-1$
 		}
-		setErrorMessage(errorMessage);
 	}
 
 	private void showStatus() {