// $codepro.audit.disable com.instantiations.assist.eclipse.analysis.audit.rule.effectivejava.alwaysOverridetoString.alwaysOverrideToString, com.instantiations.assist.eclipse.analysis.deserializeabilitySecurity, com.instantiations.assist.eclipse.analysis.disallowReturnMutable, com.instantiations.assist.eclipse.analysis.enforceCloneableUsageSecurity
/*******************************************************************************
 * Copyright (c) 2012 Ericsson AB and others.
 * 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
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Ericsson AB - initial API and implementation
 *******************************************************************************/

package org.eclipse.mylyn.reviews.r4e.ui.internal.utils;

import java.io.File;
import java.lang.reflect.Field;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.StringTokenizer;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.ReentrantLock;

import org.eclipse.compare.ICompareNavigator;
import org.eclipse.compare.contentmergeviewer.TextMergeViewer;
import org.eclipse.compare.internal.CompareContentViewerSwitchingPane;
import org.eclipse.compare.internal.CompareEditorInputNavigator;
import org.eclipse.compare.internal.MergeSourceViewer;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferenceConverter;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.text.ITextOperationTarget;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.window.Window;
import org.eclipse.mylyn.reviews.frame.ui.annotation.IReviewAnnotationSupport;
import org.eclipse.mylyn.reviews.notifications.core.IMeetingData;
import org.eclipse.mylyn.reviews.r4e.core.model.R4EAnomalyState;
import org.eclipse.mylyn.reviews.r4e.core.model.R4EFileVersion;
import org.eclipse.mylyn.reviews.r4e.core.model.R4EFormalReview;
import org.eclipse.mylyn.reviews.r4e.core.model.R4EParticipant;
import org.eclipse.mylyn.reviews.r4e.core.model.R4EReviewPhase;
import org.eclipse.mylyn.reviews.r4e.core.model.drules.R4EDesignRuleClass;
import org.eclipse.mylyn.reviews.r4e.core.model.drules.R4EDesignRuleRank;
import org.eclipse.mylyn.reviews.r4e.core.model.serial.impl.CompatibilityException;
import org.eclipse.mylyn.reviews.r4e.core.model.serial.impl.OutOfSyncException;
import org.eclipse.mylyn.reviews.r4e.core.model.serial.impl.ResourceHandlingException;
import org.eclipse.mylyn.reviews.r4e.core.rfs.spi.ReviewsFileStorageException;
import org.eclipse.mylyn.reviews.r4e.ui.R4EUIPlugin;
import org.eclipse.mylyn.reviews.r4e.ui.internal.annotation.control.R4ECompareAnnotationSupport;
import org.eclipse.mylyn.reviews.r4e.ui.internal.annotation.control.R4ESingleAnnotationSupport;
import org.eclipse.mylyn.reviews.r4e.ui.internal.commands.UIElementsProvider;
import org.eclipse.mylyn.reviews.r4e.ui.internal.dialogs.IParticipantInputDialog;
import org.eclipse.mylyn.reviews.r4e.ui.internal.dialogs.IParticipantUnassignDialog;
import org.eclipse.mylyn.reviews.r4e.ui.internal.dialogs.R4EUIDialogFactory;
import org.eclipse.mylyn.reviews.r4e.ui.internal.editors.EditorProxy;
import org.eclipse.mylyn.reviews.r4e.ui.internal.editors.R4ECompareEditorInput;
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.IR4EUIModelElement;
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.IR4EUIPosition;
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.R4EUIAnomalyBasic;
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.R4EUIAnomalyExtended;
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.R4EUIComment;
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.R4EUIContent;
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.R4EUIFileContext;
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.R4EUIModelController;
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.R4EUIPostponedAnomaly;
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.R4EUIReviewBasic;
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.R4EUIReviewExtended;
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.R4EUITextPosition;
import org.eclipse.mylyn.reviews.userSearch.userInfo.IUserInfo;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.browser.IWebBrowser;
import org.eclipse.ui.editors.text.EditorsUI;
import org.eclipse.ui.services.ISourceProviderService;
import org.eclipse.ui.texteditor.AnnotationPreference;
import org.eclipse.ui.texteditor.ITextEditor;

/**
 * This class provides general utility methods used in the UI implementation
 * 
 * @author Sebastien Dubois
 * @version $Revision: 1.0 $
 */
public class UIUtils {

	// ------------------------------------------------------------------------
	// Constants
	// ------------------------------------------------------------------------

	//NOTE:  THese values are used in the hack to change cursor position in compare editor.

	/**
	 * Field COMPARE_EDITOR_TEXT_CLASS_NAME. (value is ""org.eclipse.compare.contentmergeviewer.TextMergeViewer"")
	 */
	private static final String COMPARE_EDITOR_TEXT_CLASS_NAME = "org.eclipse.compare.contentmergeviewer.TextMergeViewer";

	/**
	 * Field COMPARE_EDITOR_TEXT_FIELD_LEFT. (value is ""fLeft"")
	 */
	private static final String COMPARE_EDITOR_TEXT_FIELD_LEFT = "fLeft";

	/**
	 * Field COMPARE_EDITOR_TEXT_FIELD_RIGHT. (value is ""fRight"")
	 */
	private static final String COMPARE_EDITOR_TEXT_FIELD_RIGHT = "fRight";

	/**
	 * Field DEFAULT_OBJECT_CLASS_NAME. (value is ""Object"")
	 */
	private static final String DEFAULT_OBJECT_CLASS_NAME = "Object";

	/**
	 * Field TEST_MODE.
	 */
	//This could be replaced by org.eclipse.mylyn.commons.core.CoreUtil#TEST_MODE,
	//however it's worth repeating as it's a small piece of code
	public static final boolean TEST_MODE;
	static {
		final String application = System.getProperty("eclipse.application", ""); //$NON-NLS-1$ //$NON-NLS-2$
		if (application.length() > 0) {
			TEST_MODE = application.endsWith("testapplication") || application.endsWith("uitest"); //$NON-NLS-1$ //$NON-NLS-2$
		} else {
			final String commands = System.getProperty("eclipse.commands", ""); //$NON-NLS-1$ //$NON-NLS-2$
			TEST_MODE = commands.contains("testapplication\n"); //$NON-NLS-1$
		}
		//Do not show Error Dialogs when doing automated testing
		if (TEST_MODE) {
			ErrorDialog.AUTOMATED_MODE = true;
		} else {
			ErrorDialog.AUTOMATED_MODE = false;
		}
	}

	/**
	 * Field COMPATIBILITY_ERROR_MESSAGE. (value is ""Cannot use older version of R4E to open newer element version"")
	 */
	private static final String COMPATIBILITY_ERROR_MESSAGE = "Cannot use older version of R4E to open newer element version";

