ASSIGNED - bug 168204: [patch] support bugzilla's usermatchmode for
matching names to email addresses 
https://bugs.eclipse.org/bugs/show_bug.cgi?id=168204
diff --git a/org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/BugzillaClient.java b/org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/BugzillaClient.java
index 6ae7592..c9e816d 100644
--- a/org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/BugzillaClient.java
+++ b/org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/BugzillaClient.java
@@ -1919,7 +1919,30 @@
 										"You have been logged out. Please retry operation.")); //$NON-NLS-1$
 							}
 						}
+						for (Iterator<String> iterator = bugzillaLanguageSettings.getResponseForCommand(
+								BugzillaLanguageSettings.COMMAND_ERROR_CONFIRM_MATCH).iterator(); iterator.hasNext()
+								&& !found;) {
+							String value = iterator.next().toLowerCase(Locale.ENGLISH);
+							found = found || title.indexOf(value) != -1;
+						}
+						if (found) {
+							BugzillaStatus status = new BugzillaStatus(IStatus.ERROR, BugzillaCorePlugin.ID_PLUGIN,
+									BugzillaStatus.ERROR_CONFIRM_MATCH, repositoryUrl.toString(), "Confirm Match", body); //$NON-NLS-1$
+							parseResultConfirmMatch(tokenizer, status);
+						}
 
+						found = false;
+						for (Iterator<String> iterator = bugzillaLanguageSettings.getResponseForCommand(
+								BugzillaLanguageSettings.COMMAND_ERROR_MATCH_FAILED).iterator(); iterator.hasNext()
+								&& !found;) {
+							String value = iterator.next().toLowerCase(Locale.ENGLISH);
+							found = found || title.indexOf(value) != -1;
+						}
+						if (found) {
+							BugzillaStatus status = new BugzillaStatus(IStatus.ERROR, BugzillaCorePlugin.ID_PLUGIN,
+									BugzillaStatus.ERROR_MATCH_FAILED, repositoryUrl.toString(), "Match Failed", body); //$NON-NLS-1$
+							parseResultMatchFailed(tokenizer, status);
+						}
 						isTitle = false;
 					}
 				} else {
@@ -2456,4 +2479,116 @@
 		}
 	}
 
+	private void parseResultConfirmMatch(HtmlStreamTokenizer tokenizer, BugzillaStatus status) throws IOException,
+			CoreException {
+		boolean isSelect = false;
+		String name = ""; //$NON-NLS-1$
+		String value = ""; //$NON-NLS-1$
+		try {
+			for (Token token = tokenizer.nextToken(); token.getType() != Token.EOF; token = tokenizer.nextToken()) {
+				if (token.getType() == Token.TAG && ((HtmlTag) (token.getValue())).getTagType() == Tag.SELECT
+						&& !((HtmlTag) (token.getValue())).isEndTag()) {
+					isSelect = true;
+					name = ((HtmlTag) (token.getValue())).getAttribute("id"); //$NON-NLS-1$
+					continue;
+				}
+
+				if (isSelect) {
+					if (token.getType() == Token.TAG && ((HtmlTag) (token.getValue())).getTagType() == Tag.OPTION
+							&& !((HtmlTag) (token.getValue())).isEndTag()) {
+						value = ((HtmlTag) (token.getValue())).getAttribute("value"); //$NON-NLS-1$
+						status.addResponseData(name, value);
+					}
+					if (token.getType() == Token.TAG && ((HtmlTag) token.getValue()).getTagType() == Tag.SELECT
+							&& ((HtmlTag) token.getValue()).isEndTag()) {
+						isSelect = false;
+					}
+				}
+			}
+			throw new CoreException(status);
+		} catch (ParseException e) {
+			throw new CoreException(new BugzillaStatus(IStatus.ERROR, BugzillaCorePlugin.ID_PLUGIN,
+					RepositoryStatus.ERROR_INTERNAL, "Unable to parse response from " + repositoryUrl.toString() + ".")); //$NON-NLS-1$//$NON-NLS-2$
+		}
+	}
+
+	private void parseResultMatchFailed(HtmlStreamTokenizer tokenizer, BugzillaStatus status) throws IOException,
+			CoreException {
+		boolean isDT = false;
+		String dtString = ""; //$NON-NLS-1$
+		String lastDTValue = ""; //$NON-NLS-1$
+		boolean isDiv = false;
+		String divString = ""; //$NON-NLS-1$
+		try {
+			for (Token token = tokenizer.nextToken(); token.getType() != Token.EOF; token = tokenizer.nextToken()) {
+				if (token.getType() == Token.TAG && ((HtmlTag) (token.getValue())).getTagType() == Tag.TD
+						&& ((HtmlTag) (token.getValue())).isEndTag()) {
+					isDT = false;
+					if (!dtString.equals("")) { //$NON-NLS-1$
+						lastDTValue = dtString;
+					}
+					dtString = ""; //$NON-NLS-1$
+					continue;
+				}
+				if (token.getType() == Token.TAG && ((HtmlTag) (token.getValue())).getTagType() == Tag.DIV
+						&& ((HtmlTag) (token.getValue())).isEndTag()) {
+					isDiv = false;
+					if (divString.length() > 4) {
+						if (lastDTValue.equals("CC:")) { //$NON-NLS-1$
+							lastDTValue = "newcc"; //$NON-NLS-1$
+						}
+						if (lastDTValue.equals("Assignee:")) { //$NON-NLS-1$
+							lastDTValue = "assigned_to"; //$NON-NLS-1$
+						}
+						if (lastDTValue.equals("QAContact:")) { //$NON-NLS-1$
+							lastDTValue = "qa_contact"; //$NON-NLS-1$
+						}
+
+						int start = divString.indexOf("</b>"); //$NON-NLS-1$
+						int optionValue = divString.indexOf("<option value=\"", start + 4); //$NON-NLS-1$
+						String value = ""; //$NON-NLS-1$
+						if (optionValue == -1) {
+							int startText = divString.indexOf(">", start + 4) + 1; //$NON-NLS-1$
+							int endText = divString.indexOf("<", startText + 1); //$NON-NLS-1$
+							String temp = divString.substring(startText, endText);
+							value = divString.substring(5, start) + temp;
+							status.addResponseData(lastDTValue, "#msg#" + value); //$NON-NLS-1$
+						} else {
+							while (optionValue != -1) {
+								int endText = divString.indexOf("\">", optionValue + 1); //$NON-NLS-1$
+								value = divString.substring(optionValue + 15, endText);
+								value = value.replace("&#64;", "@"); //$NON-NLS-1$ //$NON-NLS-2$
+								status.addResponseData(lastDTValue, value);
+								optionValue = divString.indexOf("<option value=\"", endText + 1); //$NON-NLS-1$
+							}
+						}
+					}
+					dtString = ""; //$NON-NLS-1$
+					divString = ""; //$NON-NLS-1$
+					continue;
+				}
+				if (isDiv) {
+					divString += (" " + token.getValue()); //$NON-NLS-1$
+				}
+				if (isDT) {
+					if (token.getType() == Token.TAG && ((HtmlTag) (token.getValue())).getTagType() == Tag.DIV
+							&& !((HtmlTag) (token.getValue())).isEndTag()) {
+						isDiv = true;
+						divString = ""; //$NON-NLS-1$
+					} else {
+						dtString += token.getValue();
+					}
+				}
+				if (token.getType() == Token.TAG && ((HtmlTag) (token.getValue())).getTagType() == Tag.TD
+						&& !((HtmlTag) (token.getValue())).isEndTag()) {
+					isDT = true;
+					continue;
+				}
+			}
+			throw new CoreException(status);
+		} catch (ParseException e) {
+			throw new CoreException(new BugzillaStatus(IStatus.ERROR, BugzillaCorePlugin.ID_PLUGIN,
+					RepositoryStatus.ERROR_INTERNAL, "Unable to parse response from " + repositoryUrl.toString() + ".")); //$NON-NLS-1$ //$NON-NLS-2$
+		}
+	}
 }
