Bug 473847 - Support DialogCompare for pure E4 applications

Removes runtime dependencies to the workbench which allows pure E4
applications to execute comparisons within dialogs without exceptions.

Bug: 473847
Signed-off-by: Stefan Dirix <sdirix@eclipsesource.com>
Change-Id: I51851b0cab6dace0bc44bc9b6d30dfad32eeff39
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/CompareEditorInput.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/CompareEditorInput.java
index 0d5ff3f..1f5d744 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/CompareEditorInput.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/CompareEditorInput.java
@@ -10,6 +10,7 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Stefan Dirix (sdirix@eclipsesource.com) - Bug 473847: Minimum E4 Compatibility of Compare
  *******************************************************************************/
 package org.eclipse.compare;
 
@@ -562,7 +563,7 @@
 			}
 			control.addDisposeListener(ev -> handleDispose());
 		});
-		if (fHelpContextId != null)
+		if (fHelpContextId != null && PlatformUI.isWorkbenchRunning())
 			PlatformUI.getWorkbench().getHelpSystem().setHelp(fComposite, fHelpContextId);
 		contentsCreated();
 		return fComposite;
@@ -1459,7 +1460,7 @@
 
 	private boolean saveChanges() {
 		try {
-			PlatformUI.getWorkbench().getProgressService().run(true, true, monitor -> {
+			Utilities.executeRunnable(monitor -> {
 				try {
 					saveChanges(monitor);
 				} catch (CoreException e) {
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/contentmergeviewer/TextMergeViewer.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/contentmergeviewer/TextMergeViewer.java
index 47d7ce0..63ae286 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/contentmergeviewer/TextMergeViewer.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/contentmergeviewer/TextMergeViewer.java
@@ -20,6 +20,7 @@
  *     Robin Stocker (robin@nibor.org) - Bug 398594: [Edit] Enable center arrow buttons when editable and for both sides
  *     Robin Stocker (robin@nibor.org) - Bug 399960: [Edit] Make merge arrow buttons easier to hit
  *     John Hendrikx (hjohn@xs4all.nl) - Bug 541401 - [regression] Vertical scrollbar thumb size is wrong in compare view
+ *     Stefan Dirix (sdirix@eclipsesource.com) - Bug 473847: Minimum E4 Compatibility of Compare
  *******************************************************************************/
 package org.eclipse.compare.contentmergeviewer;
 
@@ -2036,7 +2037,9 @@
 	 */
 	@Override
 	protected void createControls(Composite composite) {
-		PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, ICompareContextIds.TEXT_MERGE_VIEW);
+		if (PlatformUI.isWorkbenchRunning()) {
+			PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, ICompareContextIds.TEXT_MERGE_VIEW);
+		}
 
 		// 1st row
 		if (fMarginWidth > 0) {
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/BinaryCompareViewer.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/BinaryCompareViewer.java
index ede59b1..1643acf 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/BinaryCompareViewer.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/BinaryCompareViewer.java
@@ -51,7 +51,9 @@
 
 	public BinaryCompareViewer(Composite parent, final CompareConfiguration cc) {
 
-		PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, ICompareContextIds.BINARY_COMPARE_VIEW);
+		if(PlatformUI.isWorkbenchRunning()) {
+			PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, ICompareContextIds.BINARY_COMPARE_VIEW);
+		}
 
 		fBundle= ResourceBundle.getBundle(BUNDLE_NAME);
 
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareContainer.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareContainer.java
index 31d5f28..5b03a63 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareContainer.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareContainer.java
@@ -24,7 +24,6 @@
 import org.eclipse.jface.viewers.ISelectionProvider;
 import org.eclipse.ui.IActionBars;
 import org.eclipse.ui.IWorkbenchPart;
-import org.eclipse.ui.PlatformUI;
 import org.eclipse.ui.services.IServiceLocator;
 
 public class CompareContainer implements ICompareContainer {
@@ -68,7 +67,7 @@
 	public void run(boolean fork, boolean cancelable,
 			IRunnableWithProgress runnable)
 			throws InvocationTargetException, InterruptedException {
-		PlatformUI.getWorkbench().getProgressService().run(fork, cancelable, runnable);
+		Utilities.executeRunnable(runnable, fork, cancelable);
 	}
 
 	@Override
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareContentViewerSwitchingPane.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareContentViewerSwitchingPane.java
index 3026cc9..c0fe685 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareContentViewerSwitchingPane.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareContentViewerSwitchingPane.java
@@ -1,8 +1,7 @@
 /*******************************************************************************
  * Copyright (c) 2009, 2017 IBM Corporation and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
  * https://www.eclipse.org/legal/epl-2.0/
  *
@@ -10,6 +9,7 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Stefan Dirix (sdirix@eclipsesource.com) - Bug 473847: Minimum E4 Compatibility of Compare
  *******************************************************************************/
 package org.eclipse.compare.internal;
 
@@ -47,7 +47,6 @@
 import org.eclipse.swt.widgets.MenuItem;
 import org.eclipse.swt.widgets.ToolBar;
 import org.eclipse.swt.widgets.ToolItem;
-import org.eclipse.ui.PlatformUI;
 
 public class CompareContentViewerSwitchingPane extends CompareViewerSwitchingPane {
 	private static final String OPTIMIZED_INFO_IMAGE_NAME = "obj16/message_info.png"; //$NON-NLS-1$
@@ -122,8 +121,7 @@
 		toolBar = new ToolBar(composite, SWT.FLAT);
 		toolBar.setVisible(false); // hide by default
 		final ToolItem toolItem = new ToolItem(toolBar, SWT.PUSH, 0);
-		toolItem.setImage(PlatformUI.getWorkbench().getSharedImages().getImage(
-				/* IWorkbenchGraphicConstants */"IMG_LCL_VIEW_MENU")); //$NON-NLS-1$
+		Utilities.setMenuImage(toolItem);
 		toolItem.setToolTipText(CompareMessages.CompareContentViewerSwitchingPane_switchButtonTooltip);
 		toolItem.addSelectionListener(new SelectionAdapter() {
 			@Override
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareDialog.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareDialog.java
index ed303ba..6dc96d2 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareDialog.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareDialog.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * Copyright (c) 2000, 2016 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -10,6 +10,7 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Stefan Dirix (sdirix@eclipsesource.com) - Bug 473847: Minimum E4 Compatibility of Compare
  *******************************************************************************/
 package org.eclipse.compare.internal;
 
@@ -211,7 +212,7 @@
 	@Override
 	protected void configureShell(Shell newShell) {
 		super.configureShell(newShell);
-		if (getHelpContextId() != null)
+		if (PlatformUI.isWorkbenchRunning() && getHelpContextId() != null)
 			PlatformUI.getWorkbench().getHelpSystem().setHelp(newShell, getHelpContextId());
 	}
 
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareEditor.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareEditor.java
index 7da9a8e..c02f3a5 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareEditor.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareEditor.java
@@ -454,7 +454,11 @@
 					}
 				}
 				fPageBook.showPage(fControl);
-				PlatformUI.getWorkbench().getHelpSystem().setHelp(fControl, ICompareContextIds.COMPARE_EDITOR);
+
+				if (PlatformUI.isWorkbenchRunning()) {
+					PlatformUI.getWorkbench().getHelpSystem().setHelp(fControl, ICompareContextIds.COMPARE_EDITOR);
+				}
+
 				if (isActive()) {
 					setFocus();
 				}
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareEditorContributor.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareEditorContributor.java
index 1d54e91..870e838 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareEditorContributor.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareEditorContributor.java
@@ -53,22 +53,20 @@
 	public CompareEditorContributor() {
 		ResourceBundle bundle= CompareUI.getResourceBundle();
 
-		IWorkbenchHelpSystem helpSystem= PlatformUI.getWorkbench().getHelpSystem();
-
 		fIgnoreWhitespace= ChangePropertyAction.createIgnoreWhiteSpaceAction(bundle, null);
-		helpSystem.setHelp(fIgnoreWhitespace, ICompareContextIds.IGNORE_WHITESPACE_ACTION);
-
 		fNext= new NavigationAction(bundle, true);
-		helpSystem.setHelp(fNext, ICompareContextIds.GLOBAL_NEXT_DIFF_ACTION);
-
 		fPrevious= new NavigationAction(bundle, false);
-		helpSystem.setHelp(fPrevious, ICompareContextIds.GLOBAL_PREVIOUS_DIFF_ACTION);
-
 		fToolbarNext= new NavigationAction(bundle, true);
-		helpSystem.setHelp(fToolbarNext, ICompareContextIds.NEXT_DIFF_ACTION);
-
 		fToolbarPrevious= new NavigationAction(bundle, false);
-		helpSystem.setHelp(fToolbarPrevious, ICompareContextIds.PREVIOUS_DIFF_ACTION);
+
+		if (PlatformUI.isWorkbenchRunning()) {
+			IWorkbenchHelpSystem helpSystem = PlatformUI.getWorkbench().getHelpSystem();
+			helpSystem.setHelp(fIgnoreWhitespace, ICompareContextIds.IGNORE_WHITESPACE_ACTION);
+			helpSystem.setHelp(fNext, ICompareContextIds.GLOBAL_NEXT_DIFF_ACTION);
+			helpSystem.setHelp(fPrevious, ICompareContextIds.GLOBAL_PREVIOUS_DIFF_ACTION);
+			helpSystem.setHelp(fToolbarNext, ICompareContextIds.NEXT_DIFF_ACTION);
+			helpSystem.setHelp(fToolbarPrevious, ICompareContextIds.PREVIOUS_DIFF_ACTION);
+		}
 	}
 
 	@Override
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareHandlerService.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareHandlerService.java
index 564726c..a25353e 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareHandlerService.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareHandlerService.java
@@ -10,6 +10,7 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Stefan Dirix (sdirix@eclipsesource.com) - Bug 473847: Minimum E4 Compatibility of Compare
  *******************************************************************************/
 package org.eclipse.compare.internal;
 
@@ -44,6 +45,10 @@
 			if (service != null)
 				return new CompareHandlerService(container, null);
 		}
+		if (!PlatformUI.isWorkbenchRunning() && shell != null) {
+			Expression e = new ActiveShellExpression(shell);
+			return new CompareHandlerService(container, e);
+		}
 		if (container.getWorkbenchPart() == null && shell != null) {
 			// We're in a dialog so we can use an active shell expression
 			IHandlerService service = PlatformUI.getWorkbench().getService(IHandlerService.class);
@@ -92,7 +97,7 @@
 				if (service != null)
 					fHandlerService = service;
 			}
-			if (fHandlerService == null && fContainer.getWorkbenchPart() == null && fExpression != null) {
+			if (PlatformUI.isWorkbenchRunning() && fHandlerService == null && fContainer.getWorkbenchPart() == null && fExpression != null) {
 				// We're in a dialog so we can use an active shell expression
 				IHandlerService service = PlatformUI.getWorkbench().getService(IHandlerService.class);
 				if (service != null) {
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/ComparePreferencePage.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/ComparePreferencePage.java
index 133adb2..caa454e 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/ComparePreferencePage.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/ComparePreferencePage.java
@@ -249,8 +249,9 @@
 
 	@Override
 	protected Control createContents(Composite parent) {
-
-		PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, ICompareContextIds.COMPARE_PREFERENCE_PAGE);
+		if (PlatformUI.isWorkbenchRunning()) {
+			PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, ICompareContextIds.COMPARE_PREFERENCE_PAGE);
+		}
 
 		fOverlayStore.load();
 		fOverlayStore.start();
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareStructureViewerSwitchingPane.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareStructureViewerSwitchingPane.java
index 1593d85..4f4d799 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareStructureViewerSwitchingPane.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareStructureViewerSwitchingPane.java
@@ -10,6 +10,7 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Stefan Dirix (sdirix@eclipsesource.com) - Bug 473847: Minimum E4 Compatibility of Compare
  *******************************************************************************/
 package org.eclipse.compare.internal;
 
@@ -43,7 +44,6 @@
 import org.eclipse.swt.widgets.MenuItem;
 import org.eclipse.swt.widgets.ToolBar;
 import org.eclipse.swt.widgets.ToolItem;
-import org.eclipse.ui.PlatformUI;
 
 public class CompareStructureViewerSwitchingPane extends
 		CompareViewerSwitchingPane {
@@ -111,8 +111,7 @@
 		toolBar = new ToolBar(composite, SWT.FLAT);
 		toolBar.setVisible(false); // hide by default
 		final ToolItem toolItem = new ToolItem(toolBar, SWT.PUSH, 0);
-		toolItem.setImage(PlatformUI.getWorkbench().getSharedImages().getImage(
-				/* IWorkbenchGraphicConstants */"IMG_LCL_VIEW_MENU")); //$NON-NLS-1$
+		Utilities.setMenuImage(toolItem);
 		toolItem
 				.setToolTipText(CompareMessages.CompareStructureViewerSwitchingPane_switchButtonTooltip);
 		toolItem.addSelectionListener(new SelectionAdapter() {
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareUIPlugin.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareUIPlugin.java
index 693ca3d..384504d 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareUIPlugin.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareUIPlugin.java
@@ -12,6 +12,7 @@
  *     IBM Corporation - initial API and implementation
  *     Carsten Pfeiffer <carsten.pfeiffer@gebit.de> - CompareUIPlugin.getCommonType() returns null if left or right side is not available - https://bugs.eclipse.org/311843
  *     Stefan Xenos <sxenos@gmail.com> (Google) - bug 448968 - Add diagnostic logging
+ *     Stefan Dirix <sdirix@eclipsesource.com> - bug 473847: Minimum E4 Compatibility of Compare
  *******************************************************************************/
 package org.eclipse.compare.internal;
 
@@ -475,17 +476,23 @@
 	}
 
 	/**
-	 * Returns the SWT Shell of the active workbench window or <code>null</code> if
+	 * If the workbench is running returns the SWT Shell of the active workbench window or <code>null</code> if
 	 * no workbench window is active.
 	 *
-	 * @return the SWT Shell of the active workbench window, or <code>null</code> if
-	 * 	no workbench window is active
+	 * If the workbench is not running, returns the shell of the default display.
+	 *
+	 * @return If the workbench is running, returns the SWT Shell of the active workbench window, or <code>null</code> if
+	 * 	no workbench window is active. Otherwise returns the shell of the default display.
 	 */
 	public static Shell getShell() {
-		IWorkbenchWindow window = getActiveWorkbenchWindow();
-		if (window == null)
-			return null;
-		return window.getShell();
+		if(PlatformUI.isWorkbenchRunning()){
+			IWorkbenchWindow window = getActiveWorkbenchWindow();
+			if (window == null)
+				return null;
+			return window.getShell();
+		}
+
+		return Display.getDefault().getActiveShell();
 	}
 
 	/**
@@ -606,10 +613,12 @@
 	public boolean compareResultOK(CompareEditorInput input, IRunnableContext context) {
 		final Shell shell= getShell();
 		try {
-			// run operation in separate thread and make it cancelable
-			if (context == null)
-				context = PlatformUI.getWorkbench().getProgressService();
-			context.run(true, true, input);
+			// run operation in context if possible
+			if (context != null) {
+				context.run(true, true, input);
+			} else {
+				Utilities.executeRunnable(input);
+			}
 
 			String message= input.getMessage();
 			if (message != null) {
@@ -1377,13 +1386,16 @@
 	}
 
 	private void internalOpenDialog(final CompareEditorInput input) {
-		Runnable runnable = () -> {
-			CompareDialog dialog = new CompareDialog(PlatformUI
-					.getWorkbench().getModalDialogShellProvider()
-					.getShell(), input);
+		syncExec(() -> {
+			Shell shell;
+			if (PlatformUI.isWorkbenchRunning()) {
+				shell = PlatformUI.getWorkbench().getModalDialogShellProvider().getShell();
+			} else {
+				shell = Display.getDefault().getActiveShell();
+			}
+			CompareDialog dialog = new CompareDialog(shell, input);
 			dialog.open();
-		};
-		syncExec(runnable);
+		});
 	}
 
 	private void syncExec(Runnable runnable) {
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/EditionAction.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/EditionAction.java
index b6612c7..5619280 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/EditionAction.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/EditionAction.java
@@ -24,6 +24,10 @@
 import org.eclipse.compare.IStreamContentAccessor;
 import org.eclipse.compare.ITypedElement;
 import org.eclipse.compare.ResourceNode;
+import org.eclipse.core.filebuffers.FileBuffers;
+import org.eclipse.core.filebuffers.ITextFileBuffer;
+import org.eclipse.core.filebuffers.ITextFileBufferManager;
+import org.eclipse.core.filebuffers.LocationKind;
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IFileState;
 import org.eclipse.core.runtime.CoreException;
@@ -218,6 +222,24 @@
 	}
 
 	private IDocument getDocument(IFile file) {
+		if (file == null) {
+			return null;
+		}
+
+		// first try FileBuffer API
+		ITextFileBufferManager bufferManager = FileBuffers.getTextFileBufferManager();
+		ITextFileBuffer buffer = bufferManager.getTextFileBuffer(file.getFullPath(), LocationKind.IFILE);
+		if (buffer != null) {
+			IDocument document = buffer.getDocument();
+			if (document != null) {
+				return document;
+			}
+		}
+
+		// if unsuccessful, try open editors
+		if (!PlatformUI.isWorkbenchRunning()) {
+			return null;
+		}
 		IWorkbench wb= PlatformUI.getWorkbench();
 		if (wb == null)
 			return null;
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/ImageMergeViewer.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/ImageMergeViewer.java
index 50d8da2..bc0ec4c 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/ImageMergeViewer.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/ImageMergeViewer.java
@@ -44,7 +44,9 @@
 	public ImageMergeViewer(Composite parent, int styles, CompareConfiguration mp) {
 		super(styles, ResourceBundle.getBundle(BUNDLE_NAME), mp);
 
-		PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, ICompareContextIds.IMAGE_COMPARE_VIEW);
+		if (PlatformUI.isWorkbenchRunning()) {
+			PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, ICompareContextIds.IMAGE_COMPARE_VIEW);
+		}
 
 		buildControl(parent);
 		String title= Utilities.getString(getResourceBundle(), "title"); //$NON-NLS-1$
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/MergeSourceViewer.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/MergeSourceViewer.java
index 1728df9..f44b6ef 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/MergeSourceViewer.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/MergeSourceViewer.java
@@ -12,6 +12,7 @@
  *     IBM Corporation - initial API and implementation
  *     Max Weninger (max.weninger@windriver.com) - Bug 131895 [Edit] Undo in compare
  *     Max Weninger (max.weninger@windriver.com) - Bug 72936 [Viewers] Show line numbers in comparision
+ *     Stefan Dirix (sdirix@eclipsesource.com) - Bug 473847: Minimum E4 Compatibility of Compare
  *******************************************************************************/
 package org.eclipse.compare.internal;
 
@@ -1040,7 +1041,7 @@
 	}
 
 	private IOperationHistory getHistory() {
-		if (PlatformUI.getWorkbench() == null) {
+		if (!PlatformUI.isWorkbenchRunning()) {
 			return null;
 		}
 		return PlatformUI.getWorkbench().getOperationSupport()
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/ResizableDialog.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/ResizableDialog.java
index d1e65e4..4ee2b92 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/ResizableDialog.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/ResizableDialog.java
@@ -61,7 +61,7 @@
 	@Override
 	protected void configureShell(Shell newShell) {
 		super.configureShell(newShell);
-		if (fContextId != null)
+		if (fContextId != null && PlatformUI.isWorkbenchRunning())
 			PlatformUI.getWorkbench().getHelpSystem().setHelp(newShell, fContextId);
 	}
 
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/Utilities.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/Utilities.java
index 2f2bc3b..78d22a8 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/Utilities.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/Utilities.java
@@ -1,8 +1,14 @@
 /*******************************************************************************
+<<<<<<< HEAD
  * Copyright (c) 2000, 2017 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
+=======
+ * Copyright (c) 2000, 2016 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+>>>>>>> Bug 473847 - Support DialogCompare for pure E4 applications
  * which accompanies this distribution, and is available at
  * https://www.eclipse.org/legal/epl-2.0/
  *
@@ -10,6 +16,7 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Stefan Dirix (sdirix@eclipsesource.com) - Bug 473847: Minimum E4 Compatibility of Compare
  *******************************************************************************/
 package org.eclipse.compare.internal;
 
@@ -60,6 +67,7 @@
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.ListenerList;
 import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.core.runtime.OperationCanceledException;
 import org.eclipse.core.runtime.Path;
 import org.eclipse.core.runtime.SafeRunner;
@@ -69,6 +77,7 @@
 import org.eclipse.jface.action.IAction;
 import org.eclipse.jface.dialogs.ErrorDialog;
 import org.eclipse.jface.operation.IRunnableContext;
+import org.eclipse.jface.operation.IRunnableWithProgress;
 import org.eclipse.jface.resource.ImageDescriptor;
 import org.eclipse.jface.text.IDocument;
 import org.eclipse.jface.text.IRegion;
@@ -77,9 +86,13 @@
 import org.eclipse.jface.viewers.ISelection;
 import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Item;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.swt.widgets.Widget;
 import org.eclipse.ui.IActionBars;
@@ -88,6 +101,7 @@
 import org.eclipse.ui.IWorkbenchPart;
 import org.eclipse.ui.IWorkbenchPartSite;
 import org.eclipse.ui.IWorkbenchSite;
+import org.eclipse.ui.PlatformUI;
 import org.eclipse.ui.progress.IWorkbenchSiteProgressService;
 import org.eclipse.ui.texteditor.IDocumentProvider;
 
@@ -911,4 +925,64 @@
 		}
 		return buffer.toString();
 	}
+
+	/**
+	 * Executes the given runnable. Uses the {@link org.eclipse.ui.progress.IProgressService IProgressService}
+	 * if available.
+	 *
+	 * @param runnable
+	 *            The {@link IRunnableWithProgress} to execute.
+	 * @throws InvocationTargetException
+	 * @throws InterruptedException
+	 */
+	public static void executeRunnable(IRunnableWithProgress runnable) throws InvocationTargetException,
+			InterruptedException {
+		executeRunnable(runnable, true, true);
+	}
+
+	/**
+	 * Executes the given runnable. Uses the {@link org.eclipse.ui.progress.IProgressService IProgressService}
+	 * if available.
+	 *
+	 * @param runnable
+	 *            The {@link IRunnableWithProgress} to execute.
+	 * @param fork indicates whether to run within a separate thread.
+	 * @param cancelable indicates whether the operation shall be cancelable
+	 * @throws InvocationTargetException
+	 * @throws InterruptedException
+	 */
+	public static void executeRunnable(IRunnableWithProgress runnable, boolean fork, boolean cancelable) throws InvocationTargetException,
+			InterruptedException {
+		if (PlatformUI.isWorkbenchRunning()) {
+			PlatformUI.getWorkbench().getProgressService().run(fork, cancelable, runnable);
+		} else {
+			runnable.run(new NullProgressMonitor());
+		}
+	}
+
+	/**
+	 * Sets the menu image for the given {@link Item}. Uses the workbench shared image if available, otherwise
+	 * creates a new image and adds a dispose listener.
+	 *
+	 * @param item
+	 *            The {@link Item} for which the menu image is to be set.
+	 */
+	public static void setMenuImage(final Item item) {
+		final Image image;
+		if (PlatformUI.isWorkbenchRunning()) {
+			image = PlatformUI.getWorkbench().getSharedImages().getImage(
+			/* IWorkbenchGraphicConstants */"IMG_LCL_VIEW_MENU"); //$NON-NLS-1$
+		} else {
+			image = CompareUIPlugin.getImageDescriptor("elcl16/view_menu.png").createImage(); //$NON-NLS-1$
+			item.addDisposeListener(new DisposeListener() {
+				public void widgetDisposed(DisposeEvent e) {
+					Image img = item.getImage();
+					if ((img != null) && (!img.isDisposed())) {
+						img.dispose();
+					}
+				}
+			});
+		}
+		item.setImage(image);
+	}
 }
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/merge/DocumentMerger.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/merge/DocumentMerger.java
index e7d4726..1398708 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/merge/DocumentMerger.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/merge/DocumentMerger.java
@@ -48,8 +48,6 @@
 import org.eclipse.jface.text.TextUtilities;
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.graphics.Point;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.progress.IProgressService;
 
 /**
  * A document merger manages the differences between two documents
@@ -574,11 +572,10 @@
 			}
 			monitor.done();
 		};
-		IProgressService progressService= PlatformUI.getWorkbench().getProgressService();
 
 		RangeDifference[] e= null;
 		try {
-			progressService.run(true, true, runnable);
+			Utilities.executeRunnable(runnable);
 			e= (RangeDifference[]) result[0];
 		} catch (InvocationTargetException ex) {
 			throw new CoreException(new Status(IStatus.ERROR, CompareUIPlugin.PLUGIN_ID, 0, CompareMessages.DocumentMerger_3, ex.getTargetException()));
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/InputPatchPage.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/InputPatchPage.java
index 1d1cf74..9d95f68 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/InputPatchPage.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/InputPatchPage.java
@@ -181,7 +181,10 @@
 		shell.addShellListener(fActivationListener);
 
 		Dialog.applyDialogFont(composite);
-		PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, ICompareContextIds.PATCH_INPUT_WIZARD_PAGE);
+
+		if(PlatformUI.isWorkbenchRunning()) {
+			PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, ICompareContextIds.PATCH_INPUT_WIZARD_PAGE);
+		}
 	}
 
 	/**
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchTargetPage.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchTargetPage.java
index 2c0e878..7bd7b4d 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchTargetPage.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchTargetPage.java
@@ -88,7 +88,9 @@
 		updateWidgetEnablements();
 
 		Dialog.applyDialogFont(composite);
-		PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, ICompareContextIds.PATCH_INPUT_WIZARD_PAGE);
+		if (PlatformUI.isWorkbenchRunning()) {
+			PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, ICompareContextIds.PATCH_INPUT_WIZARD_PAGE);
+		}
 
 		useWorkspaceAsTarget.addListener(SWT.Selection, event -> {
 			fShowError = true;
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PreviewPatchPage2.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PreviewPatchPage2.java
index b3a969c..54797a8 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PreviewPatchPage2.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PreviewPatchPage2.java
@@ -58,7 +58,6 @@
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.swt.widgets.Text;
-import org.eclipse.ui.PlatformUI;
 import org.eclipse.ui.forms.events.ExpansionAdapter;
 import org.eclipse.ui.forms.events.ExpansionEvent;
 import org.eclipse.ui.forms.widgets.ExpandableComposite;
@@ -651,9 +650,8 @@
 	private int guessFuzzFactor(final WorkspacePatcher patcher) {
 		final int[] result= new int[] { -1 };
 		try {
-			PlatformUI.getWorkbench().getProgressService().run(true, true,
-					monitor -> result[0]= patcher.guessFuzzFactor(monitor)
-			);
+			org.eclipse.compare.internal.Utilities
+					.executeRunnable(monitor -> result[0] = patcher.guessFuzzFactor(monitor));
 		} catch (InvocationTargetException | InterruptedException ex) {
 			// NeedWork
 		}
diff --git a/bundles/org.eclipse.compare/icons/full/elcl16/view_menu.png b/bundles/org.eclipse.compare/icons/full/elcl16/view_menu.png
new file mode 100644
index 0000000..d8dc2f8
--- /dev/null
+++ b/bundles/org.eclipse.compare/icons/full/elcl16/view_menu.png
Binary files differ
diff --git a/bundles/org.eclipse.compare/icons/full/elcl16/view_menu@2x.png b/bundles/org.eclipse.compare/icons/full/elcl16/view_menu@2x.png
new file mode 100644
index 0000000..0774bdf
--- /dev/null
+++ b/bundles/org.eclipse.compare/icons/full/elcl16/view_menu@2x.png
Binary files differ