	/**
	 * Field COMPATIBILITY_WARNING_DIALOG_TITLE. (value is ""Version Mismatch Detected"")
	 */
	private static final String COMPATIBILITY_WARNING_DIALOG_TITLE = "Version Mismatch Detected";

	/**
	 * Field COMPATIBILITY_WARNING_MESSAGE. (value is ""You are trying to open an older version of the element than the
	 * one currently handled by this version of R4E.\n You can open the element normally, which will upgrade its version
	 * to the current one, or in Read-only mode, which will preserve its version.\n"")
	 */
	private static final String COMPATIBILITY_WARNING_MESSAGE = "You are trying to open an older version of the element than the one currently handled by this version of R4E."
			+ R4EUIConstants.LINE_FEED
			+ "You can open the element normally, which will convert its version to the current application meta-data, or in Read-only mode, which will preserve its version.";

	/**
	 * Field COMPATIBILITY_WARNING_DIALOG_BUTTONS.
	 */
	private static final String[] COMPATIBILITY_WARNING_DIALOG_BUTTONS = { "Open (Convert Version)",
			"Open in Read-Only Mode (Preserve Version)", "Cancel" };

	/**
	 * Field MEETING_DATA_MISMATCH_DIALOG_TITLE. (value is ""Meeting Data Mismatch Detected"")
	 */
	private static final String MEETING_DATA_MISMATCH_DIALOG_TITLE = "Meeting Data Mismatch Detected";

	/**
	 * Field MEETING_DATA_MISMATCH_MESSAGE. (value is ""R4E Meeting Data is different than the Remote Mail Server
	 * Meeting Data .\n Which one should we keep?"")
	 */
	private static final String MEETING_DATA_MISMATCH_MESSAGE = "R4E Meeting Data is different than the Remote Mail Server Meeting Data."
			+ R4EUIConstants.LINE_FEED + "Which one should we keep?";

	/**
	 * Field MEETING_DATA_MISMATCH_DIALOG_BUTTONS.
	 */
	private static final String[] MEETING_DATA_MISMATCH_DIALOG_BUTTONS = { "Use Local data", "Use Remote Data",
			"Cancel" };

	/**
	 * Field DISABLED_FONT_COLOR.
	 */
	public static final Color DISABLED_FONT_COLOR = Display.getCurrent().getSystemColor(SWT.COLOR_DARK_GRAY);

	/**
	 * Field ENABLED_FONT_COLOR.
	 */
	public static final Color ENABLED_FONT_COLOR = Display.getCurrent().getSystemColor(SWT.COLOR_BLACK);

	/**
	 * Field SINGLE_KEY_ANNOTATION_SUPPORT. (value is ""singleEditorAnnotationSupport"")
	 */
	private static final String SINGLE_KEY_ANNOTATION_SUPPORT = "singleEditorAnnotationSupport";

	/**
	 * Field COMPARE_KEY_ANNOTATION_SUPPORT. (value is ""compareEditorAnnotationSupport"")
	 */
	private static final String COMPARE_KEY_ANNOTATION_SUPPORT = "compareEditorAnnotationSupport";

	// ------------------------------------------------------------------------
	// Members
	// ------------------------------------------------------------------------

	/**
	 * Field fLock.
	 */
	private final static ReentrantLock fLock = new ReentrantLock();

	// ------------------------------------------------------------------------
	// Methods
	// ------------------------------------------------------------------------

	/**
	 * Get the current image and add it to the image registry if necessary
	 * 
	 * @param aUrl
	 *            - the location of the image to load
	 * @return Image
	 */
	public static Image loadIcon(String aUrl) {
		final R4EUIPlugin plugin = R4EUIPlugin.getDefault();
		//Need to lock since this can be called in multiple jobs for 
		//the same icon. i.e. create multiple participants
		fLock.lock();
		Image icon = plugin.getImageRegistry().get(aUrl);
		try {
			if (null == icon) {
				final URL imageURL = plugin.getBundle().getEntry(aUrl);
				final ImageDescriptor descriptor = ImageDescriptor.createFromURL(imageURL);
				icon = descriptor.createImage();
				plugin.getImageRegistry().put(aUrl, icon);
			}
		} finally {
			fLock.unlock();
		}

		return icon;
	}

	/**
	 * Get a disabled version of the current image and add it to the image registry if necessary
	 * 
	 * @param aUrl
	 *            - the location of the original image
	 * @return Image
	 */
	public static Image loadDisabledIcon(final String aUrl) {
		final R4EUIPlugin plugin = R4EUIPlugin.getDefault();
		fLock.lock();
		Image icon = plugin.getImageRegistry().get(aUrl + "_disabled");
		try {
			if (null == icon) {
				final URL imageURL = plugin.getBundle().getEntry(aUrl);
				final ImageDescriptor originalDescriptor = ImageDescriptor.createFromURL(imageURL);
				final ImageDescriptor disabledDescriptor = ImageDescriptor.createWithFlags(originalDescriptor,
						SWT.IMAGE_DISABLE);
				//NOTE:  Here we block while creating the new Image because we need to return it from this method
				Display.getDefault().syncExec(new Runnable() {
					public void run() {
						final Image newIcon = disabledDescriptor.createImage();
						plugin.getImageRegistry().put(aUrl + "_disabled", newIcon);
					}
				});
			}
		} finally {
			fLock.unlock();
		}
		return icon;
	}

	/**
	 * Method displayResourceErrorDialog.
	 * 
	 * @param e
	 *            ResourceHandlingException
	 */
	public static void displayResourceErrorDialog(ResourceHandlingException e) {
		R4EUIPlugin.Ftracer.traceError("Exception: " + e.toString() + " (" + e.getMessage() + ")");
		R4EUIPlugin.getDefault().logError("Exception: " + e.toString(), e);
		final ErrorDialog dialog = new ErrorDialog(null, R4EUIConstants.DIALOG_TITLE_ERROR, "Resource Error Detected",
				new Status(IStatus.ERROR, R4EUIPlugin.PLUGIN_ID, 0, e.getMessage(), e), IStatus.ERROR);
		Display.getDefault().syncExec(new Runnable() {
			public void run() {
				dialog.open();
			}
		});
	}

	/**
	 * Method displayCompatibilityErrorDialog.
	 * 
	 * @param e
	 *            CompatibilityException
	 */
	public static void displayCompatibilityErrorDialog(CompatibilityException e) {
		R4EUIPlugin.Ftracer.traceError("Exception: " + e.toString() + " (" + e.getMessage() + ")");
		R4EUIPlugin.getDefault().logError("Exception: " + e.toString(), e);
		final ErrorDialog dialog = new ErrorDialog(null, R4EUIConstants.DIALOG_TITLE_ERROR,
				"Compatibility problem Detected",
				new Status(IStatus.ERROR, R4EUIPlugin.PLUGIN_ID, 0, e.getMessage(), e), IStatus.ERROR);
		Display.getDefault().syncExec(new Runnable() {
			public void run() {
				dialog.open();
			}
		});
	}