diff --git a/org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/BugzillaLanguageSettings.java b/org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/BugzillaLanguageSettings.java
index 214410b..8c21559 100644
--- a/org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/BugzillaLanguageSettings.java
+++ b/org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/BugzillaLanguageSettings.java
@@ -42,6 +42,10 @@
 
 	public static final String COMMAND_SUSPICIOUS_ACTION = "suspicious_action"; //$NON-NLS-1$
 
+	public static final String COMMAND_ERROR_CONFIRM_MATCH = "error_confirm_match"; //$NON-NLS-1$
+
+	public static final String COMMAND_ERROR_MATCH_FAILED = "error_match_failed"; //$NON-NLS-1$
+
 	public static final String COMMAND_BUG = "bug"; //$NON-NLS-1$
 
 	public static final String COMMAND_SUBMITTED = "submitted"; //$NON-NLS-1$
diff --git a/org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/BugzillaRepositoryConnector.java b/org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/BugzillaRepositoryConnector.java
index bba1d98..3cf9512 100644
--- a/org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/BugzillaRepositoryConnector.java
+++ b/org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/BugzillaRepositoryConnector.java
@@ -131,6 +131,8 @@
 		enSetting.addLanguageAttribute("submitted", "Submitted"); //$NON-NLS-1$ //$NON-NLS-2$
 		enSetting.addLanguageAttribute("submitted", "posted"); //$NON-NLS-1$ //$NON-NLS-2$
 		enSetting.addLanguageAttribute("suspicious_action", "Suspicious action"); //$NON-NLS-1$ //$NON-NLS-2$
+		enSetting.addLanguageAttribute("error_confirm_match", "confirm match"); //$NON-NLS-1$//$NON-NLS-2$
+		enSetting.addLanguageAttribute("error_match_failed", "match failed"); //$NON-NLS-1$ //$NON-NLS-2$
 		languages.add(enSetting);
 
 		java2buzillaPlatformMap.put("x86", "PC"); // can be PC or Macintosh! //$NON-NLS-1$ //$NON-NLS-2$
diff --git a/org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/BugzillaStatus.java b/org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/BugzillaStatus.java
index 344f658..5df54dc 100644
--- a/org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/BugzillaStatus.java
+++ b/org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/BugzillaStatus.java
@@ -11,6 +11,11 @@
 
 package org.eclipse.mylyn.internal.bugzilla.core;
 
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
 import org.eclipse.core.runtime.Status;
 import org.eclipse.mylyn.tasks.core.RepositoryStatus;
 import org.eclipse.osgi.util.NLS;
