// $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.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;

import org.eclipse.compare.ITypedElement;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.util.EList;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.ISourceReference;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.TextSelection;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.mylyn.reviews.notifications.core.IMeetingData;
import org.eclipse.mylyn.reviews.notifications.spi.NotificationsConnector;
import org.eclipse.mylyn.reviews.r4e.core.model.R4EDelta;
import org.eclipse.mylyn.reviews.r4e.core.model.R4EFileContext;
import org.eclipse.mylyn.reviews.r4e.core.model.R4EFileVersion;
import org.eclipse.mylyn.reviews.r4e.core.model.R4EItem;
import org.eclipse.mylyn.reviews.r4e.core.model.R4EMeetingData;
import org.eclipse.mylyn.reviews.r4e.core.model.R4EParticipant;
import org.eclipse.mylyn.reviews.r4e.core.model.R4EReviewComponent;
import org.eclipse.mylyn.reviews.r4e.core.model.R4EReviewType;
import org.eclipse.mylyn.reviews.r4e.core.model.R4ETextPosition;
import org.eclipse.mylyn.reviews.r4e.core.model.R4EUserRole;
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.ui.R4EUIPlugin;
import org.eclipse.mylyn.reviews.r4e.ui.internal.dialogs.R4EUIDialogFactory;
import org.eclipse.mylyn.reviews.r4e.ui.internal.editors.R4ECompareEditorInput;
import org.eclipse.mylyn.reviews.r4e.ui.internal.editors.R4EFileEditorInput;
import org.eclipse.mylyn.reviews.r4e.ui.internal.editors.R4EFileRevisionEditorInput;
import org.eclipse.mylyn.reviews.r4e.ui.internal.editors.R4EFileRevisionTypedElement;
import org.eclipse.mylyn.reviews.r4e.ui.internal.editors.R4EFileTypedElement;
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.IR4EUIModelElement;
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.R4EUIAnomalyBasic;
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.R4EUIReviewItem;
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.R4EUITextPosition;
import org.eclipse.mylyn.reviews.r4e.ui.internal.preferences.PreferenceConstants;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.FileEditorInput;

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

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

	/**
	 * Field LINE_FEED_MSG_PART.
	 */
	private static final String LINE_FEED_MSG_PART = R4EUIConstants.LINE_FEED;

	/**
	 * Field TAB_MSG_PART. (value is ""\t"")
	 */
	private static final String TAB_MSG_PART = "\t";

	/**
	 * Field SUBJECT_MSG_HEADER. (value is "" Review "")
	 */
	private static final String SUBJECT_MSG_HEADER = " Review ";

	/**
	 * Field INTRO_MSG_BODY. (value is ""Hi,"")
	 */
	private static final String INTRO_MSG_BODY = "Hi,";

	/**
	 * Field OUTRO_MSG_BODY. (value is ""Best Regards,"")
	 */
	private static final String OUTRO_MSG_BODY = "Best Regards,";

	/**
	 * Field ITEMS_READY_MSG_BODY. (value is ""The following Review Item(s) and Files are Ready for you to Review"")
	 */
	private static final String ITEMS_READY_MSG_BODY = "The following Review Item(s) and Files are Ready for you to Review";

	/**
	 * Field MEETING_REQUEST_MSG_BODY. (value is ""This invitation is for the decision phase." + LINE_FEED_MSG_PART +
	 * "Please review the included items prior to the meeting."")
	 */
	private static final String MEETING_REQUEST_MSG_BODY = "This invitation is for the decision phase."
			+ LINE_FEED_MSG_PART + "Please review the included items prior to the meeting.";

	/**
	 * Field ADDED_ITEMS_MSG_BODY. (value is ""The following Review Item(s) and Files have been Added." +
	 * LINE_FEED_MSG_PART + "Please Refresh your Review if it is currently Open"")
	 */
	private static final String ADDED_ELEMENTS_MSG_BODY = "The following Review Element(s) have been Added."
			+ LINE_FEED_MSG_PART + "Please Refresh your Review if it is currently Open";

	/**
	 * Field REMOVED_ITEMS_MSG_BODY. (value is ""The following Review Item(s) and Files have been Removed." +
	 * LINE_FEED_MSG_PART + "Please Refresh your Review if it is currently Open"")
	 */
	private static final String REMOVED_ELEMENTS_MSG_BODY = "The following Element(s) have been Removed."
			+ LINE_FEED_MSG_PART + "Please Refresh your Review if it is currently Open";

	/**
	 * Field PROGRESS_MESSAGE. (value is ""Progress Update: " + LINE_FEED_MSG_PART")
	 */
	private static final String PROGRESS_MESSAGE = "Progress Update: " + LINE_FEED_MSG_PART;

	/**
	 * Field COMPLETION_MESSAGE. (value is ""I have Completed this Review, see Details below: " + LINE_FEED_MSG_PART")
	 */
	private static final String COMPLETION_MESSAGE = "I have Completed this Review, see Details below: "
			+ LINE_FEED_MSG_PART;

	/**
	 * Field QUESTION_MSG_BODY. (value is ""I have a Question concerning the Following "")
	 */
	private static final String QUESTION_MSG_BODY = "I have a Question concerning the Following Elements: "
			+ LINE_FEED_MSG_PART + LINE_FEED_MSG_PART;

	/**
	 * Field DEFAULT_MEETING_DURATION. (value is "60")
	 */
	private static final Integer DEFAULT_MEETING_DURATION = new Integer(60);

	/**
	 * Field DECISION_MEETING_UPDATED_MSG. (value is "" - Decision Meeting Request Updated"")
	 */
	private static final String DECISION_MEETING_UPDATED_MSG = " - Decision Meeting Request Updated";

	/**
	 * Field DECISION_MEETING_INITIAL_MSG. (value is "" - Items Ready for Review & Decision Meeting Request"")
	 */
	private static final String DECISION_MEETING_INITIAL_MSG = " - Items Ready for Review & Decision Meeting Request";

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

	//Notifications

	/**
	 * Method sendItemsReadyNotification
	 * 
	 * @throws CoreException
	 * @throws ResourceHandlingException
	 */
	public static void sendItemsReadyNotification() throws CoreException, ResourceHandlingException {
		if (null != R4EUIDialogFactory.getInstance().getMailConnector()) {
			final String[] messageDestinations = createItemsUpdatedDestinations();
			final String messageSubject = createSubject() + " - Items Ready for Review";
			final String messageBody = createItemsReadyNotificationMessage(false);
			sendMessage(messageDestinations, messageSubject, messageBody);
		} else {
			showNoEmailConnectorDialog();
		}
	}

	/**
	 * Method sendItemsAddedNotification
	 * 
	 * @param aAddedElements
	 *            List<R4EReviewComponent>
	 * @throws CoreException
	 * @throws ResourceHandlingException
	 */
	public static void sendItemsAddedNotification(List<R4EReviewComponent> aAddedElements) throws CoreException,
			ResourceHandlingException {
		if (null != R4EUIDialogFactory.getInstance().getMailConnector()) {
			final String[] messageDestinations = createItemsUpdatedDestinations();
			final String messageSubject = createSubject() + " - Items Added for Review";
			final String messageBody = createUpdatedItemsNotificationMessage(aAddedElements, true);
			sendMessage(messageDestinations, messageSubject, messageBody);
		} else {
			showNoEmailConnectorDialog();
		}
	}

	/**
	 * Method sendItemsRemovedNotification
	 * 
	 * @param aRemovedElements
	 *            List<R4EReviewComponent>
	 * @throws CoreException
	 * @throws ResourceHandlingException
	 */
	public static void sendItemsRemovedNotification(List<R4EReviewComponent> aRemovedElements) throws CoreException,
			ResourceHandlingException {
		if (null != R4EUIDialogFactory.getInstance().getMailConnector()) {
			final String[] messageDestinations = createItemsUpdatedDestinations();
			final String messageSubject = createSubject() + " - Items Removed from Review";
			final String messageBody = createUpdatedItemsNotificationMessage(aRemovedElements, false);
			sendMessage(messageDestinations, messageSubject, messageBody);
		} else {
			showNoEmailConnectorDialog();
		}
	}

	/**
	 * Method sendProgressNotification
	 * 
	 * @throws CoreException
	 * @throws ResourceHandlingException
	 */
	public static void sendProgressNotification() throws CoreException, ResourceHandlingException {
		if (null != R4EUIDialogFactory.getInstance().getMailConnector()) {
			final String[] messageDestinations = createProgressDestinations();
			final String messageSubject = createSubject() + " - Participant Progress";
			final String messageBody = createProgressNotification(PROGRESS_MESSAGE);
			sendMessage(messageDestinations, messageSubject, messageBody);
		} else {
			showNoEmailConnectorDialog();
		}
	}

	/**
	 * Method sendCompletionNotification
	 * 
	 * @throws CoreException
	 * @throws ResourceHandlingException
	 */
	public static void sendCompletionNotification() throws CoreException, ResourceHandlingException {
		if (null != R4EUIDialogFactory.getInstance().getMailConnector()) {
			final String[] messageDestinations = createProgressDestinations();
			final String messageSubject = createSubject() + " - Participant Progress (Completed)";
			final String messageBody = createProgressNotification(COMPLETION_MESSAGE);
			sendMessage(messageDestinations, messageSubject, messageBody);
		} else {
			showNoEmailConnectorDialog();
		}
	}

	/**
	 * Method sendQuestion
	 * 
	 * @param aSource
	 *            Object
	 * @throws CoreException
	 * @throws ResourceHandlingException
	 */
	public static void sendQuestion(ISelection aSource) throws CoreException, ResourceHandlingException {
		if (null != R4EUIDialogFactory.getInstance().getMailConnector()) {
			String[] messageDestinations = null;
			messageDestinations = createQuestionDestinations();
			final String messageSubject = createSubject() + " - Question regarding review ";
			final String messageBody = createQuestionMessage(aSource);
			sendMessage(messageDestinations, messageSubject, messageBody);
		} else {
			showNoEmailConnectorDialog();
		}
	}

	/**
	 * Method sendMessage
	 * 
	 * @param aDestinations
	 *            String[]
	 * @param aSubject
	 *            String
	 * @param aBody
	 *            String
	 * @throws CoreException
	 * @throws ResourceHandlingException
	 */
	public static void sendMessage(String[] aDestinations, final String aSubject, final String aBody)
			throws ResourceHandlingException {

		final String originatorEmail = getOriginatorEmail();
		final String[] destinations = adjustDestinationEmails(aDestinations, originatorEmail);

		//Make sure the email is sent in the UI thread
		Display.getDefault().syncExec(new Runnable() {
			public void run() {
				try {
					R4EUIDialogFactory.getInstance()
							.getMailConnector()
							.sendEmailGraphical(originatorEmail, destinations, aSubject, aBody, null, null);
				} catch (CoreException e) {
					UIUtils.displayCoreErrorDialog(e);
				}
			}
		});
	}

	/**
	 * Method getOriginatorEmail
	 * 
	 * @return String
	 * @throws ResourceHandlingException
	 */
	private static String getOriginatorEmail() throws ResourceHandlingException {
		String originatorEmail = null;
		final R4EParticipant user = R4EUIModelController.getActiveReview().getParticipant(
				R4EUIModelController.getReviewer(), false);
		if (null != user) {
			originatorEmail = user.getEmail();
		}

		if (originatorEmail == null || originatorEmail.length() == 0) {
			//if the user's email is null OR Undefined OR
			//If current user is not part of the review, get email from preferences
			final IPreferenceStore store = R4EUIPlugin.getDefault().getPreferenceStore();
			originatorEmail = store.getString(PreferenceConstants.P_USER_EMAIL);
		}
		return originatorEmail;
	}

	/**
	 * Method adjustDestinationEmails (see bug 390102)
	 * 
	 * @param aDestinations
	 *            - String[]
	 * @param aOriginator
	 *            - String
	 * @return String[]
	 * @throws ResourceHandlingException
	 */
	private static String[] adjustDestinationEmails(String[] aDestinations, String aOriginator) {
		List<String> destinations = new ArrayList<String>(Arrays.asList(aDestinations));
		if (aOriginator != null
				&& R4EUIPlugin.getDefault()
						.getPreferenceStore()
						.getBoolean(PreferenceConstants.P_SEND_NOTIFICATION_TO_SENDER)) {
			//Make sure sender is part of the destination list
			if (!destinations.contains(aOriginator)) {
				destinations.add(aOriginator);
			}
		}
		return destinations.toArray(new String[destinations.size()]);
	}

	/**
	 * Method createSubject
	 * 
	 * @return String
	 */
	private static String createSubject() {
		final StringBuilder subject = new StringBuilder();
		subject.append("[r4e-mail] ");
		subject.append(SUBJECT_MSG_HEADER);
		subject.append(R4EUIModelController.getActiveReview().getName());
		return subject.toString();
	}

	/**
	 * Method isEmailValid
	 * 
	 * @param aParticipant
	 *            R4EParticipant
	 * @return boolean
	 */
	private static boolean isEmailValid(R4EParticipant aParticipant) {
		if (aParticipant.isEnabled() && !R4EUIModelController.getReviewer().equals(aParticipant.getId())) {
			final String emailStr = aParticipant.getEmail();
			if (null != emailStr && !("".equals(emailStr))) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Method createItemsUpdatedDestinations
	 * 
	 * @return String[]
	 */
	private static String[] createItemsUpdatedDestinations() {
		final ArrayList<String> destinations = new ArrayList<String>();
		final List<R4EParticipant> participants = R4EUIModelController.getActiveReview().getParticipants(false);
		for (R4EParticipant participant : participants) {
			if (isEmailValid(participant)) {
				//All active participants should receive this email
				destinations.add(participant.getEmail());
			}
		}
		return destinations.toArray(new String[destinations.size()]);
	}

	/**
	 * Method createProgressDestinations
	 * 
	 * @return String[]
	 */
	private static String[] createProgressDestinations() {
		final ArrayList<String> destinations = new ArrayList<String>();
		final List<R4EParticipant> participants = R4EUIModelController.getActiveReview().getParticipants(false);
		for (R4EParticipant participant : participants) {
			if (isEmailValid(participant)) {
				if (!(R4EUIModelController.getActiveReview().getReview().getType().equals(R4EReviewType.R4E_REVIEW_TYPE_FORMAL))) {
					destinations.add(participant.getEmail());
				} else {
					//If this is a formal review, only send mail if we have the proper role
					if ((participant.getRoles().contains(R4EUserRole.R4E_ROLE_LEAD)
							|| participant.getRoles().contains(R4EUserRole.R4E_ROLE_ORGANIZER) || participant.getRoles()
							.contains(R4EUserRole.R4E_ROLE_AUTHOR))) {
						destinations.add(participant.getEmail());
					}
				}
			}
		}
		return destinations.toArray(new String[destinations.size()]);
	}

	/**
	 * Method createQuestionDestinations
	 * 
	 * @return String[]
	 */
	private static String[] createQuestionDestinations() {
		final ArrayList<String> destinations = new ArrayList<String>();
		final List<R4EParticipant> participants = R4EUIModelController.getActiveReview().getParticipants(false);
		for (R4EParticipant participant : participants) {
			if (isEmailValid(participant)) {
				if (!(R4EUIModelController.getActiveReview().getReview().getType().equals(R4EReviewType.R4E_REVIEW_TYPE_FORMAL))) {
					destinations.add(participant.getEmail());
				} else {
					//If this is a formal review, only send mail if we have the proper role
					if ((participant.getRoles().contains(R4EUserRole.R4E_ROLE_LEAD)
							|| participant.getRoles().contains(R4EUserRole.R4E_ROLE_ORGANIZER) || participant.getRoles()
							.contains(R4EUserRole.R4E_ROLE_AUTHOR))) {
						destinations.add(participant.getEmail());
					}
				}
			}
		}
		return destinations.toArray(new String[destinations.size()]);
	}

	/**
	 * Method createAnomalyCreatorDestination
	 * 
	 * @param aAnomaly
	 *            R4EUIAnomalyBasic
	 * @return String
	 */
	/*  TODO not used for now, could be added later to narrow down destinations for anomaly questions
	private static String[] createAnomalyCreatorDestination(R4EUIAnomalyBasic aAnomaly) {
		final ArrayList<String> destinations = new ArrayList<String>();
		if (!R4EUIModelController.getReviewer().equals(aAnomaly.getAnomaly().getUser().getId())) {
			R4EParticipant participant = (R4EParticipant) aAnomaly.getAnomaly().getUser();
			if (isEmailValid(participant)) {
				destinations.add(participant.getEmail());
			}
		}
		return destinations.toArray(new String[destinations.size()]);
	}
	 */

	/**
	 * Method createItemsReadyNotificationMessage
	 * 
	 * @param aMeetingRequestIncluded
	 *            boolean
	 * @return String
	 */
	private static String createItemsReadyNotificationMessage(boolean aMeetingRequestIncluded) {
		final StringBuilder msgBody = new StringBuilder();

		msgBody.append(createIntroPart());
		if (aMeetingRequestIncluded) {
			msgBody.append(MEETING_REQUEST_MSG_BODY + LINE_FEED_MSG_PART + LINE_FEED_MSG_PART);
		} else {
			msgBody.append(ITEMS_READY_MSG_BODY + LINE_FEED_MSG_PART + LINE_FEED_MSG_PART);
		}
		final List<R4EUIReviewItem> items = R4EUIModelController.getActiveReview().getReviewItems();
		for (R4EUIReviewItem item : items) {
			if (item.isEnabled()) {
				if (null != item.getItem().getDescription()) {
					msgBody.append("Review Item -> " + item.getItem().getDescription() + LINE_FEED_MSG_PART);
				} else {
					//Always use the name of the file for Resource review items
					msgBody.append("Review Item -> " + item.getChildren()[0].getName() + " (Resource)"
							+ LINE_FEED_MSG_PART);
				}
				msgBody.append("Eclipse Project: File Path (Repository | Project)[: Line range]" + LINE_FEED_MSG_PART);
				R4EUIFileContext[] contexts = (R4EUIFileContext[]) item.getChildren();
				for (R4EUIFileContext context : contexts) {
					R4EFileVersion fileVersion = context.getTargetFileVersion();
					if (null == fileVersion) {
						fileVersion = context.getBaseFileVersion();
					}
					if (context.isEnabled() && null != fileVersion) {
						IResource resource = fileVersion.getResource();
						msgBody.append(TAB_MSG_PART);
						//Project
						if (null != resource) {
							msgBody.append(resource.getProject());
						}
						//Path
						String path = fileVersion.getRepositoryPath();
						if (null != path && !(path.equals(""))) {
							msgBody.append(": " + path + " (Repository)");
						} else if (null != resource) {
							msgBody.append(": " + resource.getProjectRelativePath() + " (Project)");
						}
						//Line Range
						R4EUIContent[] contents = (R4EUIContent[]) context.getContentsContainerElement().getChildren();
						msgBody.append(": ");
						for (R4EUIContent content : contents) {
							msgBody.append(content.getPosition().toString() + ", ");
						}
						msgBody.append(LINE_FEED_MSG_PART);
					}
				}
				msgBody.append(LINE_FEED_MSG_PART);
			}
		}
		msgBody.append(createReviewInfoPart());
		msgBody.append(createOutroPart());
		return msgBody.toString();
	}

	/**
	 * Method createRemovedItemsNotificationMessage
	 * 
	 * @param aElements
	 *            List<R4EReviewComponent>
	 * @param aIsAdded
	 *            boolean
	 * @return String
	 */
	private static String createUpdatedItemsNotificationMessage(List<R4EReviewComponent> aElements, boolean aIsAdded) {
		final StringBuilder msgBody = new StringBuilder();

		msgBody.append(createIntroPart());
		if (aIsAdded) {
			msgBody.append(ADDED_ELEMENTS_MSG_BODY + LINE_FEED_MSG_PART + LINE_FEED_MSG_PART);
		} else {
			msgBody.append(REMOVED_ELEMENTS_MSG_BODY + LINE_FEED_MSG_PART + LINE_FEED_MSG_PART);
		}
		boolean legendAppended = false;
		for (R4EReviewComponent component : aElements) {
			if (component instanceof R4EItem) {
				if (null != ((R4EItem) component).getDescription()) {
					msgBody.append("Review Item -> " + ((R4EItem) component).getDescription() + LINE_FEED_MSG_PART);
				}
				msgBody.append("Eclipse Project: File Path (Repository | Project)[: Line range]" + LINE_FEED_MSG_PART);
				EList<R4EFileContext> contexts = ((R4EItem) component).getFileContextList();
				for (R4EFileContext context : contexts) {
					R4EFileVersion fileVersion = context.getTarget();
					if (null != fileVersion) {
						IResource resource = fileVersion.getResource();
						msgBody.append(TAB_MSG_PART);
						//Project
						if (null != resource) {
							msgBody.append(resource.getProject());
						}
						//Path
						String path = fileVersion.getRepositoryPath();
						if (null != path && !(path.equals(""))) {
							msgBody.append(": " + path + " (Repository)");
						} else if (null != resource) {
							msgBody.append(": " + resource.getProjectRelativePath() + " (Project)");
						}
						//Line Range
						if (context.getDeltas().size() > 0) {
							msgBody.append(": ");
							EList<R4EDelta> deltas = context.getDeltas();
							for (R4EDelta delta : deltas) {
								msgBody.append(buildLineTag(delta) + ", ");
							}
						}
					}
					msgBody.append(LINE_FEED_MSG_PART);
				}
				msgBody.append(LINE_FEED_MSG_PART);
			} else if (component instanceof R4EDelta) {
				if (!legendAppended) {
					msgBody.append("Eclipse Project: File Path (Repository | Project)[: Line range]"
							+ LINE_FEED_MSG_PART);
					legendAppended = true;
				}
				R4EFileContext context = (R4EFileContext) ((R4EDelta) component).eContainer();
				R4EFileVersion fileVersion = context.getTarget();
				if (null != fileVersion) {
					IResource resource = fileVersion.getResource();
					msgBody.append(TAB_MSG_PART);
					//Project
					if (null != resource) {
						msgBody.append(resource.getProject());
					}
					//Path
					String path = fileVersion.getRepositoryPath();
					if (null != path && !(path.equals(""))) {
						msgBody.append(": " + path + " (Repository)");
					} else if (null != resource) {
						msgBody.append(": " + resource.getProjectRelativePath() + " (Project)");
					}
					msgBody.append(": " + buildLineTag((R4EDelta) component) + ", ");
				}
			}
			msgBody.append(LINE_FEED_MSG_PART);
		}

		msgBody.append(createReviewInfoPart());
		msgBody.append(createOutroPart());
		return msgBody.toString();
	}

	/**
	 * Method createProgressNotification
	 * 
	 * @param aHeader
	 *            String
	 * @return String
	 */
	private static String createProgressNotification(String aHeader) {
		final StringBuilder msgBody = new StringBuilder();

		msgBody.append(createIntroPart());
		msgBody.append(aHeader + LINE_FEED_MSG_PART);

		//First count the number of elements to add to the message 
		int numReviewedFiles = 0;
		int numTotalFiles = 0;
		int numTotalAnomalies = 0;
		final List<R4EUIReviewItem> items = R4EUIModelController.getActiveReview().getReviewItems();
		for (R4EUIReviewItem item : items) {
			R4EUIFileContext[] contexts = (R4EUIFileContext[]) item.getChildren();
			for (R4EUIFileContext context : contexts) {
				if (context.isUserReviewed()) {
					++numReviewedFiles;
				}
				++numTotalFiles;
				R4EUIAnomalyBasic[] anomalies = (R4EUIAnomalyBasic[]) context.getAnomalyContainerElement()
						.getChildren();
				for (R4EUIAnomalyBasic anomaly : anomalies) {
					if (anomaly.getAnomaly().getUser().getId().equals(R4EUIModelController.getReviewer())) {
						++numTotalAnomalies; //Specific anomalies
					}
				}
			}
		}
		final R4EUIAnomalyBasic[] globalAnomalies = (R4EUIAnomalyBasic[]) R4EUIModelController.getActiveReview()
				.getAnomalyContainer()
				.getChildren();
		for (R4EUIAnomalyBasic anomaly : globalAnomalies) {
			if (anomaly.getAnomaly().getUser().getId().equals(R4EUIModelController.getReviewer())) {
				++numTotalAnomalies; //Global Anomalies
			}
		}

		//Add current review progress
		msgBody.append("Files Reviewed: " + numReviewedFiles + TAB_MSG_PART);
		msgBody.append("Files Total: " + numTotalFiles + TAB_MSG_PART);
		final double progress = (numReviewedFiles / new Integer(numTotalFiles).doubleValue()) * 100;
		final DecimalFormat fmt = new DecimalFormat("#");
		msgBody.append("Progress: " + fmt.format(progress) + "%");
		msgBody.append(LINE_FEED_MSG_PART);

		//Add anomalies created by current reviewer
		msgBody.append("Anomalies Created by: " + R4EUIModelController.getReviewer() + LINE_FEED_MSG_PART);
		msgBody.append("Count: " + numTotalAnomalies + LINE_FEED_MSG_PART + LINE_FEED_MSG_PART);

		R4EUIFileContext context;
		R4EUIAnomalyBasic anomaly;
		for (R4EUIReviewItem item : items) {
			R4EUIFileContext[] contexts = (R4EUIFileContext[]) item.getChildren();
			for (int i = 0; i < contexts.length; i++) {
				context = contexts[i];
				if (0 == i) {
					//Add format line
					msgBody.append("FileContext: " + TAB_MSG_PART + "Eclipse Project: File Path (Repository | Project)"
							+ LINE_FEED_MSG_PART);
				}
				if (null != context.getAnomalyContainerElement()) {
					R4EUIAnomalyBasic[] anomalies = (R4EUIAnomalyBasic[]) context.getAnomalyContainerElement()
							.getChildren();

					R4EFileVersion fileVersion = context.getTargetFileVersion();
					if (null == fileVersion) {
						fileVersion = context.getBaseFileVersion();
					}
					if (context.isEnabled() && null != fileVersion) {
						IResource resource = fileVersion.getResource();
						msgBody.append(TAB_MSG_PART);
						//Project
						if (null != resource) {
							msgBody.append(resource.getProject());
						}
						//Path
						String path = fileVersion.getRepositoryPath();
						if (null != path && !(path.equals(""))) {
							msgBody.append(": " + path + " (Repository)");
						} else if (null != resource) {
							msgBody.append(": " + resource.getProjectRelativePath() + " (Project)");
						}
						msgBody.append(LINE_FEED_MSG_PART);
					}

					for (int j = 0; j < anomalies.length; j++) {
						anomaly = anomalies[j];
						if (0 == j) {
							//Add format line
							msgBody.append(TAB_MSG_PART + "Anomaly: " + "Line Range: Title: Description"
									+ LINE_FEED_MSG_PART);
						}
						if (anomaly.getAnomaly().getUser().getId().equals(R4EUIModelController.getReviewer())) {
							//Add anomaly
							msgBody.append(TAB_MSG_PART + TAB_MSG_PART + "   " + anomaly.getPosition().toString()
									+ ": " + anomaly.getAnomaly().getTitle() + ": "
									+ anomaly.getAnomaly().getDescription() + LINE_FEED_MSG_PART);

							//Also add child comments
							R4EUIComment[] comments = (R4EUIComment[]) anomaly.getChildren();
							for (R4EUIComment comment : comments) {
								msgBody.append(TAB_MSG_PART + TAB_MSG_PART + TAB_MSG_PART + "Comment: "
										+ comment.getComment().getDescription() + LINE_FEED_MSG_PART);
							}
						}
					}
				}
			}
		}
		msgBody.append(LINE_FEED_MSG_PART);

		//Add global anomalies
		if (globalAnomalies.length > 0) {
			msgBody.append("Global Anomalies: " + LINE_FEED_MSG_PART);
		}
		for (R4EUIAnomalyBasic globalAnomaly : globalAnomalies) {
			if (globalAnomaly.getAnomaly().getUser().getId().equals(R4EUIModelController.getReviewer())) {
				//Add anomaly
				msgBody.append(globalAnomaly.getAnomaly().getTitle() + ": "
						+ globalAnomaly.getAnomaly().getDescription() + LINE_FEED_MSG_PART);

				//Also add child comments
				R4EUIComment[] globalComments = (R4EUIComment[]) globalAnomaly.getChildren();
				for (R4EUIComment globalComment : globalComments) {
					msgBody.append(TAB_MSG_PART + "Comment: " + globalComment.getComment().getDescription()
							+ LINE_FEED_MSG_PART);
				}
			}
		}

		msgBody.append(createReviewInfoPart());
		msgBody.append(createOutroPart());
		return msgBody.toString();
	}

	/**
	 * Method createQuestionMessage
	 * 
	 * @param aSource
	 *            Object
	 * @return String
	 * @throws CoreException
	 */
	private static String createQuestionMessage(ISelection aSource) throws CoreException {
		final StringBuilder msgBody = new StringBuilder();
		msgBody.append(createIntroPart());
		msgBody.append(QUESTION_MSG_BODY);

		//Act differently depending on the type of selection we get
		if (aSource instanceof ITextSelection) {
			addElementInfo(msgBody, aSource);
		} else if (aSource instanceof IStructuredSelection) {
			//Iterate through all selections
			for (final Iterator<?> iterator = ((IStructuredSelection) aSource).iterator(); iterator.hasNext();) {
				addElementInfo(msgBody, iterator.next());
				msgBody.append(LINE_FEED_MSG_PART);
			}
		}
		msgBody.append(LINE_FEED_MSG_PART);
		msgBody.append(createReviewInfoPart());
		msgBody.append(createOutroPart());
		return msgBody.toString();
	}

	/**
	 * Method addElementInfo
	 * 
	 * @param aMsgBody
	 *            StringBuilder
	 * @param aSource
	 *            Object
	 * @throws CoreException
	 */
	private static void addElementInfo(StringBuilder aMsgBody, Object aSource) throws CoreException {
		if (aSource instanceof R4EUIPostponedAnomaly) {
			R4EFileVersion file = ((R4EUIFileContext) ((R4EUIPostponedAnomaly) aSource).getParent()).getTargetFileVersion();
			if (null == file) {
				file = ((R4EUIFileContext) ((R4EUIPostponedAnomaly) aSource).getParent()).getBaseFileVersion();
			}
			if (null != file) {
				final String path = file.getRepositoryPath();
				if (null != path && !(path.equals(""))) {
					aMsgBody.append("Postponed File Path (Repository): " + path + LINE_FEED_MSG_PART);
				} else if (null != file.getResource()) {
					aMsgBody.append("Postponed File Path (Project): " + file.getResource().getProject()
							+ R4EUIConstants.SEPARATOR + file.getResource().getProjectRelativePath()
							+ LINE_FEED_MSG_PART);
				}
				aMsgBody.append("Postponed File Version: " + file.getVersionID() + LINE_FEED_MSG_PART);
			} else {
				aMsgBody.append("Postponed File (Local): "
						+ ((R4EUIFileContext) ((R4EUIPostponedAnomaly) aSource).getParent()).getName()
						+ LINE_FEED_MSG_PART);
			}
			aMsgBody.append("Postponed Anomaly Line(s): " + ((R4EUIPostponedAnomaly) aSource).getPosition().toString()
					+ LINE_FEED_MSG_PART);
			aMsgBody.append("Postponed Anomaly Title: " + ((R4EUIPostponedAnomaly) aSource).getAnomaly().getTitle()
					+ LINE_FEED_MSG_PART);
			aMsgBody.append("Postponed Anomaly Description: "
					+ ((R4EUIPostponedAnomaly) aSource).getAnomaly().getDescription() + LINE_FEED_MSG_PART);
		} else if (aSource instanceof R4EUIAnomalyBasic) {
			final IR4EUIModelElement parent = ((R4EUIAnomalyBasic) aSource).getParent().getParent();
			if (parent instanceof R4EUIFileContext) {
				//This is an anomaly tied to specific content
				R4EFileVersion file = ((R4EUIFileContext) parent).getTargetFileVersion();
				if (null == file) {
					file = ((R4EUIFileContext) parent).getBaseFileVersion();
				}
				if (null != file) {
					final String path = file.getRepositoryPath();
					if (null != path && !(path.equals(""))) {
						aMsgBody.append("File Path (Repository): " + path + LINE_FEED_MSG_PART);
					} else if (null != file.getResource()) {
						aMsgBody.append("File Path (Project): " + file.getResource().getProject()
								+ R4EUIConstants.SEPARATOR + file.getResource().getProjectRelativePath()
								+ LINE_FEED_MSG_PART);
					}
					aMsgBody.append("File Version: " + file.getVersionID() + LINE_FEED_MSG_PART);
				} else {
					aMsgBody.append("File (Local): "
							+ ((R4EUIFileContext) ((R4EUIAnomalyBasic) aSource).getParent().getParent()).getName()
							+ LINE_FEED_MSG_PART);
				}
				aMsgBody.append("Anomaly Line(s): " + ((R4EUIAnomalyBasic) aSource).getPosition().toString()
						+ LINE_FEED_MSG_PART);
			}
			aMsgBody.append("Anomaly Title: " + ((R4EUIAnomalyBasic) aSource).getAnomaly().getTitle()
					+ LINE_FEED_MSG_PART);
			aMsgBody.append("Anomaly Description: " + ((R4EUIAnomalyBasic) aSource).getAnomaly().getDescription()
					+ LINE_FEED_MSG_PART);
		} else if (aSource instanceof R4EUIComment) {
			final IR4EUIModelElement parent = ((R4EUIComment) aSource).getParent().getParent().getParent();
			if (parent instanceof R4EUIFileContext) {
				R4EFileVersion file = ((R4EUIFileContext) parent).getTargetFileVersion();
				if (null == file) {
					file = ((R4EUIFileContext) parent).getBaseFileVersion();
				}
				if (null != file) {
					final String path = file.getRepositoryPath();
					if (null != path && !(path.equals(""))) {
						aMsgBody.append("File Path (Repository): " + path + LINE_FEED_MSG_PART);
					} else if (null != file.getResource()) {
						aMsgBody.append("File Path (Project): " + file.getResource().getProject()
								+ R4EUIConstants.SEPARATOR + file.getResource().getProjectRelativePath()
								+ LINE_FEED_MSG_PART);
					}
					aMsgBody.append("File Version: " + file.getVersionID() + LINE_FEED_MSG_PART);
				} else {
					aMsgBody.append("File (Local): "
							+ ((R4EUIFileContext) ((R4EUIComment) aSource).getParent().getParent().getParent()).getName()
							+ LINE_FEED_MSG_PART);
				}
				aMsgBody.append("Anomaly Line(s): "
						+ ((R4EUIAnomalyBasic) ((R4EUIComment) aSource).getParent()).getPosition().toString()
						+ LINE_FEED_MSG_PART);
			}
			aMsgBody.append("Anomaly Title: "
					+ ((R4EUIAnomalyBasic) ((R4EUIComment) aSource).getParent()).getAnomaly().getTitle()
					+ LINE_FEED_MSG_PART);
			aMsgBody.append("Anomaly Description: "
					+ ((R4EUIAnomalyBasic) ((R4EUIComment) aSource).getParent()).getAnomaly().getDescription()
					+ LINE_FEED_MSG_PART);

			aMsgBody.append("Anomaly Comment: " + ((R4EUIComment) aSource).getComment().getDescription()
					+ LINE_FEED_MSG_PART);
		} else if (aSource instanceof R4EUIReviewBasic) {
			aMsgBody.append("Review: " + ((R4EUIReviewBasic) aSource).getReview().getName() + LINE_FEED_MSG_PART);

		} else if (aSource instanceof R4EUIReviewItem) {
			final String description = ((R4EUIReviewItem) aSource).getItem().getDescription();
			if (null != description) {
				aMsgBody.append("Review Item Description: " + description + LINE_FEED_MSG_PART);
			} else {
				//This is a ressource review item, so put the resource filename
				aMsgBody.append("Review Item Resource: "
						+ ((R4EUIReviewItem) aSource).getFileContexts().get(0).getName() + LINE_FEED_MSG_PART);
			}

		} else if (aSource instanceof R4EUIFileContext) {
			final R4EFileVersion file = ((R4EUIFileContext) aSource).getTargetFileVersion();
			if (null != file) {
				final String path = file.getRepositoryPath();
				if (null != path && !(path.equals(""))) {
					aMsgBody.append("Target File Path (Repository): " + path + LINE_FEED_MSG_PART);
				} else if (null != file.getResource()) {
					aMsgBody.append("Target File Path (Project): " + file.getResource().getProject()
							+ R4EUIConstants.SEPARATOR + file.getResource().getProjectRelativePath()
							+ LINE_FEED_MSG_PART);
				}
				aMsgBody.append("Target File Version: " + file.getVersionID() + LINE_FEED_MSG_PART);
			} else {
				aMsgBody.append("Target File (Local): " + ((R4EUIFileContext) aSource).getName() + LINE_FEED_MSG_PART);
				aMsgBody.append("Target File Version: None" + LINE_FEED_MSG_PART);
			}
			final R4EFileVersion baseFile = ((R4EUIFileContext) aSource).getBaseFileVersion();
			if (null != baseFile) {
				final String path = baseFile.getRepositoryPath();
				if (null != path && !(path.equals(""))) {
					aMsgBody.append("Base File Path (Repository): " + path + LINE_FEED_MSG_PART);
				} else if (null != baseFile.getResource()) {
					aMsgBody.append("Base File Path (Project): " + baseFile.getResource().getProject()
							+ R4EUIConstants.SEPARATOR + baseFile.getResource().getProjectRelativePath()
							+ LINE_FEED_MSG_PART);
				}
				aMsgBody.append("Base File Version: " + baseFile.getVersionID() + LINE_FEED_MSG_PART);
			} else {
				aMsgBody.append("Base File (Local): " + ((R4EUIFileContext) aSource).getName() + LINE_FEED_MSG_PART);
				aMsgBody.append("Base File Version: None" + LINE_FEED_MSG_PART);
			}
		} else if (aSource instanceof R4EUIContent) {
			R4EFileVersion file = ((R4EUIFileContext) ((R4EUIContent) aSource).getParent().getParent()).getTargetFileVersion();
			if (null == file) {
				file = ((R4EUIFileContext) ((R4EUIContent) aSource).getParent().getParent()).getBaseFileVersion();
			}
			if (null != file) {
				final String path = file.getRepositoryPath();
				if (null != path && !(path.equals(""))) {
					aMsgBody.append("File Path (Repository): " + path + LINE_FEED_MSG_PART);
				} else if (null != file.getResource()) {
					aMsgBody.append("File Path (Project): " + file.getResource().getProject()
							+ R4EUIConstants.SEPARATOR + file.getResource().getProjectRelativePath()
							+ LINE_FEED_MSG_PART);
				}
				aMsgBody.append("File Version: " + file.getVersionID() + LINE_FEED_MSG_PART);
			} else {
				aMsgBody.append("File (Local): "
						+ ((R4EUIFileContext) ((R4EUIContent) aSource).getParent().getParent()).getName()
						+ LINE_FEED_MSG_PART);
			}
			aMsgBody.append("Content Line(s): " + ((R4EUIContent) aSource).getPosition().toString()
					+ LINE_FEED_MSG_PART);

		} else if (aSource instanceof IFile) {
			aMsgBody.append("File: " + ((IFile) aSource).getProject().getName() + R4EUIConstants.SEPARATOR
					+ ((IFile) aSource).getProjectRelativePath().toPortableString() + LINE_FEED_MSG_PART);
			aMsgBody.append(LINE_FEED_MSG_PART);
			aMsgBody.append("Position in File: " + CommandUtils.getPosition((IFile) aSource).toString()
					+ LINE_FEED_MSG_PART);
		} else if (aSource instanceof TextSelection) {
			final IEditorPart editorPart = PlatformUI.getWorkbench()
					.getActiveWorkbenchWindow()
					.getActivePage()
					.getActiveEditor();
			final IEditorInput input = editorPart.getEditorInput();
			if (input instanceof R4ECompareEditorInput) {
				//TODO: For now we give the file version of the file on the left side, regardless of whose side the selected input was.
				//		Later we want to refine this.
				final ITypedElement element = ((R4ECompareEditorInput) input).getLeftElement();
				if (element instanceof R4EFileTypedElement) {
					final R4EFileVersion file = ((R4EFileTypedElement) element).getFileVersion();
					aMsgBody.append("File: " + file.getResource().getProject() + R4EUIConstants.SEPARATOR
							+ file.getResource().getProjectRelativePath() + LINE_FEED_MSG_PART);
					aMsgBody.append("File Version: " + file.getVersionID() + LINE_FEED_MSG_PART);
				} else if (element instanceof R4EFileRevisionTypedElement) {
					final R4EFileVersion file = ((R4EFileRevisionTypedElement) element).getFileVersion();
					aMsgBody.append("File Path: " + file.getRepositoryPath() + LINE_FEED_MSG_PART);
					aMsgBody.append("File Version: " + file.getVersionID() + LINE_FEED_MSG_PART);
				}
			} else if (input instanceof R4EFileRevisionEditorInput) {
				final R4EFileVersion file = ((R4EFileRevisionEditorInput) input).getFileVersion();
				aMsgBody.append("File Path: " + file.getRepositoryPath() + LINE_FEED_MSG_PART);
				aMsgBody.append("File Version: " + file.getVersionID() + LINE_FEED_MSG_PART);
			} else if (input instanceof R4EFileEditorInput) {
				final R4EFileVersion file = ((R4EFileEditorInput) input).getFileVersion();
				aMsgBody.append("File: " + file.getResource().getProject() + R4EUIConstants.SEPARATOR
						+ file.getResource().getProjectRelativePath() + LINE_FEED_MSG_PART);
				aMsgBody.append("File Version: " + file.getVersionID() + LINE_FEED_MSG_PART);
			} else if (input instanceof FileEditorInput) {
				final IFile file = ((FileEditorInput) input).getFile();
				aMsgBody.append("File: " + file.getProject() + R4EUIConstants.SEPARATOR + file.getProjectRelativePath()
						+ LINE_FEED_MSG_PART);
				aMsgBody.append("File Version: (None available)" + LINE_FEED_MSG_PART);
			}
			final TextSelection selectedText = (TextSelection) aSource;
			aMsgBody.append(LINE_FEED_MSG_PART);
			aMsgBody.append("Position in File: " + CommandUtils.getPosition(selectedText).toString()
					+ LINE_FEED_MSG_PART + LINE_FEED_MSG_PART);
			aMsgBody.append("Contents: " + LINE_FEED_MSG_PART);
			aMsgBody.append(selectedText.getText());
		} else if (R4EUIPlugin.isJDTAvailable() && aSource instanceof ISourceReference) {
			//NOTE:  This is always true because all elements that implement ISourceReference
			//       also implement IJavaElement.  The resource is always an IFile
			final IFile file = (IFile) ((IJavaElement) aSource).getResource();
			aMsgBody.append("File: " + file.getProject() + R4EUIConstants.SEPARATOR + file.getProjectRelativePath()
					+ LINE_FEED_MSG_PART);
			aMsgBody.append("File Version: (None available)" + LINE_FEED_MSG_PART);
			try {
				final R4EUITextPosition position = CommandUtils.getPosition((ISourceReference) aSource, file);
				aMsgBody.append("Position in File: " + position.toString() + LINE_FEED_MSG_PART + LINE_FEED_MSG_PART);
			} catch (CoreException e) {
				// Ignore
			}
		} else if (R4EUIPlugin.isCDTAvailable() && aSource instanceof org.eclipse.cdt.core.model.ISourceReference) {
			//NOTE:  This is always true because all elements that implement ISourceReference
			//       also implement ICElement.  The resource is always an IFile
			IFile file = null;
			if (aSource instanceof org.eclipse.cdt.core.model.ITranslationUnit) {
				file = (IFile) ((org.eclipse.cdt.core.model.ICElement) aSource).getResource();
			} else if (aSource instanceof org.eclipse.cdt.core.model.ICElement) {
				file = (IFile) ((org.eclipse.cdt.core.model.ICElement) aSource).getParent().getResource();
			}
			if (null != file) {
				aMsgBody.append("File: " + file.getProject() + R4EUIConstants.SEPARATOR + file.getProjectRelativePath()
						+ LINE_FEED_MSG_PART);
				aMsgBody.append("File Version: (None available)" + LINE_FEED_MSG_PART);
				try {
					final R4EUITextPosition position = CommandUtils.getPosition(
							(org.eclipse.cdt.core.model.ISourceReference) aSource, file);
					aMsgBody.append("Position in File: " + position.toString() + LINE_FEED_MSG_PART
							+ LINE_FEED_MSG_PART);
				} catch (CoreException e) {
					// Ignore
				}
			}
		}
	}

	/**
	 * Method createReviewInfoPart
	 * 
	 * @return String
	 */
	private static String createReviewInfoPart() {
		final StringBuilder msgReviewInfo = new StringBuilder();

		msgReviewInfo.append(LINE_FEED_MSG_PART);
		msgReviewInfo.append("Review Information");
		msgReviewInfo.append(LINE_FEED_MSG_PART);
		msgReviewInfo.append("Group: " + TAB_MSG_PART + TAB_MSG_PART
				+ R4EUIModelController.getActiveReview().getParent().getName() + LINE_FEED_MSG_PART);
		msgReviewInfo.append("Review: " + TAB_MSG_PART + R4EUIModelController.getActiveReview().getReview().getName()
				+ LINE_FEED_MSG_PART);
		msgReviewInfo.append("Components: " + TAB_MSG_PART);
		final List<String> components = R4EUIModelController.getActiveReview().getReview().getComponents();
		for (String component : components) {
			msgReviewInfo.append(component + ", ");
		}
		msgReviewInfo.append(LINE_FEED_MSG_PART);
		msgReviewInfo.append("Project: " + TAB_MSG_PART
				+ R4EUIModelController.getActiveReview().getReview().getProject() + LINE_FEED_MSG_PART);
		msgReviewInfo.append("Participants: " + TAB_MSG_PART);
		final List<String> participants = R4EUIModelController.getActiveReview().getParticipantIDs();
		for (String participant : participants) {
			msgReviewInfo.append(participant + ", ");
		}
		msgReviewInfo.append(LINE_FEED_MSG_PART);
		msgReviewInfo.append(LINE_FEED_MSG_PART);

		return msgReviewInfo.toString();
	}

	/**
	 * Method replaceParticipantsInBody
	 * 
	 * @param aOldBody
	 *            - String
	 * @return String
	 */
	private static String replaceParticipantsInBody(String aOldBody) {
		StringBuffer buffer = new StringBuffer();
		buffer.append("Participants: " + TAB_MSG_PART);
		final List<String> participants = R4EUIModelController.getActiveReview().getParticipantIDs();
		for (String participant : participants) {
			buffer.append(participant + ", ");
		}
		buffer.append(LINE_FEED_MSG_PART);
		return aOldBody.replaceFirst("Participants:.*", buffer.toString());
	}

	/**
	 * Method createIntroPart
	 * 
	 * @return String
	 */
	private static String createIntroPart() {
		final StringBuilder msgIntro = new StringBuilder();
		msgIntro.append(LINE_FEED_MSG_PART);
		msgIntro.append(INTRO_MSG_BODY);
		msgIntro.append(LINE_FEED_MSG_PART);
		msgIntro.append(LINE_FEED_MSG_PART);
		return msgIntro.toString();
	}

	/**
	 * Method createOutroPart
	 * 
	 * @return String
	 */
	private static String createOutroPart() {
		final StringBuilder msgOutro = new StringBuilder();
		msgOutro.append(OUTRO_MSG_BODY + LINE_FEED_MSG_PART);
		msgOutro.append(R4EUIModelController.getReviewer());
		return msgOutro.toString();
	}

	//Meetings

	/**
	 * Method sendMeetingRequest
	 * 
	 * @throws OutOfSyncException
	 * @throws ResourceHandlingException
	 * @throws CoreException
	 */
	public static void sendMeetingRequest() throws ResourceHandlingException, OutOfSyncException {
		final NotificationsConnector mailConnector = R4EUIDialogFactory.getInstance().getMailConnector();
		if (null != mailConnector) {

			String originatorEmail = getOriginatorEmail();
			String[] destinations = adjustDestinationEmails(createItemsUpdatedDestinations(), originatorEmail);

			//Notify user if request cannot be sent when no valid destinations defined
			if (0 == destinations.length) {
				final ErrorDialog dialog = new ErrorDialog(null, R4EUIConstants.DIALOG_TITLE_ERROR,
						"Cannot Send Meeting Request", new Status(IStatus.ERROR, R4EUIPlugin.PLUGIN_ID,
								"No valid destinations for participants defined", null), IStatus.ERROR);
				Display.getDefault().syncExec(new Runnable() {
					public void run() {
						dialog.open();
					}
				});
				return;
			}

			IMeetingData updatedMeetingData = null;

			//Check if a meeting request already exist.  If so, update it.  Otherwise create a new one
			final R4EMeetingData r4eMeetingData = R4EUIModelController.getActiveReview().getReview().getActiveMeeting();
			if (null != r4eMeetingData) {
				IMeetingData oldMeetingData = null;
				final IMeetingData localMeetingData = new R4EUIMeetingData(r4eMeetingData);

				//First update the current meeting request local data with any source/destination changes (if any)
				localMeetingData.setSender(originatorEmail);
				localMeetingData.clearReceivers();
				for (String destination : destinations) {
					localMeetingData.addReceiver(destination);
				}
				localMeetingData.setBody(replaceParticipantsInBody(localMeetingData.getBody()));

				//Then try to find the meeting data on mail server
				oldMeetingData = mailConnector.fetchSystemMeetingData(localMeetingData,
						R4EUIModelController.getActiveReview().getReview().getStartDate());

				if (null == oldMeetingData) {
					//Meeting data not found on mail server, so create one from the local data
					try {
						updatedMeetingData = mailConnector.createMeetingRequest(createSubject()
								+ DECISION_MEETING_UPDATED_MSG, localMeetingData.getBody(), destinations,
								localMeetingData.getStartTime(), localMeetingData.getDuration(),
								localMeetingData.getLocation());
					} catch (CoreException e) {
						R4EUIPlugin.Ftracer.traceWarning("Exception: " + e.toString() + " (" + e.getMessage() + ")");
						R4EUIPlugin.getDefault().logWarning("Exception: " + e.toString(), e);
						return;
					}
				} else {
					//Meeting data found on mail server, now let's compare the values
					if (!localMeetingData.equals(oldMeetingData)) {
						//Values are different, ask user which ones we should keep
						final int result = UIUtils.displayMeetingDataMismatchDialog(localMeetingData, oldMeetingData);
						if (result == R4EUIConstants.DIALOG_YES) {
							//Update the mail server data with local data
							updatedMeetingData = mailConnector.openAndUpdateMeeting(localMeetingData,
									R4EUIModelController.getActiveReview().getReview().getStartDate(), true);
						} else if (result == R4EUIConstants.DIALOG_NO) {
							//Update the local data with mail server data
							updatedMeetingData = mailConnector.openAndUpdateMeeting(localMeetingData,
									R4EUIModelController.getActiveReview().getReview().getStartDate(), false);
						}
					} else {
						//Use local data
						updatedMeetingData = mailConnector.openAndUpdateMeeting(localMeetingData,
								R4EUIModelController.getActiveReview().getReview().getStartDate(), true);
					}
				}
			} else {
				//Meeting data not found anywhere, so create a brand new one with default values
				try {
					updatedMeetingData = mailConnector.createMeetingRequest(createSubject()
							+ DECISION_MEETING_INITIAL_MSG, createItemsReadyNotificationMessage(true), destinations,
							getDefaultStartTime(), DEFAULT_MEETING_DURATION, "");
				} catch (CoreException e) {
					R4EUIPlugin.Ftracer.traceWarning("Exception: " + e.toString() + " (" + e.getMessage() + ")");
					R4EUIPlugin.getDefault().logWarning("Exception: " + e.toString(), e);
					return;
				}
			}
			if (null != updatedMeetingData) {
				R4EUIModelController.getActiveReview().setMeetingData(updatedMeetingData);
			}
		} else {
			showNoEmailConnectorDialog();
		}
	}

	/**
	 * Method getDefaultStartTime
	 * 
	 * @return Long
	 */
	public static Long getDefaultStartTime() {

		// Make sure we leave 3 days to review and don't set a meeting on the week-end
		final GregorianCalendar meetingDate = new GregorianCalendar();
		switch (meetingDate.get(Calendar.DAY_OF_WEEK)) {
		case Calendar.TUESDAY:
			meetingDate.setTimeInMillis(meetingDate.getTimeInMillis() + 518400000);
			break;
		case Calendar.WEDNESDAY:
			meetingDate.setTimeInMillis(meetingDate.getTimeInMillis() + 691200000);
			break;
		case Calendar.THURSDAY:
			meetingDate.setTimeInMillis(meetingDate.getTimeInMillis() + 604800000);
			break;
		case Calendar.FRIDAY:
			meetingDate.setTimeInMillis(meetingDate.getTimeInMillis() + 518400000);
			break;
		case Calendar.SATURDAY:
			meetingDate.setTimeInMillis(meetingDate.getTimeInMillis() + 432000000);
			break;
		default:
			meetingDate.setTimeInMillis(meetingDate.getTimeInMillis() + 345600000);
			break;
		}

		// Set start time at 10 AM
		meetingDate.set(Calendar.HOUR_OF_DAY, 10);
		meetingDate.set(Calendar.MINUTE, 0);
		meetingDate.set(Calendar.SECOND, 0);
		// Add the current time zone offset
		meetingDate.setTimeInMillis(meetingDate.getTimeInMillis());
		return Long.valueOf(meetingDate.getTimeInMillis());
	}

	/**
	 * Method showNoEmailConnectorDialog
	 */
	private static void showNoEmailConnectorDialog() {
		final ErrorDialog dialog = new ErrorDialog(
				null,
				R4EUIConstants.DIALOG_TITLE_WARNING,
				"No Email connector detected"
						+ "Take note that no Automatic Email can be sent because no Mail Services Connector is Present",
				new Status(IStatus.WARNING, R4EUIPlugin.PLUGIN_ID, 0, null, null), IStatus.WARNING);
		Display.getDefault().syncExec(new Runnable() {
			public void run() {
				dialog.open();
			}
		});
	}

	/**
	 * Method buildLineTag
	 * 
	 * @param aDelta
	 *            R4EDelta
	 * @return String
	 */
	private static String buildLineTag(R4EDelta aDelta) {
		if (null != aDelta.getTarget() && null != aDelta.getTarget().getLocation()) {
			final int startLine = ((R4ETextPosition) aDelta.getTarget().getLocation()).getStartLine();
			final int endLineLine = ((R4ETextPosition) aDelta.getTarget().getLocation()).getEndLine();
			final StringBuilder buffer = new StringBuilder(R4EUIConstants.DEFAULT_LINE_TAG_LENGTH);
			if (startLine == endLineLine) {
				buffer.append(R4EUIConstants.LINE_TAG + startLine);
			} else {
				buffer.append(R4EUIConstants.LINES_TAG + startLine + "-" + endLineLine);
			}
			return buffer.toString();
		}
		return "";
	}
}