	/**
	 * Method displayCompatibilityErrorDialog.
	 */
	public static void displayCompatibilityErrorDialog() {
		R4EUIPlugin.Ftracer.traceError(COMPATIBILITY_ERROR_MESSAGE);
		final ErrorDialog dialog = new ErrorDialog(null, R4EUIConstants.DIALOG_TITLE_ERROR,
				"Compatibility problem Detected", new Status(IStatus.ERROR, R4EUIPlugin.PLUGIN_ID, 0,
						COMPATIBILITY_ERROR_MESSAGE, null), IStatus.ERROR);
		Display.getDefault().syncExec(new Runnable() {
			public void run() {
				dialog.open();
			}
		});
	}

	/**
	 * Method displayCompatibilityWarningDialog.
	 * 
	 * @param aDataVersion
	 *            String
	 * @param aApplVersionl
	 *            String
	 * @return int
	 */
	public static int displayCompatibilityWarningDialog(final String aDataVersion, final String aApplVersionl) {
		R4EUIPlugin.Ftracer.traceWarning(COMPATIBILITY_WARNING_MESSAGE);
		final int[] result = new int[1]; //We need this to be able to pass the result value outside.  This is safe as we are using SyncExec
		Display.getDefault().syncExec(new Runnable() {
			public void run() {
				final MessageDialog dialog = new MessageDialog(null, COMPATIBILITY_WARNING_DIALOG_TITLE, null,
						COMPATIBILITY_WARNING_MESSAGE + R4EUIConstants.LINE_FEED + "Element meta-data Version: "
								+ aDataVersion + R4EUIConstants.LINE_FEED + "Application meta-data Version: "
								+ aApplVersionl, MessageDialog.QUESTION_WITH_CANCEL,
						COMPATIBILITY_WARNING_DIALOG_BUTTONS, 0);
				result[0] = dialog.open();
			}
		});
		return result[0];
	}

	/**
	 * Method displaySyncErrorDialog.
	 * 
	 * @param e
	 *            OutOfSyncException
	 */
	public static void displaySyncErrorDialog(OutOfSyncException e) {
		R4EUIPlugin.Ftracer.traceWarning("Exception: " + e.toString() + " (" + e.getMessage() + ")");
		final ErrorDialog dialog = new ErrorDialog(
				null,
				R4EUIConstants.DIALOG_TITLE_ERROR,
				"Synchronization Error Detected" + "Please refresh the review navigator view and try the command again",
				new Status(IStatus.ERROR, R4EUIPlugin.PLUGIN_ID, 0, e.getMessage(), e), IStatus.ERROR);
		Display.getDefault().syncExec(new Runnable() {
			public void run() {
				dialog.open();
			}
		});
		// TODO later we will want to do this automatically
	}

	/**
	 * Method displayVersionErrorDialog.
	 * 
	 * @param e
	 */
	public static void displayReviewsFileStorageErrorDialog(ReviewsFileStorageException e) {
		R4EUIPlugin.Ftracer.traceError("Exception: " + e.toString() + " (" + e.getMessage() + ")");
		R4EUIPlugin.getDefault().logError("Exception: " + e.toString(), e);
		final ErrorDialog dialog = new ErrorDialog(null, R4EUIConstants.DIALOG_TITLE_ERROR,
				"Local Review Storage Error Detected", new Status(IStatus.ERROR, R4EUIPlugin.PLUGIN_ID, 0,
						e.getMessage(), e), IStatus.ERROR);
		Display.getDefault().syncExec(new Runnable() {
			public void run() {
				dialog.open();
			}
		});
	}

	/**
	 * Method displayCoreErrorDialog.
	 * 
	 * @param e
	 *            CoreException
	 */
	public static void displayCoreErrorDialog(CoreException e) {
		displayCoreErrorDialog(e, true);
	}

	/**
	 * Method displayCoreErrorDialog.
	 * 
	 * @param aEx
	 *            CoreException
	 * @param aBol
	 *            Boolean : To log the error in the error log
	 */
	public static void displayCoreErrorDialog(CoreException aEx, Boolean aBol) {
		if (aBol) {
			R4EUIPlugin.Ftracer.traceError("Exception: " + aEx.toString() + " (" + aEx.getMessage() + ")"); //$NON-NLS-2$//$NON-NLS-3$
			R4EUIPlugin.getDefault().logError("Exception: " + aEx.toString(), aEx);
		}
		final ErrorDialog dialog = new ErrorDialog(null, R4EUIConstants.DIALOG_TITLE_ERROR,
				"Eclipse Runtime Core Error Detected", new Status(IStatus.ERROR, R4EUIPlugin.PLUGIN_ID, 0,
						aEx.getMessage(), aEx), IStatus.ERROR);
		Display.getDefault().syncExec(new Runnable() {
			public void run() {
				dialog.open();
			}
		});
	}

	/**
	 * Method displayFailedLoadDialog.
	 * 
	 * @param aLoadErrors
	 *            List<String>
	 */
	public static void displayFailedLoadDialog(List<String> aLoadErrors) {
		final StringBuilder errorMsgs = new StringBuilder();
		errorMsgs.append("The following errors were reported:" + R4EUIConstants.LINE_FEED);
		for (String msg : aLoadErrors) {
			errorMsgs.append(msg);
		}
		final ErrorDialog dialog = new ErrorDialog(null, R4EUIConstants.DIALOG_TITLE_ERROR,
				"Some elements failed to load", new Status(IStatus.ERROR, R4EUIPlugin.PLUGIN_ID, 0,
						errorMsgs.toString(), null), IStatus.ERROR);
		Display.getDefault().syncExec(new Runnable() {
			public void run() {
				dialog.open();
			}
		});
	}