@@ -24,26 +29,38 @@
 
 	private String repositoryUrl = ""; //$NON-NLS-1$
 
+	public final static int ERROR_CONFIRM_MATCH = 1024;
+
+	public final static int ERROR_MATCH_FAILED = 1025;
+
+	private final String htmlMessage;
+
+	private Map<String, List<String>> responseData = new LinkedHashMap<String, List<String>>();
+
 	public BugzillaStatus(int severity, String pluginId, int code) {
 		super(severity, pluginId, code, "MylynStatus", null); //$NON-NLS-1$
 		this.errorMessage = null;
+		this.htmlMessage = null;
 	}
 
 	public BugzillaStatus(int severity, String pluginId, int code, String errorMessage) {
 		super(severity, pluginId, code, "MylynStatus", null); //$NON-NLS-1$
 		this.errorMessage = errorMessage;
+		this.htmlMessage = null;
 	}
 
 	public BugzillaStatus(int severity, String pluginId, int code, String repositoryUrl, Throwable e) {
 		super(severity, pluginId, code, "MylynStatus", e); //$NON-NLS-1$
 		this.repositoryUrl = repositoryUrl;
 		this.errorMessage = e.getMessage();
+		this.htmlMessage = null;
 	}
 
 	public BugzillaStatus(int severity, String pluginId, int code, String repositoryUrl, String errorMessage) {
 		super(severity, pluginId, code, "MylynStatus", null); //$NON-NLS-1$
 		this.errorMessage = errorMessage;
 		this.repositoryUrl = repositoryUrl;
+		this.htmlMessage = null;
 	}
 
 	public BugzillaStatus(int severity, String pluginId, int code, String repositoryUrl, String errorMessage,
@@ -51,6 +68,15 @@
 		super(severity, pluginId, code, "MylynStatus", e); //$NON-NLS-1$
 		this.errorMessage = errorMessage;
 		this.repositoryUrl = repositoryUrl;
+		this.htmlMessage = null;
+	}
+
+	public BugzillaStatus(int severity, String pluginId, int code, String repositoryUrl, String errorMessage,
+			String body) {
+		super(severity, pluginId, code, "MylynStatus", null); //$NON-NLS-1$
+		this.errorMessage = errorMessage;
+		this.repositoryUrl = repositoryUrl;
+		this.htmlMessage = body;
 	}
 
 	/**
@@ -112,4 +138,25 @@
 	public void setRepositoryUrl(String repositoryUrl) {
 		this.repositoryUrl = repositoryUrl;
 	}
+
+	public String getHtmlMessage() {
+		return htmlMessage;
+	}
+
+	public Map<String, List<String>> getResponseData() {
+		return responseData;
+	}
+
+	public void setResponseData(Map<String, List<String>> responseData) {
+		this.responseData = responseData;
+	}
+
+	public void addResponseData(String name, String response) {
+		List<String> responseList = responseData.get(name);
+		if (responseList == null) {
+			responseList = new LinkedList<String>();
+			responseData.put(name.toLowerCase(), responseList);
+		}
+		responseList.add(response);
+	}
 }
diff --git a/org.eclipse.mylyn.bugzilla.ui/plugin.xml b/org.eclipse.mylyn.bugzilla.ui/plugin.xml
index 0cc9494..ee753ed 100644
--- a/org.eclipse.mylyn.bugzilla.ui/plugin.xml
+++ b/org.eclipse.mylyn.bugzilla.ui/plugin.xml
@@ -60,6 +60,8 @@
 		<languageAttribute command="submitted" 					response="Submitted"/>
 		<languageAttribute command="submitted" 					response="posted"/>
 		<languageAttribute command="suspicious_action" 			response="Suspicious action"/>
+		<languageAttribute command="error_confirm_match"		response="confirm match"/> 
+        <languageAttribute command="error_match_failed"			response="match failed"/>
       </language> 
       -->
       <language 
@@ -84,6 +86,8 @@
 			<languageAttribute command="submitted" 					response="Submitted"/>
 			<languageAttribute command="submitted" 					response="posted"/>
 	     	<languageAttribute command="suspicious_action"			response="Suspicious action"/> 
+			<languageAttribute command="error_confirm_match"		response="confirm match"/> 
+        	<languageAttribute command="error_match_failed"			response="match failed"/>
        </language> 
    </extension>    
   
diff --git a/org.eclipse.mylyn.bugzilla.ui/src/org/eclipse/mylyn/internal/bugzilla/ui/editor/BugzillaResponseDetailDialog.java b/org.eclipse.mylyn.bugzilla.ui/src/org/eclipse/mylyn/internal/bugzilla/ui/editor/BugzillaResponseDetailDialog.java
index 1ddeb9c..d793622 100644
--- a/org.eclipse.mylyn.bugzilla.ui/src/org/eclipse/mylyn/internal/bugzilla/ui/editor/BugzillaResponseDetailDialog.java
+++ b/org.eclipse.mylyn.bugzilla.ui/src/org/eclipse/mylyn/internal/bugzilla/ui/editor/BugzillaResponseDetailDialog.java
@@ -11,12 +11,7 @@
 
 package org.eclipse.mylyn.internal.bugzilla.ui.editor;
 
-import java.util.List;
-import java.util.Map;
-
 import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaRepositoryResponse;
-import org.eclipse.osgi.util.NLS;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
@@ -27,18 +22,20 @@
 
 public class BugzillaResponseDetailDialog extends Dialog {
 
-	private final BugzillaRepositoryResponse response;
+	private final String messageText;
 
-	public BugzillaResponseDetailDialog(Shell parentShell, BugzillaRepositoryResponse response) {
+	private final String titleText;
+
+	public BugzillaResponseDetailDialog(Shell parentShell, String titleText, String messageText) {
 		super(parentShell);
 		setShellStyle(getShellStyle() | SWT.RESIZE);
-		this.response = response;
+		this.messageText = messageText;
+		this.titleText = titleText;
 	}
 
 	@Override
 	protected Control createDialogArea(Composite parent) {
-		getShell().setText(Messages.BugzillaResponseDetailDialog_Titel);
-
+		getShell().setText(titleText);
 		Composite composite = new Composite(parent, SWT.NONE);
 		composite.setLayout(new GridLayout());
 		GridData gd = new GridData(GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL | GridData.FILL_BOTH);
@@ -50,24 +47,7 @@
 		gd.widthHint = 300;
 		text.setLayoutData(gd);
 		text.setEditable(false);
-
-		String mes = ""; //$NON-NLS-1$
-		for (String iterable_map : response.getResponseData().keySet()) {
-			if (mes.length() > 0) {
-				mes += "\n"; //$NON-NLS-1$
-			}
-			mes += NLS.bind(Messages.BugzillaResponseDetailDialog_Bug_Line, iterable_map);
-			Map<String, List<String>> responseMap = response.getResponseData().get(iterable_map);
-			for (String iterable_list : responseMap.keySet()) {
-				mes += NLS.bind(Messages.BugzillaResponseDetailDialog_Action_Line, iterable_list);
-				List<String> responseList = responseMap.get(iterable_list);
-				for (String string : responseList) {
-					mes += NLS.bind(Messages.BugzillaResponseDetailDialog_Email_Line, string);
-				}
-			}
-
-		}
-		text.setText(mes);
+		text.setText(messageText);
 		parent.pack();
 		applyDialogFont(composite);
 		return composite;
diff --git a/org.eclipse.mylyn.bugzilla.ui/src/org/eclipse/mylyn/internal/bugzilla/ui/editor/BugzillaTaskEditorPage.java b/org.eclipse.mylyn.bugzilla.ui/src/org/eclipse/mylyn/internal/bugzilla/ui/editor/BugzillaTaskEditorPage.java
index 5ac2e55..e43234d 100644
--- a/org.eclipse.mylyn.bugzilla.ui/src/org/eclipse/mylyn/internal/bugzilla/ui/editor/BugzillaTaskEditorPage.java
+++ b/org.eclipse.mylyn.bugzilla.ui/src/org/eclipse/mylyn/internal/bugzilla/ui/editor/BugzillaTaskEditorPage.java
@@ -11,6 +11,8 @@
 
 package org.eclipse.mylyn.internal.bugzilla.ui.editor;
 
+import java.text.MessageFormat;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
@@ -21,6 +23,9 @@
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.fieldassist.ControlDecoration;
+import org.eclipse.jface.fieldassist.FieldDecoration;
+import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
 import org.eclipse.mylyn.commons.core.StatusHandler;
 import org.eclipse.mylyn.commons.net.AuthenticationCredentials;
 import org.eclipse.mylyn.commons.net.AuthenticationType;
@@ -30,12 +35,15 @@
 import org.eclipse.mylyn.internal.bugzilla.core.BugzillaOperation;
 import org.eclipse.mylyn.internal.bugzilla.core.BugzillaRepositoryConnector;
 import org.eclipse.mylyn.internal.bugzilla.core.BugzillaRepositoryResponse;
+import org.eclipse.mylyn.internal.bugzilla.core.BugzillaStatus;
 import org.eclipse.mylyn.internal.bugzilla.core.BugzillaTaskDataHandler;
 import org.eclipse.mylyn.internal.bugzilla.core.BugzillaVersion;
 import org.eclipse.mylyn.internal.bugzilla.core.IBugzillaConstants;
 import org.eclipse.mylyn.internal.bugzilla.core.RepositoryConfiguration;
 import org.eclipse.mylyn.internal.bugzilla.ui.BugzillaUiPlugin;
 import org.eclipse.mylyn.internal.provisional.commons.ui.WorkbenchUtil;
+import org.eclipse.mylyn.internal.tasks.ui.PersonProposalProvider;
+import org.eclipse.mylyn.internal.tasks.ui.editors.PersonAttributeEditor;
 import org.eclipse.mylyn.internal.tasks.ui.editors.TaskEditorActionPart;
 import org.eclipse.mylyn.tasks.core.RepositoryResponse;
 import org.eclipse.mylyn.tasks.core.RepositoryStatus;
@@ -57,9 +65,17 @@
 import org.eclipse.mylyn.tasks.ui.editors.TaskEditor;
 import org.eclipse.mylyn.tasks.ui.editors.TaskEditorInput;
 import org.eclipse.mylyn.tasks.ui.editors.TaskEditorPartDescriptor;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.widgets.Control;
 import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.fieldassist.ContentAssistCommandAdapter;
 import org.eclipse.ui.forms.events.HyperlinkAdapter;
 import org.eclipse.ui.forms.events.HyperlinkEvent;
+import org.eclipse.ui.handlers.IHandlerActivation;
+import org.eclipse.ui.keys.IBindingService;
 
 /**
  * @author Rob Elves
@@ -77,6 +93,12 @@
 
 	private TaskDataModelListener productListener;
 
+	private final List<ControlDecoration> errorDecorations = new ArrayList<ControlDecoration>();
+
+	private final List<PersonAttributeEditor> editorsWithError = new ArrayList<PersonAttributeEditor>(3);
+
+	private IHandlerActivation contentAssistHandlerActivation;
+
 	public BugzillaTaskEditorPage(TaskEditor editor) {
 		this(editor, BugzillaCorePlugin.CONNECTOR_KIND);
 	}
@@ -328,6 +350,14 @@
 				attrToken.setValue(tokenString);
 			}
 		}
+		//		for (ControlDecoration decoration : errorDecorations) {
+		//			decoration.hide();
+		//			decoration.dispose();
+		//		}
+		//		errorDecorations.clear();
+		//		for (PersonAttributeEditor editor : editorsWithError) {
+		//			editor.getContentAssistCommandAdapter().setEnabled(true);
+		//		}
 		if (!checkCanSubmit(IMessageProvider.ERROR)) {
 			return;
 		}
@@ -497,7 +527,15 @@
 
 	@Override
 	protected void handleTaskSubmitted(SubmitJobEvent event) {
-		if (event.getJob().getResponse() != null && event.getJob().getResponse() instanceof BugzillaRepositoryResponse) {
+		if (event.getJob().getStatus() != null) {
+			switch (event.getJob().getStatus().getCode()) {
+			case BugzillaStatus.ERROR_CONFIRM_MATCH:
+			case BugzillaStatus.ERROR_MATCH_FAILED:
+				presentErrorToUI((BugzillaStatus) event.getJob().getStatus());
+				break;
+			}
+		} else if (event.getJob().getResponse() != null
+				&& event.getJob().getResponse() instanceof BugzillaRepositoryResponse) {
 			final RepositoryResponse response = event.getJob().getResponse();
 			if (response instanceof BugzillaRepositoryResponse) {
 				final BugzillaRepositoryResponse bugzillaResponse = (BugzillaRepositoryResponse) response;
@@ -506,8 +544,27 @@
 							IMessageProvider.INFORMATION, new HyperlinkAdapter() {
 								@Override
 								public void linkActivated(HyperlinkEvent event) {
+
+									String message = ""; //$NON-NLS-1$
+									for (String iterable_map : bugzillaResponse.getResponseData().keySet()) {
+										if (message.length() > 0) {
+											message += "\n"; //$NON-NLS-1$
+										}
+										message += NLS.bind(Messages.BugzillaTaskEditorPage_Bug_Line, iterable_map);
+										Map<String, List<String>> responseMap = bugzillaResponse.getResponseData().get(
+												iterable_map);
+										for (String iterable_list : responseMap.keySet()) {
+											message += NLS.bind(Messages.BugzillaTaskEditorPage_Action_Line,
+													iterable_list);
+											List<String> responseList = responseMap.get(iterable_list);
+											for (String string : responseList) {
+												message += NLS.bind(Messages.BugzillaTaskEditorPage_Email_Line, string);
+											}
+										}
+									}
 									BugzillaResponseDetailDialog dialog = new BugzillaResponseDetailDialog(
-											WorkbenchUtil.getShell(), bugzillaResponse);
+											WorkbenchUtil.getShell(), Messages.BugzillaTaskEditorPage_Response_Titel,
+											message);
 									dialog.open();
 								}
 							});
@@ -567,4 +624,112 @@
 		}
 		return true;
 	}
+
+	private void presentErrorToUI(BugzillaStatus bugzillaStatus) {
+		String resultString;
+		String resultDetail = ""; //$NON-NLS-1$
+		int count = 0;
+		String fieldString = ""; //$NON-NLS-1$
+		Map<String, List<String>> response = bugzillaStatus.getResponseData();
+		FieldDecorationRegistry registry = FieldDecorationRegistry.getDefault();
+		FieldDecoration fieldDecoration = registry.getFieldDecoration(FieldDecorationRegistry.DEC_ERROR);
+
+		for (String string : response.keySet()) {
+			TaskAttribute attribute = getModel().getTaskData().getRoot().getAttribute(string);
+			if (count++ > 0) {
+				fieldString += MessageFormat.format(Messages.BugzillaTaskEditorPage_Error_Label_N,
+						attribute.getMetaData().getLabel());
+			} else {
+				fieldString += MessageFormat.format(Messages.BugzillaTaskEditorPage_Error_Label_1,
+						attribute.getMetaData().getLabel());
+			}
+			resultDetail += attribute.getMetaData().getLabel() + "\n"; //$NON-NLS-1$
+
+			AbstractAttributeEditor editor = getEditorForAttribute(attribute);
+			if (editor != null) {
+				Map<String, String> newPersonProposalMap = new HashMap<String, String>();
+				String decorationText = ""; //$NON-NLS-1$
+				for (String responseValue : response.get(string)) {
+					if (responseValue.startsWith("#msg#")) { //$NON-NLS-1$
+						decorationText += responseValue.substring(5);
+					} else {
+						newPersonProposalMap.put(responseValue, responseValue);
+					}
+					resultDetail += "\t\t" //$NON-NLS-1$
+							+ (responseValue.startsWith("#msg#") ? responseValue.substring(5) : responseValue) + "\n"; //$NON-NLS-1$ //$NON-NLS-2$
+				}
+
+				final Control control = editor.getControl();
+
+				ControlDecoration decoration = new ControlDecoration(control, SWT.LEFT | SWT.TOP);
+				decoration.setImage(fieldDecoration.getImage());
+				IBindingService bindingService = (IBindingService) PlatformUI.getWorkbench().getService(
+						IBindingService.class);
+				if (!decorationText.equals("")) { //$NON-NLS-1$
+					decoration.setDescriptionText(decorationText);
+					errorDecorations.add(decoration);
+				} else {
+					decoration.setDescriptionText(NLS.bind(
+							Messages.BugzillaTaskEditorPage_Content_Assist_for_Error_Available,
+							bindingService.getBestActiveBindingFormattedFor(ContentAssistCommandAdapter.CONTENT_PROPOSAL_COMMAND)));
+					errorDecorations.add(decoration);
+
+					PersonAttributeEditor personEditor = ((PersonAttributeEditor) editor);
+					final PersonProposalProvider personProposalProvider = (PersonProposalProvider) personEditor.getContentAssistCommandAdapter()
+							.getContentProposalProvider();
+					personProposalProvider.setErrorProposals(newPersonProposalMap);
+					editorsWithError.add(personEditor);
+					personEditor.getText().addKeyListener(new KeyListener() {
+
+						public void keyReleased(KeyEvent e) {
+							// ignore
+						}
+
+						public void keyPressed(KeyEvent e) {
+							if (e.keyCode != SWT.ARROW_LEFT && e.keyCode != SWT.ARROW_RIGHT && e.keyCode != SWT.CTRL
+									&& !((e.keyCode == 32) && ((e.stateMask & SWT.CTRL) == SWT.CTRL))) {
+								for (ControlDecoration error : errorDecorations) {
+									if (error.getControl() == control) {
+										error.hide();
+										errorDecorations.remove(error);
+										error.dispose();
+										break;
+									}
+								}
+								personProposalProvider.setErrorProposals(null);
+							}
+						}
+					});
+				}
+
+			}
+		}
+		final String codeString;
+		switch (bugzillaStatus.getCode()) {
+		case BugzillaStatus.ERROR_CONFIRM_MATCH:
+			codeString = Messages.BugzillaTaskEditorPage_Confirm;
+			break;
+		case BugzillaStatus.ERROR_MATCH_FAILED:
+			codeString = Messages.BugzillaTaskEditorPage_Error;
+			break;
+		default:
+			codeString = ""; //$NON-NLS-1$
+			break;
+		}
+		if (count > 1) {
+			resultString = MessageFormat.format(Messages.BugzillaTaskEditorPage_Message_more, codeString, fieldString);
+		} else {
+			resultString = MessageFormat.format(Messages.BugzillaTaskEditorPage_Message_one, codeString, fieldString);
+		}
+
+		final String resultDetailString = resultDetail;
+		getTaskEditor().setMessage(resultString, IMessageProvider.ERROR, new HyperlinkAdapter() {
+			@Override
+			public void linkActivated(HyperlinkEvent event) {
+				BugzillaResponseDetailDialog dialog = new BugzillaResponseDetailDialog(WorkbenchUtil.getShell(),
+						codeString + Messages.BugzillaTaskEditorPage_match_Detail, resultDetailString);
+				dialog.open();
+			}
+		});
+	}
 }
diff --git a/org.eclipse.mylyn.bugzilla.ui/src/org/eclipse/mylyn/internal/bugzilla/ui/editor/Messages.java b/org.eclipse.mylyn.bugzilla.ui/src/org/eclipse/mylyn/internal/bugzilla/ui/editor/Messages.java
index c4264c7..08aea77 100644
--- a/org.eclipse.mylyn.bugzilla.ui/src/org/eclipse/mylyn/internal/bugzilla/ui/editor/Messages.java
+++ b/org.eclipse.mylyn.bugzilla.ui/src/org/eclipse/mylyn/internal/bugzilla/ui/editor/Messages.java
@@ -51,13 +51,13 @@
 
 	public static String BugzillaPlanningEditorPart_Team_Planning;
 
-	public static String BugzillaResponseDetailDialog_Titel;
+	public static String BugzillaTaskEditorPage_Response_Titel;
 
-	public static String BugzillaResponseDetailDialog_Bug_Line;
+	public static String BugzillaTaskEditorPage_Bug_Line;
 
-	public static String BugzillaResponseDetailDialog_Action_Line;
+	public static String BugzillaTaskEditorPage_Action_Line;
 
-	public static String BugzillaResponseDetailDialog_Email_Line;
+	public static String BugzillaTaskEditorPage_Email_Line;
 
 	public static String BugzillaTaskEditorCommentPart_privateComment;
 
@@ -71,6 +71,30 @@
 
 	public static String BugzillaTaskEditorPage_Changes_Submitted_Message;
 
+	public static String BugzillaTaskEditorPage_Confirm;
+
+	public static String BugzillaTaskEditorPage_Content_Assist_for_Error_Available;
+
+	public static String BugzillaTaskEditorPage_Error;
+
+	public static String BugzillaTaskEditorPage_Error_Label_1;
+
+	public static String BugzillaTaskEditorPage_Error_Label_N;
+
+	public static String BugzillaTaskEditorPage_Legal_Value_1;
+
+	public static String BugzillaTaskEditorPage_Legal_Value_N;
+
+	public static String BugzillaTaskEditorPage_Legal_Values_More;
+
+	public static String BugzillaTaskEditorPage_Legal_Values_One;
+
+	public static String BugzillaTaskEditorPage_match_Detail;
+
+	public static String BugzillaTaskEditorPage_Message_more;
+
+	public static String BugzillaTaskEditorPage_Message_one;
+
 	public static String BugzillaTaskEditorPage_Please_enter_a_description_before_submitting;
 
 	public static String BugzillaTaskEditorPage_Please_enter_a_short_summary_before_submitting;
diff --git a/org.eclipse.mylyn.bugzilla.ui/src/org/eclipse/mylyn/internal/bugzilla/ui/editor/messages.properties b/org.eclipse.mylyn.bugzilla.ui/src/org/eclipse/mylyn/internal/bugzilla/ui/editor/messages.properties
index ec01b9b..16b53dd 100644
--- a/org.eclipse.mylyn.bugzilla.ui/src/org/eclipse/mylyn/internal/bugzilla/ui/editor/messages.properties
+++ b/org.eclipse.mylyn.bugzilla.ui/src/org/eclipse/mylyn/internal/bugzilla/ui/editor/messages.properties
@@ -23,16 +23,28 @@
 BugzillaPlanningEditorPart_Current_Estimate=Current Estimate:
 BugzillaPlanningEditorPart_Team_Planning=Team Planning
 
-BugzillaResponseDetailDialog_Titel=submitted Changes Details
-BugzillaResponseDetailDialog_Bug_Line={0}\n
-BugzillaResponseDetailDialog_Action_Line=\ \ \ \ \ \ \ \ {0}\n
-BugzillaResponseDetailDialog_Email_Line=\ \ \ \ \ \ \ \  \ \ \ \ {0}\n
+BugzillaTaskEditorPage_Response_Titel=submitted Changes Details
+BugzillaTaskEditorPage_Bug_Line={0}\n
+BugzillaTaskEditorPage_Action_Line=\ \ \ \ \ \ \ \ {0}\n
+BugzillaTaskEditorPage_Email_Line=\ \ \ \ \ \ \ \  \ \ \ \ {0}\n
 BugzillaTaskEditorCommentPart_privateComment=private Comment
 BugzillaTaskEditorCommentPart_publicComment=public Comment
 BugzillaTaskEditorNewCommentPart_privateComment=private Comment
 BugzillaTaskEditorNewCommentPart_publicComment=public Comment
 BugzillaTaskEditorPage_Anonymous_can_not_submit_Tasks=Anonymous can not submit Tasks\!
 BugzillaTaskEditorPage_Changes_Submitted_Message=Changes submitted
+BugzillaTaskEditorPage_Confirm=Confirm
+BugzillaTaskEditorPage_Content_Assist_for_Error_Available=Content Assist for Error Available ({0})
+BugzillaTaskEditorPage_Error=Error
+BugzillaTaskEditorPage_Error_Label_1="{0}"
+BugzillaTaskEditorPage_Error_Label_N=, "{0}"
+BugzillaTaskEditorPage_Legal_Value_1={0}
+BugzillaTaskEditorPage_Legal_Value_N=, \n{0}
+BugzillaTaskEditorPage_Legal_Values_More=legal values are:\n{0}
+BugzillaTaskEditorPage_Legal_Values_One=legal value is\n{0}
+BugzillaTaskEditorPage_match_Detail=\ match Detail
+BugzillaTaskEditorPage_Message_more={0} match for fields {1}
+BugzillaTaskEditorPage_Message_one={0} match for field {1}
 BugzillaTaskEditorPage_Please_enter_a_description_before_submitting=Please enter a description before submitting
 BugzillaTaskEditorPage_Please_enter_a_short_summary_before_submitting=Please enter a short summary before submitting
 BugzillaTaskEditorPage_Please_select_a_component_before_submitting=Please select a component before submitting
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/PersonProposalProvider.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/PersonProposalProvider.java
index c3bbd53..5f352d3 100644
--- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/PersonProposalProvider.java
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/PersonProposalProvider.java
@@ -61,7 +61,9 @@
 
 	private TaskData currentTaskData;
 
-	private final Map<String, String> proposals;
+	private Map<String, String> proposals;
+
+	private Map<String, String> errorProposals = null;
 
 	public PersonProposalProvider(AbstractTask task, TaskData taskData) {
 		this(task, taskData, new HashMap<String, String>(0));
@@ -116,19 +118,36 @@
 
 		// retrieve subset of the tree set using key range
 		SortedSet<String> addressSet = getAddressSet();
-		if (!searchText.equals("")) { //$NON-NLS-1$
-			// lower bounds
-			searchText = searchText.toLowerCase();
+		if (errorProposals == null || !errorProposals.isEmpty()) {
+			if (!searchText.equals("")) { //$NON-NLS-1$
+				// lower bounds
+				searchText = searchText.toLowerCase();
 
-			// compute the upper bound
-			char[] nextWord = searchText.toCharArray();
-			nextWord[searchText.length() - 1]++;
+				// compute the upper bound
+				char[] nextWord = searchText.toCharArray();
+				nextWord[searchText.length() - 1]++;
 
-			// filter matching keys 
-			addressSet = new TreeSet<String>(addressSet.subSet(searchText, new String(nextWord)));
+				// filter matching keys 
+				addressSet = new TreeSet<String>(addressSet.subSet(searchText, new String(nextWord)));
 
-			// add matching keys based on pretty names 
-			addMatchingProposalsByPrettyName(addressSet, searchText);
+				// add matching keys based on pretty names 
+				addMatchingProposalsByPrettyName(addressSet, searchText);
+			}
+		}
+		if (repositoryUrl != null && connectorKind != null) {
+			TaskRepository repository = TasksUi.getRepositoryManager().getRepository(connectorKind, repositoryUrl);
+
+			if (repository != null) {
+				AuthenticationCredentials credentials = repository.getCredentials(AuthenticationType.REPOSITORY);
+				if (credentials != null && credentials.getUserName().length() > 0) {
+					currentUser = credentials.getUserName();
+				}
+			}
+		}
+		if (errorProposals != null && !errorProposals.isEmpty()) {
+			for (String proposal : errorProposals.keySet()) {
+				addAddress(addressSet, proposal);
+			}
 		}
 
 		IContentProposal[] result = new IContentProposal[addressSet.size()];
@@ -227,16 +246,6 @@
 				tasks.add(currentTask);
 			}
 
-			TaskRepository repository = TasksUi.getRepositoryManager().getRepository(connectorKind, repositoryUrl);
-
-			if (repository != null) {
-				AuthenticationCredentials credentials = repository.getCredentials(AuthenticationType.REPOSITORY);
-				if (credentials != null && credentials.getUserName().length() > 0) {
-					currentUser = credentials.getUserName();
-					addressSet.add(currentUser);
-				}
-			}
-
 			Collection<AbstractTask> allTasks = TasksUiPlugin.getTaskList().getAllTasks();
 			for (AbstractTask task : allTasks) {
 				if (repositoryUrl.equals(task.getRepositoryUrl())) {
@@ -311,4 +320,20 @@
 		}
 	}
 
+	public Map<String, String> getProposals() {
+		return proposals;
+	}
+
+	public void setProposals(Map<String, String> proposals) {
+		this.proposals = proposals;
+	}
+
+	public Map<String, String> getErrorProposals() {
+		return errorProposals;
+	}
+
+	public void setErrorProposals(Map<String, String> errorProposals) {
+		this.errorProposals = errorProposals;
+	}
+
 }
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/PersonAttributeEditor.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/PersonAttributeEditor.java
index 4f02094..e62217b 100644
--- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/PersonAttributeEditor.java
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/PersonAttributeEditor.java
@@ -26,6 +26,7 @@
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.fieldassist.ContentAssistCommandAdapter;
 import org.eclipse.ui.forms.events.HyperlinkAdapter;
 import org.eclipse.ui.forms.events.HyperlinkEvent;
 import org.eclipse.ui.forms.widgets.FormToolkit;
@@ -35,6 +36,7 @@
  * @author Steffen Pingel
  */
 public class PersonAttributeEditor extends TextAttributeEditor {
+	private ContentAssistCommandAdapter contentAssistCommandAdapter = null;
 
 	public PersonAttributeEditor(TaskDataModel manager, TaskAttribute taskAttribute) {
 		super(manager, taskAttribute);
@@ -140,4 +142,12 @@
 			getText().setBackground(color);
 		}
 	}
+
+	public ContentAssistCommandAdapter getContentAssistCommandAdapter() {
+		return contentAssistCommandAdapter;
+	}
+
+	public void setContentAssistCommandAdapter(ContentAssistCommandAdapter contentAssistCommandAdapter) {
+		this.contentAssistCommandAdapter = contentAssistCommandAdapter;
+	}
 }
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/editors/AttributeEditorToolkit.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/editors/AttributeEditorToolkit.java
index c60a23f..68ff9ad 100644
--- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/editors/AttributeEditorToolkit.java
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/editors/AttributeEditorToolkit.java
@@ -99,6 +99,9 @@
 							ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS, new char[0], true);
 					adapter.setLabelProvider(labelPropsalProvider);
 					adapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE);
+					if (editor instanceof PersonAttributeEditor) {
+						((PersonAttributeEditor) editor).setContentAssistCommandAdapter(adapter);
+					}
 				}
 			}
 		} else if (editor instanceof RichTextAttributeEditor) {