	/**
	 * Method displayMeetingDataMismatchDialog.
	 * 
	 * @param aLocalData
	 *            IMeetingData
	 * @param aRemoteData
	 *            IMeetingData
	 * @return int
	 */
	public static int displayMeetingDataMismatchDialog(final IMeetingData aLocalData, final IMeetingData aRemoteData) {
		R4EUIPlugin.Ftracer.traceWarning(MEETING_DATA_MISMATCH_MESSAGE);
		final int[] result = new int[1]; //We need this to be able to pass the result value outside.  This is safe as we are using SyncExec
		Display.getDefault().syncExec(new Runnable() {
			public void run() {
				final SimpleDateFormat dueDateFormat = new SimpleDateFormat(R4EUIConstants.SIMPLE_DATE_FORMAT_MINUTES);
				String localStartTime = dueDateFormat.format(new Date(aLocalData.getStartTime()));
				String remoteStartTime = "";
				String remoteLocation = "";
				String remoteDuration = "";
				if (null != aRemoteData) {
					remoteStartTime = dueDateFormat.format(new Date(aRemoteData.getStartTime()));
					remoteLocation = aRemoteData.getLocation();
					remoteDuration = aRemoteData.getDuration().toString();
				}
				final MessageDialog dialog = new MessageDialog(null, MEETING_DATA_MISMATCH_DIALOG_TITLE, null,
						MEETING_DATA_MISMATCH_MESSAGE + R4EUIConstants.LINE_FEED + R4EUIConstants.LINE_FEED
								+ "Local Data:" + R4EUIConstants.LINE_FEED + R4EUIConstants.TAB_FEED + "Start time = "
								+ localStartTime + R4EUIConstants.LINE_FEED + R4EUIConstants.TAB_FEED + "Duration = "
								+ aLocalData.getDuration() + R4EUIConstants.LINE_FEED + R4EUIConstants.TAB_FEED
								+ "Location = " + aLocalData.getLocation() + R4EUIConstants.LINE_FEED + "Remote Data:"
								+ R4EUIConstants.LINE_FEED + R4EUIConstants.TAB_FEED + "Start time = "
								+ remoteStartTime + R4EUIConstants.LINE_FEED + R4EUIConstants.TAB_FEED + "Duration = "
								+ remoteDuration + R4EUIConstants.LINE_FEED + R4EUIConstants.TAB_FEED + "Location = "
								+ remoteLocation, MessageDialog.QUESTION_WITH_CANCEL,
						MEETING_DATA_MISMATCH_DIALOG_BUTTONS, 0);
				result[0] = dialog.open();
			}
		});
		return result[0];
	}

	/**
	 * Method displayPastDateError.
	 * 
	 * @param aPastDate
	 *            Date
	 * @param aPastDateStr
	 *            String
	 * @return boolean
	 */
	public static void displayPastDateError(Date aPastDate, String aPastDateStr) {
		final ErrorDialog dialog = new ErrorDialog(null, R4EUIConstants.DIALOG_TITLE_ERROR,
				"Date Passed Error Detected", new Status(IStatus.ERROR, R4EUIPlugin.PLUGIN_ID, 0,
						"You cannot specify a date (" + aPastDateStr + ") that occured in the past", null),
				IStatus.ERROR);
		Display.getDefault().syncExec(new Runnable() {
			public void run() {
				dialog.open();
			}
		});
	}

	/**
	 * Method isFilterPreferenceSet.
	 * 
	 * @param aFilterSet
	 *            Object
	 * @return boolean
	 */
	public static boolean isFilterPreferenceSet(Object aFilterSet) {
		if (null != aFilterSet && aFilterSet.toString().equals(R4EUIConstants.VALUE_TRUE_STR)) {
			return true;
		}
		return false;
	}

	/**
	 * Method parseStringList.
	 * 
	 * @param aStringList
	 *            String
	 * @return List<String>
	 */
	public static List<String> parseStringList(String aStringList) {
		final List<String> stringArray = new ArrayList<String>();
		if (null != aStringList) {
			final StringTokenizer st = new StringTokenizer(aStringList, File.pathSeparator + R4EUIConstants.LINE_FEED);
			while (st.hasMoreElements()) {
				stringArray.add((String) st.nextElement());
			}
		}
		return stringArray;
	}

	/**
	 * Method addTabbedPropertiesTextResizeListener. Resizes a Text widget in a ScrolledComposite to fit the text being
	 * typed. It also adds scrollbars to the composite as needed
	 * 
	 * @param aText
	 *            Text - The Text widget
	 */
	//TODO this only works for flatFormComposites and not vanilla ones.  For now this is not a big deal, but we will want to review it later
	//A new auto-resizable text widget class should be created for this eventually
	public static void addTabbedPropertiesTextResizeListener(final Text aText) {
		aText.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				//compute new Text field size
				final Point newSize = aText.computeSize(SWT.DEFAULT, SWT.DEFAULT);
				final Point oldSize = aText.getSize();
				final int heightDiff = newSize.y - oldSize.y;
				if (0 != heightDiff && 0 != oldSize.y) {
					aText.setSize(newSize);
					aText.getParent().layout();

					//Set scrollable height so that scrollbar appear if needed
					Composite scrolledParent = aText.getParent();
					while (!(scrolledParent instanceof ScrolledComposite)) {
						scrolledParent = scrolledParent.getParent();
						if (null == scrolledParent) {
							return;
						}
					}
					((ScrolledComposite) scrolledParent).setMinSize(aText.getParent().computeSize(SWT.DEFAULT,
							SWT.DEFAULT));

					//If the text falls outside of the display scroll down to reposition
					if ((aText.getLocation().y + aText.getCaretLocation().y + aText.getLineHeight()) > (scrolledParent.getClientArea().y + scrolledParent.getClientArea().height)) {

						final Point origin = ((ScrolledComposite) scrolledParent).getOrigin();
						origin.y += heightDiff;

						((ScrolledComposite) scrolledParent).setOrigin(origin);
					}
				}
			}
		});
	}

	/**
	 * Method mapParticipantToIndex.
	 * 
	 * @param aParticipant
	 *            String
	 * @return int
	 */
	public static int mapParticipantToIndex(String aParticipant) {
		if (null == R4EUIModelController.getActiveReview()) {
			return 0;
		}
		final List<R4EParticipant> participants = R4EUIModelController.getActiveReview().getParticipants(false);
		final int numParticipants = participants.size();
		int index = 0;
		for (int i = 0; i < numParticipants; i++) {
			if (participants.get(i).isEnabled()) {

				if (participants.get(i).getId().equals(aParticipant)) {
					return index;
				}
				index++;
			} else {
				//Participant is disable, so do not consider the index since it does not show
			}
		}
		return R4EUIConstants.INVALID_VALUE; //Will happen for the disable participants
	}

	/**
	 * Method getClassFromString.
	 * 
	 * @param aClass
	 *            String
	 * @return R4ECommentClass
	 */
	public static R4EDesignRuleClass getClassFromString(String aClass) {
		if (aClass.equals(R4EUIConstants.ANOMALY_CLASS_ERRONEOUS)) {
			return R4EDesignRuleClass.ERRONEOUS;
		} else if (aClass.equals(R4EUIConstants.ANOMALY_CLASS_SUPERFLUOUS)) {
			return R4EDesignRuleClass.SUPERFLUOUS;
		} else if (aClass.equals(R4EUIConstants.ANOMALY_CLASS_IMPROVEMENT)) {
			return R4EDesignRuleClass.IMPROVEMENT;
		} else if (aClass.equals(R4EUIConstants.ANOMALY_CLASS_COMMENT)) {
			return R4EDesignRuleClass.COMMENT;
		} else if (aClass.equals(R4EUIConstants.ANOMALY_CLASS_QUESTION)) {
			return R4EDesignRuleClass.QUESTION;
		} else if (aClass.equals(R4EUIConstants.ANOMALY_CLASS_MISSSING)) {
			return R4EDesignRuleClass.MISSING;
		} else {
			return null; //should never happen
		}
	}

	/**
	 * Method getClassStr.
	 * 
	 * @param aClass
	 *            R4EDesignRuleClass
	 * @return String
	 */
	public static String getClassStr(R4EDesignRuleClass aClass) {
		if (aClass.equals(R4EDesignRuleClass.ERRONEOUS)) {
			return R4EUIConstants.ANOMALY_CLASS_ERRONEOUS;
		} else if (aClass.equals(R4EDesignRuleClass.SUPERFLUOUS)) {
			return R4EUIConstants.ANOMALY_CLASS_SUPERFLUOUS;
		} else if (aClass.equals(R4EDesignRuleClass.IMPROVEMENT)) {
			return R4EUIConstants.ANOMALY_CLASS_IMPROVEMENT;
		} else if (aClass.equals(R4EDesignRuleClass.QUESTION)) {
			return R4EUIConstants.ANOMALY_CLASS_QUESTION;
		} else if (aClass.equals(R4EDesignRuleClass.COMMENT)) {
			return R4EUIConstants.ANOMALY_CLASS_COMMENT;
		} else if (aClass.equals(R4EDesignRuleClass.MISSING)) {
			return R4EUIConstants.ANOMALY_CLASS_MISSSING;
		} else {
			return null; //should never happen
		}
	}

	/**
	 * Method getRankFromString.
	 * 
	 * @param aRank
	 *            String
	 * @return R4EAnomalyRank
	 */
	public static R4EDesignRuleRank getRankFromString(String aRank) {
		if (aRank.equals(R4EUIConstants.ANOMALY_RANK_NONE)) {
			return R4EDesignRuleRank.NONE;
		} else if (aRank.equals(R4EUIConstants.ANOMALY_RANK_MINOR)) {
			return R4EDesignRuleRank.MINOR;
		} else if (aRank.equals(R4EUIConstants.ANOMALY_RANK_MAJOR)) {
			return R4EDesignRuleRank.MAJOR;
		} else {
			return null; //should never happen
		}
	}

	/**
	 * Method getRankStr.
	 * 
	 * @param aRank
	 *            R4EDesignRuleRank
	 * @return String
	 */
	public static String getRankStr(R4EDesignRuleRank aRank) {
		if (aRank.equals(R4EDesignRuleRank.NONE)) {
			return R4EUIConstants.ANOMALY_RANK_NONE;
		} else if (aRank.equals(R4EDesignRuleRank.MINOR)) {
			return R4EUIConstants.ANOMALY_RANK_MINOR;
		} else if (aRank.equals(R4EDesignRuleRank.MAJOR)) {
			return R4EUIConstants.ANOMALY_RANK_MAJOR;
		} else if (aRank.equals(R4EDesignRuleRank.DEPRECATED)) {
			return R4EUIConstants.ANOMALY_RANK_MINOR;
		} else {
			return null; //should never happen
		}
	}

	/**
	 * Method getClasses.
	 * 
	 * @return String[]
	 */
	public static String[] getClasses() {
		return R4EUIConstants.CLASS_VALUES;
	}

	/**
	 * Method getRanks.
	 * 
	 * @return String[]
	 */
	public static String[] getRanks() {
		return R4EUIConstants.RANK_VALUES;
	}

	/**
	 * Method buildUserDetailsString.
	 * 
	 * @param aUserInfo
	 *            IUserInfo
	 * @return String
	 */
	public static String buildUserDetailsString(IUserInfo aUserInfo) {
		final StringBuffer tempStr = new StringBuffer(100);
		final int numAttributeTypes = aUserInfo.getAttributeTypes().length;
		for (int i = 0; i < numAttributeTypes; i++) {
			tempStr.append(aUserInfo.getAttributeTypes()[i] + " = " + aUserInfo.getAttributeValues()[i]
					+ R4EUIConstants.LINE_FEED);
		}
		return tempStr.toString();
	}

	/**
	 * Method selectElementInEditor.
	 * 
	 * @param aInput
	 *            R4ECompareEditorInput
	 * @return boolean
	 */
	public static boolean selectElementInEditor(R4ECompareEditorInput aInput) {

		//For now the Review Navigator View must be open to see the highlighted text in the compare editor
		if (null != R4EUIModelController.getNavigatorView()) {
			final ISelection selection = R4EUIModelController.getNavigatorView().getTreeViewer().getSelection();
			final IR4EUIModelElement element = (IR4EUIModelElement) ((IStructuredSelection) selection).getFirstElement();
			IR4EUIPosition position = null;
			boolean isLeftPane = true;

			if (element instanceof R4EUIAnomalyBasic) {
				position = ((R4EUIAnomalyBasic) element).getPosition();
				if (element instanceof R4EUIPostponedAnomaly) {
					isLeftPane = false; //Use right pane for postponed anomalies
				}
			} else if (element instanceof R4EUIComment) {
				position = ((R4EUIAnomalyBasic) element.getParent()).getPosition();
			} else if (element instanceof R4EUIContent) {
				position = ((R4EUIContent) element).getPosition();
			}

			if (null != position) {
				return selectElementInEditorPane(aInput.getNavigator(), position, isLeftPane);
			}
		}
		return true;
	}

	/**
	 * Method selectElementInEditor.
	 * 
	 * @param aInput
	 *            R4ECompareEditorInput
	 * @return boolean
	 */
	public static boolean selectElementInEditorPane(ICompareNavigator aNavigator, IR4EUIPosition aPosition,
			boolean aIsLeftPane) {

		//Use free form to select position in file
		//NOTE:  This is a dirty hack that involves accessing class and field we shouldn't, but that's
		//       the only way to select the current position in the compare editor.  Hopefully this code can
		//		 be removed later when the Eclipse compare editor allows this.
		if (aNavigator instanceof CompareEditorInputNavigator) {
			final Object[] panes = ((CompareEditorInputNavigator) aNavigator).getPanes();
			for (Object pane : panes) {
				if (pane instanceof CompareContentViewerSwitchingPane) {
					Viewer viewer = ((CompareContentViewerSwitchingPane) pane).getViewer();
					if (viewer instanceof TextMergeViewer) {
						TextMergeViewer textViewer = (TextMergeViewer) viewer;
						Class textViewerClass = textViewer.getClass();
						if (!textViewerClass.getName().equals(COMPARE_EDITOR_TEXT_CLASS_NAME)) {
							do {
								textViewerClass = textViewerClass.getSuperclass();
								if (textViewerClass.getName().equals(DEFAULT_OBJECT_CLASS_NAME)) {
									break;
								}
							} while (!textViewerClass.getName().equals(COMPARE_EDITOR_TEXT_CLASS_NAME));
						}
						try {
							Field field;
							if (aIsLeftPane) {
								field = textViewerClass.getDeclaredField(COMPARE_EDITOR_TEXT_FIELD_LEFT);
							} else {
								field = textViewerClass.getDeclaredField(COMPARE_EDITOR_TEXT_FIELD_RIGHT);
							}
							field.setAccessible(true);
							MergeSourceViewer sourceViewer = (MergeSourceViewer) field.get(textViewer);

							//Now check if the element can be displayed completely in the current viewport.  If so, do it.  Otherwise, tell
							//the caller
							int visibleOffset = sourceViewer.getSourceViewer().getVisibleRegion().getOffset();
							int visibleLength = sourceViewer.getSourceViewer().getVisibleRegion().getLength();
							int elementOffset = ((R4EUITextPosition) aPosition).getOffset();
							int elementLength = ((R4EUITextPosition) aPosition).getLength();

							if (elementOffset < visibleOffset
									|| (elementOffset + elementLength) > (visibleOffset + visibleLength)) {
								return false; //Element falls outside the visible region
							} else {
								ITextEditor adapter = (ITextEditor) sourceViewer.getAdapter(ITextEditor.class);
								adapter.selectAndReveal(((R4EUITextPosition) aPosition).getOffset(),
										((R4EUITextPosition) aPosition).getLength());
							}
						} catch (SecurityException e) {
							//just continue
						} catch (NoSuchFieldException e) {
							//just continue
						} catch (IllegalArgumentException e) {
							//just continue
						} catch (IllegalAccessException e) {
							//just continue
						}
					}
				}
			}
		}
		return true;
	}

	/**
	 * Method openUrl Opens a default web browser
	 * 
	 * @param aLocation
	 *            - String
	 */
	public static void openUrl(String aLocation) {
		URL url = null;
		if (null != aLocation) {
			try {
				url = new URL(aLocation);
			} catch (MalformedURLException e) {
				R4EUIPlugin.Ftracer.traceError("Exception: " + e.toString() + " (" + e.getMessage() + ")");
				R4EUIPlugin.getDefault().logError("Exception: " + e.toString(), e);
				final ErrorDialog dialog = new ErrorDialog(null, R4EUIConstants.DIALOG_TITLE_ERROR, "Invalid location",
						new Status(IStatus.ERROR, R4EUIPlugin.PLUGIN_ID, 0, e.getMessage(), e), IStatus.ERROR);
				Display.getDefault().syncExec(new Runnable() {
					public void run() {
						dialog.open();
					}
				});
			}
		}
		final String generatedId = "org.eclipse.mylyn.web.browser-" + Calendar.getInstance().getTimeInMillis(); //$NON-NLS-1$
		final IWebBrowser browser;
		try {
			browser = PlatformUI.getWorkbench().getBrowserSupport().createBrowser(generatedId);
			browser.openURL(url);
		} catch (PartInitException e) {
			R4EUIPlugin.Ftracer.traceError("Exception: " + e.toString() + " (" + e.getMessage() + ")");
			R4EUIPlugin.getDefault().logError("Exception: " + e.toString(), e);
			final ErrorDialog dialog = new ErrorDialog(null, R4EUIConstants.DIALOG_TITLE_ERROR,
					"Error opening Browser", new Status(IStatus.ERROR, R4EUIPlugin.PLUGIN_ID, 0, e.getMessage(), e),
					IStatus.ERROR);
			Display.getDefault().syncExec(new Runnable() {
				public void run() {
					dialog.open();
				}
			});
		}
	}

	/**
	 * Method changeReviewState Verifies and Changes Review Element phase to a new one
	 * 
	 * @param aReview
	 *            - R4EUIModelElement
	 * @param aNewPhase
	 *            - R4EReviewPhase
	 */
	public static void changeReviewPhase(IR4EUIModelElement aReview, R4EReviewPhase aNewPhase) {
		final AtomicReference<String> aResultMsg = new AtomicReference<String>(null);
		if (((R4EUIReviewBasic) aReview).validatePhaseChange(aNewPhase, aResultMsg)) {
			if (null != aResultMsg.get()) {
				final ErrorDialog dialog = new ErrorDialog(null, "Warning", aResultMsg.get(), new Status(
						IStatus.WARNING, R4EUIPlugin.PLUGIN_ID, 0, null, null), IStatus.WARNING);
				Display.getDefault().syncExec(new Runnable() {
					public void run() {
						dialog.open();
					}
				});
			}
			try {
				if (aReview instanceof R4EUIReviewExtended) {
					final R4EFormalReview review = ((R4EFormalReview) ((R4EUIReviewExtended) aReview).getReview());
					if (aNewPhase.equals(R4EReviewPhase.PREPARATION)
							&& null == review.getActiveMeeting()) {
						Display.getDefault().syncExec(new Runnable() {
							public void run() {
								try {
									MailServicesProxy.sendMeetingRequest();
								} catch (ResourceHandlingException e) {
									displayResourceErrorDialog(e);
								} catch (OutOfSyncException e) {
									displaySyncErrorDialog(e);
								}
							}
						});
					}
					//Prevent changing state to PREPARATION if no Meeting Request was sent out
					if (null != review.getActiveMeeting()) {
						((R4EUIReviewExtended) aReview).updatePhase(aNewPhase);
					} else {
						final ErrorDialog dialog = new ErrorDialog(null, "Error", "No Meeting Data present",
								new Status(IStatus.ERROR, R4EUIPlugin.PLUGIN_ID, 0,
										"Please allow sending out a Meeting Request", null), IStatus.ERROR);
						Display.getDefault().syncExec(new Runnable() {
							public void run() {
								dialog.open();
							}
						});
					}
				} else {
					((R4EUIReviewBasic) aReview).updatePhase(aNewPhase);
				}
			} catch (ResourceHandlingException e1) {
				UIUtils.displayResourceErrorDialog(e1);
			} catch (OutOfSyncException e1) {
				UIUtils.displaySyncErrorDialog(e1);
			}
		} else {
			final ErrorDialog dialog = new ErrorDialog(null, R4EUIConstants.REVIEW_NOT_COMPLETED_ERROR,
					"Review phase cannot be changed", new Status(IStatus.ERROR, R4EUIPlugin.PLUGIN_ID, 0,
							aResultMsg.get(), null), IStatus.ERROR);
			Display.getDefault().syncExec(new Runnable() {
				public void run() {
					dialog.open();
				}
			});
		}
	}

	/**
	 * Method changeAnomalyState Verifies and Changes Anomaly Element state to a new one
	 * 
	 * @param aAnomaly
	 *            - IR4EUIModelElement
	 * @param aNewState
	 *            - R4EAnomalyState
	 */
	public static void changeAnomalyState(final IR4EUIModelElement aAnomaly, R4EAnomalyState aNewState) {
		try {
			((R4EUIAnomalyExtended) aAnomaly).updateState(aNewState);

			//If this is a postponed anomaly, update original one as well
			if (aAnomaly instanceof R4EUIPostponedAnomaly) {
				((R4EUIPostponedAnomaly) aAnomaly).updateOriginalAnomaly();
			}

			//Update inline markings (local anomalies only)
			if (aAnomaly.getParent().getParent() instanceof R4EUIFileContext) {
				Display.getDefault().syncExec(new Runnable() {
					public void run() {
						UIUtils.updateAnnotation(aAnomaly, (R4EUIFileContext) aAnomaly.getParent().getParent());
					}
				});
			}
		} catch (ResourceHandlingException e1) {
			UIUtils.displayResourceErrorDialog(e1);
		} catch (OutOfSyncException e1) {
			UIUtils.displaySyncErrorDialog(e1);
		} catch (CompatibilityException e) {
			UIUtils.displayCompatibilityErrorDialog(e);
		}
	}

	/**
	 * Method setNavigatorViewFocus. Set focus to current view/element
	 * 
	 * @param aElement
	 *            R4EUIModelElement
	 * @param aExpandLevel
	 *            int
	 */
	public static void setNavigatorViewFocus(IR4EUIModelElement aElement, int aExpandLevel) {
		if (null != aElement) {
			R4EUIModelController.getNavigatorView().updateView(aElement, aExpandLevel, true);
		}
	}

	/**
	 * Method formatAssignedParticipants. Concatenates assigned participants for UI display
	 * 
	 * @param aParticipants
	 *            List<String>
	 * @return String
	 */
	public static String formatAssignedParticipants(List<String> aParticipants) {
		if (aParticipants.size() > 0) {
			final StringBuffer buffer = new StringBuffer();
			for (String participants : aParticipants) {
				buffer.append(participants + R4EUIConstants.LIST_SEPARATOR + " ");
			}
			return buffer.toString().substring(0, buffer.length() - 2);
		} else {
			return "";
		}
	}

	/**
	 * Display the dialog used by the user to enter the participant to use as filter criteria
	 * 
	 * @return String
	 */
	public static String getParticipantFilterInputDialog() {
		final InputDialog dlg = R4EUIDialogFactory.getInstance().getParticipantFilterInputDialog();
		if (dlg.open() == Window.OK) {
			return dlg.getValue();
		}
		return ""; //$NON-NLS-1$
	}

	/**
	 * Display the dialog used by the user to enter the participant to assign
	 * 
	 * @return String
	 */
	public static List<R4EParticipant> getAssignParticipants() {
		final IParticipantInputDialog dialog = R4EUIDialogFactory.getInstance().getParticipantInputDialog(false);
		final int[] result = new int[1]; //We need this to be able to pass the result value outside.  This is safe as we are using SyncExec
		final List<R4EParticipant> resultParticipants = new ArrayList<R4EParticipant>();
		Display.getDefault().syncExec(new Runnable() {
			public void run() {
				dialog.create();
				result[0] = dialog.open();
				for (R4EParticipant participant : dialog.getParticipants()) {
					resultParticipants.add(participant);
				}
				R4EUIDialogFactory.getInstance().removeParticipantInputDialog();
			}
		});
		if (result[0] == Window.OK) {
			return resultParticipants;
		}
		return new ArrayList<R4EParticipant>(0); //Cancelled, no participants to use
	}

	/**
	 * Display the dialog used by the user to enter the participant unassign
	 * 
	 * @param aElement
	 *            - IR4EUIModelElement
	 * @return String
	 */
	public static List<R4EParticipant> getUnassignParticipants(final IR4EUIModelElement aElement) {
		final IParticipantUnassignDialog dialog = R4EUIDialogFactory.getInstance().getParticipantUnassignDialog(
				aElement);
		final int[] result = new int[1]; //We need this to be able to pass the result value outside.  This is safe as we are using SyncExec
		final List<R4EParticipant> resultParticipants = new ArrayList<R4EParticipant>();
		Display.getDefault().syncExec(new Runnable() {
			public void run() {
				dialog.create();
				result[0] = dialog.open();
				for (R4EParticipant participant : dialog.getParticipants()) {
					resultParticipants.add(participant);
				}
			}
		});
		if (result[0] == Window.OK) {
			return resultParticipants;
		}
		return new ArrayList<R4EParticipant>(0); //Cancelled, no participants to use
	}

	/**
	 * Gets the project path for the given file version
	 * 
	 * @param aFileVersion
	 *            - R4EFileVersion
	 * @return String
	 */
	public static String getProjectPath(R4EFileVersion aFileVersion) {
		String path = ""; //$NON-NLS-1$
		try {
			if (null != aFileVersion.getPlatformURI()) {
				final URI uri = new URI(aFileVersion.getPlatformURI());
				final String uriPath = uri.getPath();
				if (null != uriPath) {
					path = uriPath.substring(uriPath.indexOf(R4EUIConstants.SEPARATOR, 1) + 1);
				}
			}
		} catch (URISyntaxException e) {
			// Ignore
		}
		return path;
	}

	/**
	 * Method formatNumChanges. formats the NumChanges value for UI display
	 * 
	 * @param aNumChanges
	 *            int
	 * @param aNumReviewedChanges
	 *            int
	 * @return String
	 */
	public static String formatNumChanges(int aNumChanges, int aNumReviewedChanges) {
		return Integer.toString(aNumReviewedChanges) + R4EUIConstants.SEPARATOR + Integer.toString(aNumChanges);
	}

	//Inline commenting

	/**
	 * Method refreshAnnotations
	 * 
	 * @param aFile
	 *            - R4EUIFileContext
	 */
	public static void refreshAnnotations(R4EUIFileContext aFile) {
		//Add Annotation marker for inline commenting (if applicable)
		IReviewAnnotationSupport support = getAnnotationSupport(aFile);
		if (null != support) {
			support.refreshAnnotations(aFile);
		}
	}

	/**
	 * Method addAnnotation
	 * 
	 * @param aSource
	 *            - IR4EUIModelElement
	 * @param aFile
	 *            - R4EUIFileContext
	 */
	public static void addAnnotation(final IR4EUIModelElement aSource, R4EUIFileContext aFile) {
		//Add Annotation marker for inline commenting (if applicable)
		IReviewAnnotationSupport support = getAnnotationSupport(aFile);
		if (null != support) {
			support.addAnnotation(aSource);
		}
	}

	/**
	 * Method updateAnnotation
	 * 
	 * @param aSource
	 *            - IR4EUIModelElement
	 * @param aFile
	 *            - R4EUIFileContext
	 */
	public static void updateAnnotation(final IR4EUIModelElement aSource, R4EUIFileContext aFile) {
		//Add Annotation marker for inline commenting (if applicable)
		IReviewAnnotationSupport support = getAnnotationSupport(aFile);
		if (null != support) {
			support.updateAnnotation(aSource);
		}
	}

	/**
	 * Method removeAnnotation
	 * 
	 * @param aSource
	 *            - IR4EUIModelElement
	 * @param aFile
	 *            - R4EUIFileContext
	 */
	public static void removeAnnotation(final IR4EUIModelElement aSource, R4EUIFileContext aFile) {
		//Add Annotation marker for inline commenting (if applicable)
		IReviewAnnotationSupport support = getAnnotationSupport(aFile);
		if (null != support) {
			support.removeAnnotation(aSource);
		}
	}

	/**
	 * Method removeAnnotation
	 * 
	 * @param aFile
	 *            - R4EUIFileContext
	 * @return IReviewAnnotationSupport
	 */
	public static IReviewAnnotationSupport getAnnotationSupport(R4EUIFileContext aFile) {
		IReviewAnnotationSupport support = null;

		//First try to find Compare Editor
		IEditorPart editor = EditorProxy.findReusableCompareEditor(R4EUIModelController.getNavigatorView()
				.getSite()
				.getPage(), aFile.getBaseFileVersion(), aFile.getTargetFileVersion());
		if (null != editor) {
			IEditorInput input = editor.getEditorInput();
			Viewer viewer = ((R4ECompareEditorInput) input).getContentViewer();
			if (null != viewer) {
				support = getCompareAnnotationSupport(viewer, aFile);
			}
		} else {
			//Try to find Single Editor
			editor = EditorProxy.findReusableEditor(R4EUIModelController.getNavigatorView().getSite().getPage(),
					aFile.getTargetFileVersion());
			if (null != editor) {
				ITextOperationTarget target = (ITextOperationTarget) editor.getAdapter(ITextOperationTarget.class);
				if (target instanceof SourceViewer) {
					SourceViewer sourceViewer = (SourceViewer) target;
					support = getSingleAnnotationSupport(sourceViewer, aFile);
				}
			}
		}
		return support;
	}

	/**
	 * Method getSingleAnnotationSupport.
	 * 
	 * @param aSourceViewer
	 *            ISourceViewer
	 * @param aFileContext
	 *            R4EUIFileContext
	 * @return IReviewAnnotationSupport
	 */
	public static IReviewAnnotationSupport getSingleAnnotationSupport(SourceViewer aSourceViewer, Object aFileContext) {
		IReviewAnnotationSupport support = (IReviewAnnotationSupport) aSourceViewer.getData(SINGLE_KEY_ANNOTATION_SUPPORT);
		if (support == null) {
			support = new R4ESingleAnnotationSupport(aSourceViewer, aFileContext);
			aSourceViewer.setData(SINGLE_KEY_ANNOTATION_SUPPORT, support);
		}
		return support;
	}

	/**
	 * Method getCompareAnnotationSupport.
	 * 
	 * @param aSourceViewer
	 *            ISourceViewer
	 * @param aFileContext
	 *            R4EUIFileContext
	 * @return IReviewAnnotationSupport
	 */
	public static IReviewAnnotationSupport getCompareAnnotationSupport(Viewer aViewer, Object aFileContext) {
		IReviewAnnotationSupport support = (IReviewAnnotationSupport) aViewer.getData(COMPARE_KEY_ANNOTATION_SUPPORT);
		if (support == null) {
			support = new R4ECompareAnnotationSupport(aViewer, aFileContext);
			aViewer.setData(COMPARE_KEY_ANNOTATION_SUPPORT, support);
		}
		return support;
	}

	/**
	 * Method removeAnnotation
	 * 
	 * @param aPref
	 *            - AnnotationPreference
	 * @param aStore
	 *            - IPreferenceStore
	 * @return Color
	 */
	public static Color updateAnnotationColor(AnnotationPreference aPref, IPreferenceStore aStore) {
		if (aPref != null) {
			RGB rgb = getColorFromAnnotationPreference(aStore, aPref);
			return EditorsUI.getSharedTextColors().getColor(rgb);
		}
		return null;
	}

	/**
	 * Method removeAnnotation
	 * 
	 * @param aStore
	 *            - IPreferenceStore
	 * @param aPref
	 *            - AnnotationPreference
	 * @return RGB
	 */
	public static RGB getColorFromAnnotationPreference(IPreferenceStore aStore, AnnotationPreference aPref) {
		String key = aPref.getColorPreferenceKey();
		RGB rgb = null;
		if (aStore.contains(key)) {
			if (aStore.isDefault(key)) {
				rgb = aPref.getColorPreferenceValue();
			} else {
				rgb = PreferenceConverter.getColor(aStore, key);
			}
		}
		if (rgb == null) {
			rgb = aPref.getColorPreferenceValue();
		}
		return rgb;
	}

	/**
	 * Method getCommandUIElements
	 * 
	 * @return List<IR4EUIModelElement>
	 */
	public static List<IR4EUIModelElement> getCommandUIElements() {
		UIElementsProvider uiElementProvider = getSourceProvider();
		if (uiElementProvider != null) {
			return uiElementProvider.getSelectedElements();
		}
		//Create an empty list
		List<IR4EUIModelElement> uiElements = new ArrayList<IR4EUIModelElement>(1);
		return uiElements;
	}

	/**
	 * Method setCommandUIElements
	 * 
	 * @param uiElements
	 *            - List<IR4EUIModelElement>
	 */
	public static void setCommandUIElements(List<IR4EUIModelElement> uiElements) {
		UIElementsProvider uiElementProvider = getSourceProvider();
		if (uiElementProvider != null) {
			uiElementProvider.setSelectedElements(uiElements);
		}
	}

	/**
	 * Method getCommandUIElements
	 * 
	 * @return List<IR4EUIModelElement>
	 */
	public static void clearCommandUIElements() {
		UIElementsProvider uiElementProvider = getSourceProvider();
		if (uiElementProvider != null) {
			uiElementProvider.setSelectedElements(null);
		}
	}

	/**
	 * Method getSourceProvider.
	 * 
	 * @return UIElementsProvider
	 */
	private static UIElementsProvider getSourceProvider() {
		IWorkbench workbench = PlatformUI.getWorkbench();
		if (workbench != null) {
			IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
			//Window can be null when exiting
			if (window != null) {
				ISourceProviderService service = (ISourceProviderService) window.getService(ISourceProviderService.class);
				return (UIElementsProvider) service.getSourceProvider(UIElementsProvider.SELECTED_ELEMENTS);
			}

		}
		return null;
	}
}
