/*******************************************************************************
 * Copyright (c) 2004, 2015 Tasktop Technologies 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:
 *     Tasktop Technologies - initial API and implementation
 *******************************************************************************/

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;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.runtime.CoreException;
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.workbench.WorkbenchUtil;
import org.eclipse.mylyn.internal.bugzilla.core.BugzillaAttribute;
import org.eclipse.mylyn.internal.bugzilla.core.BugzillaCorePlugin;
import org.eclipse.mylyn.internal.bugzilla.core.BugzillaCustomField;
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.BugzillaUserMatchResponse;
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.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;
import org.eclipse.mylyn.tasks.core.TaskRepository;
import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
import org.eclipse.mylyn.tasks.core.data.TaskAttributeMetaData;
import org.eclipse.mylyn.tasks.core.data.TaskData;
import org.eclipse.mylyn.tasks.core.data.TaskDataModel;
import org.eclipse.mylyn.tasks.core.data.TaskDataModelEvent;
import org.eclipse.mylyn.tasks.core.data.TaskDataModelListener;
import org.eclipse.mylyn.tasks.core.sync.SubmitJobEvent;
import org.eclipse.mylyn.tasks.ui.TasksUi;
import org.eclipse.mylyn.tasks.ui.TasksUiUtil;
import org.eclipse.mylyn.tasks.ui.editors.AbstractAttributeEditor;
import org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorPage;
import org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorPart;
import org.eclipse.mylyn.tasks.ui.editors.AttributeEditorFactory;
import org.eclipse.mylyn.tasks.ui.editors.LayoutHint;
import org.eclipse.mylyn.tasks.ui.editors.LayoutHint.ColumnSpan;
import org.eclipse.mylyn.tasks.ui.editors.LayoutHint.RowSpan;
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.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
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.forms.widgets.ExpandableComposite;
import org.eclipse.ui.keys.IBindingService;

/**
 * @author Rob Elves
 * @author Frank Becker
 * @since 3.0
 */
public class BugzillaTaskEditorPage extends AbstractTaskEditorPage {

	public static final String ID_PART_BUGZILLA_PLANNING = "org.eclipse.mylyn.bugzilla.ui.editors.part.planning"; //$NON-NLS-1$

	public static final String ID_PART_BUGZILLA_FLAGS = "org.eclipse.mylyn.bugzilla.ui.editors.part.flags"; //$NON-NLS-1$

	public static final String PATH_FLAGS = "flags"; //$NON-NLS-1$

	private final Map<TaskAttribute, AbstractAttributeEditor> attributeEditorMap;

	private TaskDataModelListener productListener;

	private final List<ControlDecoration> errorDecorations = new ArrayList<ControlDecoration>();

	private final List<PersonAttributeEditor> editorsWithError = new ArrayList<PersonAttributeEditor>(3);

	public BugzillaTaskEditorPage(TaskEditor editor) {
		this(editor, BugzillaCorePlugin.CONNECTOR_KIND);
	}

	/**
	 * Call this constructor if extending the Bugzilla connector
	 *
	 * @param editor
	 * @param connectorKind
	 */
	public BugzillaTaskEditorPage(TaskEditor editor, String connectorKind) {
		super(editor, connectorKind);
		this.attributeEditorMap = new HashMap<TaskAttribute, AbstractAttributeEditor>();
		setNeedsPrivateSection(true);
		setNeedsSubmitButton(true);
	}

	@Override
	protected Set<TaskEditorPartDescriptor> createPartDescriptors() {
		Set<TaskEditorPartDescriptor> descriptors = super.createPartDescriptors();
		boolean hasPartComments = false;
		boolean hasPartNewComment = false;
		boolean hasPartDescription = false;
		// remove unnecessary default editor parts
		for (TaskEditorPartDescriptor taskEditorPartDescriptor : descriptors) {
			if (taskEditorPartDescriptor.getId().equals(ID_PART_PEOPLE)) {
				descriptors.remove(taskEditorPartDescriptor);
				break;
			}
		}
		for (TaskEditorPartDescriptor taskEditorPartDescriptor : descriptors) {
			if (taskEditorPartDescriptor.getId().equals(ID_PART_COMMENTS)) {
				descriptors.remove(taskEditorPartDescriptor);
				hasPartComments = true;
				break;
			}
		}
		for (TaskEditorPartDescriptor taskEditorPartDescriptor : descriptors) {
			if (taskEditorPartDescriptor.getId().equals(ID_PART_NEW_COMMENT)) {
				descriptors.remove(taskEditorPartDescriptor);
				hasPartNewComment = true;
				break;
			}
		}
		for (TaskEditorPartDescriptor taskEditorPartDescriptor : descriptors) {
			if (taskEditorPartDescriptor.getId().equals(ID_PART_DESCRIPTION)) {
				descriptors.remove(taskEditorPartDescriptor);
				hasPartDescription = true;
				break;
			}
		}

		// Add Bugzilla Planning part
		try {
			TaskData data = TasksUi.getTaskDataManager().getTaskData(getTask());
			if (data != null) {
				// Add Bugzilla Flag part
				Map<String, TaskAttribute> attributes = data.getRoot().getAttributes();
				for (TaskAttribute attribute : attributes.values()) {
					if (BugzillaAttribute.KIND_FLAG.equals(attribute.getMetaData().getKind())) {
						descriptors.add(new TaskEditorPartDescriptor(ID_PART_BUGZILLA_FLAGS) {
							@Override
							public AbstractTaskEditorPart createPart() {
								return new BugzillaFlagPart();
							}
						}.setPath(ID_PART_ATTRIBUTES + "/" + PATH_FLAGS)); //$NON-NLS-1$
						break;
					}
				}

				TaskAttribute attrEstimatedTime = data.getRoot()
						.getMappedAttribute(BugzillaAttribute.ESTIMATED_TIME.getKey());
				if (attrEstimatedTime != null) {
					descriptors.add(new TaskEditorPartDescriptor(ID_PART_BUGZILLA_PLANNING) {
						@Override
						public AbstractTaskEditorPart createPart() {
							return new BugzillaPlanningEditorPart();
						}
					}.setPath(ID_PART_ATTRIBUTES + "/" + PATH_PLANNING)); //$NON-NLS-1$
				}
			}
			if (hasPartDescription) {
				descriptors.add(new TaskEditorPartDescriptor(ID_PART_DESCRIPTION) {
					@Override
					public AbstractTaskEditorPart createPart() {
						BugzillaTaskEditorDescriptionPart part = new BugzillaTaskEditorDescriptionPart();
						if (getModel().getTaskData().isNew()) {
							part.setExpandVertically(true);
							part.setSectionStyle(ExpandableComposite.TITLE_BAR | ExpandableComposite.EXPANDED);
						}
						return part;
					}
				}.setPath(PATH_COMMENTS));

			}
			if (hasPartComments) {
				descriptors.add(new TaskEditorPartDescriptor(ID_PART_COMMENTS) {
					@Override
					public AbstractTaskEditorPart createPart() {
						return new BugzillaTaskEditorCommentPart();
					}
				}.setPath(PATH_COMMENTS));

			}
		} catch (CoreException e) {
			// ignore
		}

		if (hasPartNewComment) {
			// Add the updated Bugzilla new comment part
			descriptors.add(new TaskEditorPartDescriptor(ID_PART_NEW_COMMENT) {
				@Override
				public AbstractTaskEditorPart createPart() {
					return new BugzillaTaskEditorNewCommentPart();
				}
			}.setPath(PATH_COMMENTS));
		}
		// Add the updated Bugzilla people part
		descriptors.add(new TaskEditorPartDescriptor(ID_PART_PEOPLE) {
			@Override
			public AbstractTaskEditorPart createPart() {
				return new BugzillaPeoplePart();
			}
		}.setPath(PATH_PEOPLE));

		return descriptors;
	}

	@Override
	protected AttributeEditorFactory createAttributeEditorFactory() {
		AttributeEditorFactory factory = new AttributeEditorFactory(getModel(), getTaskRepository(), getEditorSite()) {
			@Override
			public AbstractAttributeEditor createEditor(String type, final TaskAttribute taskAttribute) {
				AbstractAttributeEditor editor;
				if (IBugzillaConstants.EDITOR_TYPE_KEYWORDS.equals(type)) {
					editor = new BugzillaKeywordAttributeEditor(getModel(), taskAttribute);
				} else if (IBugzillaConstants.EDITOR_TYPE_REMOVECC.equals(type)) {
					editor = new BugzillaCcAttributeEditor(getModel(), taskAttribute);
				} else if (IBugzillaConstants.EDITOR_TYPE_VOTES.equals(type)) {
					editor = new BugzillaVotesEditor(getModel(), taskAttribute);
				} else if (IBugzillaConstants.EDITOR_TYPE_FLAG.equals(type)) {
					editor = new FlagAttributeEditor(getModel(), taskAttribute);
				} else if (IBugzillaConstants.EDITOR_TYPE_SEEALSO.equals(type)) {
					editor = new BugzillaSeeAlsoAttributeEditor(getModel(), taskAttribute);
				} else {
					editor = super.createEditor(type, taskAttribute);
					if (TaskAttribute.TYPE_BOOLEAN.equals(type)) {
						editor.setDecorationEnabled(false);
					}
				}

				if (editor != null && taskAttribute.getId().startsWith(BugzillaCustomField.CUSTOM_FIELD_PREFIX)) {
					editor.setLayoutHint(new LayoutHint(editor.getLayoutHint()) {

						@Override
						public int getPriority() {
							return super.getPriority() * 10;
						}
					});
				}

				TaskAttributeMetaData properties = taskAttribute.getMetaData();
				if (editor != null && IBugzillaConstants.EDITOR_TYPE_FLAG.equals(properties.getType())) {
					editor.setLayoutHint(new LayoutHint(editor.getLayoutHint()) {

						@Override
						public int getPriority() {
							return super.getPriority() * 5;
						}
					});
				}
				if (editor != null && BugzillaAttribute.NEWCC.getKey().equals(taskAttribute.getId())) {
					editor.setLayoutHint(new LayoutHint(RowSpan.SINGLE, ColumnSpan.SINGLE));
				}
				BugzillaTaskEditorPage.this.addToAttributeEditorMap(taskAttribute, editor);
				return editor;
			}
		};
		return factory;
	}

	@Override
	public void doSubmit() {
		TaskAttribute summaryAttribute = getModel().getTaskData().getRoot().getMappedAttribute(TaskAttribute.SUMMARY);
		if (summaryAttribute != null && summaryAttribute.getValue().length() == 0) {
			getTaskEditor().setMessage(Messages.BugzillaTaskEditorPage_Please_enter_a_short_summary_before_submitting,
					IMessageProvider.ERROR);
			AbstractTaskEditorPart part = getPart(ID_PART_SUMMARY);
			if (part != null) {
				part.setFocus();
			}
			return;
		}

		TaskAttribute componentAttribute = getModel().getTaskData()
				.getRoot()
				.getMappedAttribute(BugzillaAttribute.COMPONENT.getKey());
		if (componentAttribute != null && componentAttribute.getValue().length() == 0) {
			getTaskEditor().setMessage(Messages.BugzillaTaskEditorPage_Please_select_a_component_before_submitting,
					IMessageProvider.ERROR);
			AbstractTaskEditorPart part = getPart(ID_PART_ATTRIBUTES);
			if (part != null) {
				part.setFocus();
			}
			return;
		}

		TaskAttribute descriptionAttribute = getModel().getTaskData()
				.getRoot()
				.getMappedAttribute(TaskAttribute.DESCRIPTION);
		if (descriptionAttribute != null && descriptionAttribute.getValue().length() == 0
				&& getModel().getTaskData().isNew()) {
			getTaskEditor().setMessage(Messages.BugzillaTaskEditorPage_Please_enter_a_description_before_submitting,
					IMessageProvider.ERROR);
			AbstractTaskEditorPart descriptionPart = getPart(ID_PART_DESCRIPTION);
			if (descriptionPart != null) {
				descriptionPart.setFocus();
			}
			return;
		}
		TaskAttribute targetMilestoneAttribute = getModel().getTaskData()
				.getRoot()
				.getMappedAttribute(BugzillaAttribute.TARGET_MILESTONE.getKey());
		if (targetMilestoneAttribute != null && targetMilestoneAttribute.getValue().length() == 0
				&& getModel().getTaskData().isNew()) {
			getTaskEditor().setMessage(
					Messages.BugzillaTaskEditorPage_Please_enter_a_target_milestone_before_submitting,
					IMessageProvider.ERROR);
			AbstractTaskEditorPart descriptionPart = getPart(ID_PART_ATTRIBUTES);
			if (descriptionPart != null) {
				descriptionPart.setFocus();
			}
			return;
		}

		TaskAttribute attributeOperation = getModel().getTaskData()
				.getRoot()
				.getMappedAttribute(TaskAttribute.OPERATION);
		if (attributeOperation != null) {
			if ("duplicate".equals(attributeOperation.getValue())) { //$NON-NLS-1$
				TaskAttribute originalOperation = getModel().getTaskData()
						.getRoot()
						.getAttribute(TaskAttribute.PREFIX_OPERATION + attributeOperation.getValue());
				String inputAttributeId = originalOperation.getMetaData()
						.getValue(TaskAttribute.META_ASSOCIATED_ATTRIBUTE_ID);
				if (inputAttributeId != null && !inputAttributeId.equals("")) { //$NON-NLS-1$
					TaskAttribute inputAttribute = attributeOperation.getTaskData()
							.getRoot()
							.getAttribute(inputAttributeId);
					if (inputAttribute != null) {
						String dupValue = inputAttribute.getValue();
						if (dupValue == null || dupValue.equals("")) { //$NON-NLS-1$
							getTaskEditor().setMessage(
									Messages.BugzillaTaskEditorPage_Please_enter_a_bugid_for_duplicate_of_before_submitting,
									IMessageProvider.ERROR);
							AbstractTaskEditorPart part = getPart(ID_PART_ACTIONS);
							if (part != null) {
								part.setFocus();
							}
							return;
						}
					}
				}
			}
		}

		if (getModel().getTaskData().isNew()) {
			TaskAttribute productAttribute = getModel().getTaskData()
					.getRoot()
					.getMappedAttribute(TaskAttribute.PRODUCT);
			if (productAttribute != null && productAttribute.getValue().length() > 0) {
				getModel().getTaskRepository().setProperty(IBugzillaConstants.LAST_PRODUCT_SELECTION,
						productAttribute.getValue());
			}
			TaskAttribute componentSelectedAttribute = getModel().getTaskData()
					.getRoot()
					.getMappedAttribute(TaskAttribute.COMPONENT);
			if (componentSelectedAttribute != null && componentSelectedAttribute.getValue().length() > 0) {
				getModel().getTaskRepository().setProperty(IBugzillaConstants.LAST_COMPONENT_SELECTION,
						componentSelectedAttribute.getValue());
			}
		}

		// Force the most recent known good token onto the outgoing task data to ensure submit
		// bug#263318
		TaskAttribute attrToken = getModel().getTaskData().getRoot().getAttribute(BugzillaAttribute.TOKEN.getKey());
		if (attrToken != null) {
			String tokenString = getModel().getTask().getAttribute(BugzillaAttribute.TOKEN.getKey());
			if (tokenString != null) {
				attrToken.setValue(tokenString);
			}
		}
		for (ControlDecoration decoration : errorDecorations) {
			decoration.hide();
			decoration.dispose();
		}
		errorDecorations.clear();
		editorsWithError.clear();
		if (!checkCanSubmit(IMessageProvider.ERROR)) {
			return;
		}
		getTaskEditor().setMessage("", IMessageProvider.NONE); //$NON-NLS-1$
		super.doSubmit();
	}

	@Override
	protected void createParts() {
		attributeEditorMap.clear();
		super.createParts();
		checkCanSubmit(IMessageProvider.INFORMATION);
	}

	@Override
	protected TaskDataModel createModel(TaskEditorInput input) throws CoreException {
		TaskDataModel model = super.createModel(input);
		productListener = new ProductSelectionListener();
		model.addModelListener(productListener);
		return model;
	}

	/**
	 * @since 3.1
	 */
	private void addToAttributeEditorMap(TaskAttribute attribute, AbstractAttributeEditor editor) {
		if (attributeEditorMap.containsKey(attribute)) {
			attributeEditorMap.remove(attribute);
		}
		attributeEditorMap.put(attribute, editor);
	}

	/**
	 * @since 3.1
	 */
	private AbstractAttributeEditor getEditorForAttribute(TaskAttribute attribute) {
		return attributeEditorMap.get(attribute);
	}

	private void refresh(TaskAttribute attributeComponent) {
		AbstractAttributeEditor editor = getEditorForAttribute(attributeComponent);
		if (editor != null) {
			try {
				editor.refresh();
			} catch (UnsupportedOperationException e) {
				// ignore
			}
		}
	}

	private class ProductSelectionListener extends TaskDataModelListener {
		@Override
		public void attributeChanged(TaskDataModelEvent event) {
			TaskAttribute taskAttribute = event.getTaskAttribute();
			if (taskAttribute != null) {
				if (taskAttribute.getId().equals(BugzillaAttribute.PRODUCT.getKey())) {
					RepositoryConfiguration repositoryConfiguration = null;
					try {
						BugzillaRepositoryConnector connector = (BugzillaRepositoryConnector) TasksUi
								.getRepositoryConnector(getModel().getTaskRepository().getConnectorKind());
						repositoryConfiguration = connector.getRepositoryConfiguration(getModel().getTaskRepository(),
								false, new NullProgressMonitor());
					} catch (CoreException e) {
						StatusHandler.log(new RepositoryStatus(getTaskRepository(), IStatus.ERROR,
								BugzillaUiPlugin.ID_PLUGIN, 0, "Failed to obtain repository configuration", e)); //$NON-NLS-1$
						getTaskEditor().setMessage("Problem occured when updating attributes", IMessageProvider.ERROR); //$NON-NLS-1$
						return;
					}

					TaskAttribute attributeComponent = taskAttribute.getTaskData()
							.getRoot()
							.getMappedAttribute(BugzillaAttribute.COMPONENT.getKey());
					if (attributeComponent != null) {
						List<String> optionValues = repositoryConfiguration
								.getProductOptionValues(BugzillaAttribute.COMPONENT, taskAttribute.getValue());
						Collections.sort(optionValues);
						attributeComponent.clearOptions();
						for (String option : optionValues) {
							attributeComponent.putOption(option, option);
						}
						if (optionValues.size() > 0) {
							attributeComponent.setValue(optionValues.get(0));
						}
						refresh(attributeComponent);
					}

					TaskAttribute attributeTargetMilestone = taskAttribute.getTaskData()
							.getRoot()
							.getMappedAttribute(BugzillaAttribute.TARGET_MILESTONE.getKey());
					if (attributeTargetMilestone != null) {
						List<String> optionValues = repositoryConfiguration
								.getProductOptionValues(BugzillaAttribute.TARGET_MILESTONE, taskAttribute.getValue());
						Collections.sort(optionValues);
						attributeTargetMilestone.clearOptions();
						for (String option : optionValues) {
							attributeTargetMilestone.putOption(option, option);
						}
						String defaultMilestones = repositoryConfiguration
								.getDefaultMilestones(taskAttribute.getValue());
						if (defaultMilestones != null) {
							attributeTargetMilestone.setValue(defaultMilestones);
						} else if (optionValues.size() == 1) {
							attributeTargetMilestone.setValue(optionValues.get(0));
						} else {
							attributeTargetMilestone.setValue("---"); //$NON-NLS-1$
						}
						refresh(attributeTargetMilestone);
					}

					TaskAttribute attributeVersion = taskAttribute.getTaskData()
							.getRoot()
							.getMappedAttribute(BugzillaAttribute.VERSION.getKey());
					if (attributeVersion != null) {
						List<String> optionValues = repositoryConfiguration
								.getProductOptionValues(BugzillaAttribute.VERSION, taskAttribute.getValue());
						Collections.sort(optionValues);
						attributeVersion.clearOptions();
						for (String option : optionValues) {
							attributeVersion.putOption(option, option);
						}
						if (optionValues.size() == 1) {
							attributeVersion.setValue(optionValues.get(0));
						} else {
							attributeVersion.setValue("unspecified"); //$NON-NLS-1$
						}
						refresh(attributeVersion);
					}

					TaskAttribute attributeDefaultAssignee = taskAttribute.getTaskData()
							.getRoot()
							.getMappedAttribute(BugzillaAttribute.SET_DEFAULT_ASSIGNEE.getKey());
					if (attributeDefaultAssignee != null) {
						attributeDefaultAssignee.setValue("1"); //$NON-NLS-1$
						refresh(attributeDefaultAssignee);
					}
					if (taskAttribute.getTaskData().isNew()) {
						BugzillaVersion bugzillaVersion = repositoryConfiguration.getInstallVersion();
						if (bugzillaVersion == null) {
							bugzillaVersion = BugzillaVersion.MIN_VERSION;
						}
						if (bugzillaVersion.compareMajorMinorOnly(BugzillaVersion.BUGZILLA_4_0) >= 0) {
							AbstractTaskEditorPart part = getPart(ID_PART_ACTIONS);
							boolean unconfirmedAllowed = repositoryConfiguration
									.getUnconfirmedAllowed(taskAttribute.getValue());
							TaskAttribute unconfirmedAttribute = taskAttribute.getTaskData().getRoot().getAttribute(
									TaskAttribute.PREFIX_OPERATION + BugzillaOperation.unconfirmed.toString());
							if (unconfirmedAttribute != null) {
								unconfirmedAttribute.getMetaData().setReadOnly(!unconfirmedAllowed);
							}
							if (part != null) {
								TaskEditorActionPart actionPart = (TaskEditorActionPart) part;
								actionPart.refreshOperations();
							}
						}
					}
/*
 * 					add confirm_product_change to avoid verification page on submit
 */
					TaskAttribute attributeConfirmeProductChange = taskAttribute.getTaskData()
							.getRoot()
							.getMappedAttribute(BugzillaAttribute.CONFIRM_PRODUCT_CHANGE.getKey());
					if (attributeConfirmeProductChange == null) {
						attributeConfirmeProductChange = BugzillaTaskDataHandler.createAttribute(
								taskAttribute.getTaskData().getRoot(), BugzillaAttribute.CONFIRM_PRODUCT_CHANGE);
					}
					if (attributeConfirmeProductChange != null) {
						attributeConfirmeProductChange.setValue("1"); //$NON-NLS-1$
					}
				}
			}
		}
	}

	@Override
	protected void handleTaskSubmitted(SubmitJobEvent event) {
		if (event.getJob().getStatus() != null) {
			switch (event.getJob().getStatus().getCode()) {
			case BugzillaStatus.ERROR_CONFIRM_MATCH:
			case BugzillaStatus.ERROR_MATCH_FAILED:
				showError((BugzillaStatus) event.getJob().getStatus());
				return;
			}
		}
		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;
				if (bugzillaResponse.getResponseData().size() > 0) {
					getTaskEditor().setMessage(Messages.BugzillaTaskEditorPage_Changes_Submitted_Message,
							IMessageProvider.INFORMATION, new HyperlinkAdapter() {
								@Override
								public void linkActivated(HyperlinkEvent event) {
									showSubmitResponse(bugzillaResponse);
								}

							});
				} else {
					getTaskEditor().setMessage(Messages.BugzillaTaskEditorPage_Changes_Submitted_Message,
							IMessageProvider.INFORMATION);
				}
			}
		} else {
			super.handleTaskSubmitted(event);
		}
	}

	@Override
	public void refresh() {
		super.refresh();
		checkCanSubmit(IMessageProvider.INFORMATION);
	}

	private boolean checkCanSubmit(final int type) {
		final TaskRepository taskRepository = getModel().getTaskRepository();
		String username = taskRepository.getUserName();
		if (username == null || username.length() == 0) {
			PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
				public void run() {
					getTaskEditor().setMessage(Messages.BugzillaTaskEditorPage_Anonymous_can_not_submit_Tasks, type,
							new HyperlinkAdapter() {
								@Override
								public void linkActivated(HyperlinkEvent e) {
									TasksUiUtil.openEditRepositoryWizard(taskRepository);
									refresh();
								}
							});
				}
			});
			return false;
		}
		if (!getModel().getTaskData().isNew()) {
			TaskAttribute exporter = getModel().getTaskData()
					.getRoot()
					.getAttribute(BugzillaAttribute.EXPORTER_NAME.getKey());
			if (exporter == null || exporter.getValue().equals("")) { //$NON-NLS-1$
				PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
					public void run() {
						getTaskEditor().setMessage(Messages.BugzillaTaskEditorPage_submit_disabled_please_refresh, type,
								new HyperlinkAdapter() {
									@Override
									public void linkActivated(HyperlinkEvent e) {
										TasksUiUtil.openEditRepositoryWizard(taskRepository);
										refresh();
									}
								});
					}
				});
				return false;
			}
		}
		return true;
	}

	private void showError(BugzillaStatus bugzillaStatus) {
		int count = 0;
		BugzillaUserMatchResponse response = bugzillaStatus.getUserMatchResponse();
		FieldDecorationRegistry registry = FieldDecorationRegistry.getDefault();
		FieldDecoration fieldDecoration = registry.getFieldDecoration(FieldDecorationRegistry.DEC_ERROR);
		FieldDecoration fieldDecorationWarning = registry.getFieldDecoration(FieldDecorationRegistry.DEC_WARNING);
		StringBuilder fields = new StringBuilder();
		StringBuilder detail = new StringBuilder();

		count += decorateControlsAndUpdateMessages(response.getAssignedToMsg(), response.getAssignedToProposals(),
				getModel().getTaskData().getRoot().getAttribute(BugzillaAttribute.ASSIGNED_TO.getKey()), fields, detail,
				fieldDecoration, fieldDecorationWarning);
		count += decorateControlsAndUpdateMessages(response.getQaContactMsg(), response.getQaContactProposals(),
				getModel().getTaskData().getRoot().getAttribute(BugzillaAttribute.QA_CONTACT.getKey()), fields, detail,
				fieldDecoration, fieldDecorationWarning);
		count += decorateControlsAndUpdateMessages(response.getNewCCMsg(), response.getNewCCProposals(),
				getModel().getTaskData().getRoot().getAttribute(BugzillaAttribute.NEWCC.getKey()), fields, detail,
				fieldDecoration, fieldDecorationWarning);
		updateTaskEditorPageMessageWithError(bugzillaStatus, detail.toString(), count == 1, fields.toString());
	}

	private int decorateControlsAndUpdateMessages(String message, List<String> proposals, TaskAttribute attribute,
			StringBuilder fields, StringBuilder detail, FieldDecoration fieldDecoration,
			FieldDecoration fieldDecorationWarning) {
		if (attribute == null || (message == null && proposals.size() == 0)) {
			return 0;
		}
		Map<String, String> newPersonProposalMap = new HashMap<String, String>();
		if (fields.length() > 0) {
			fields.append(MessageFormat.format(Messages.BugzillaTaskEditorPage_Error_Label_N,
					attribute.getMetaData().getLabel()));
		} else {
			fields.append(MessageFormat.format(Messages.BugzillaTaskEditorPage_Error_Label_1,
					attribute.getMetaData().getLabel()));
		}
		detail.append(attribute.getMetaData().getLabel() + "\n"); //$NON-NLS-1$
		if (message != null && !message.equals("")) { //$NON-NLS-1$
			detail.append(MessageFormat.format(Messages.BugzillaTaskEditorPage_DetailLine, message));
		} else {
			for (String proposalValue : proposals) {
				detail.append(MessageFormat.format(Messages.BugzillaTaskEditorPage_DetailLine, proposalValue));
				newPersonProposalMap.put(proposalValue, proposalValue);
			}
		}
		AbstractAttributeEditor editor = getEditorForAttribute(attribute);
		if (editor != null) {
			decorateEditorWithError(fieldDecoration, fieldDecorationWarning, message, newPersonProposalMap, editor);
		}
		return 1;
	}

	private int decorateControlsAndUpdateMessages(String message, Map<String, List<String>> proposals,
			TaskAttribute attribute, StringBuilder fields, StringBuilder detail, FieldDecoration fieldDecoration,
			FieldDecoration fieldDecorationWarning) {
		if (attribute == null || (message == null && proposals.size() == 0)) {
			return 0;
		}
		Map<String, String> newPersonProposalMap = new HashMap<String, String>();
		if (fields.length() > 0) {
			fields.append(MessageFormat.format(Messages.BugzillaTaskEditorPage_Error_Label_N,
					attribute.getMetaData().getLabel()));
		} else {
			fields.append(MessageFormat.format(Messages.BugzillaTaskEditorPage_Error_Label_1,
					attribute.getMetaData().getLabel()));
		}
		detail.append(attribute.getMetaData().getLabel() + "\n"); //$NON-NLS-1$
		if (message != null && !message.equals("")) { //$NON-NLS-1$
			detail.append(MessageFormat.format(Messages.BugzillaTaskEditorPage_DetailLine, message));
		} else {
			for (String key : proposals.keySet()) {
				detail.append(MessageFormat.format(Messages.BugzillaTaskEditorPage_Proposal_Detail, key));

				for (String proposalValue : proposals.get(key)) {
					detail.append(MessageFormat.format(Messages.BugzillaTaskEditorPage_DetailLine, proposalValue));
					newPersonProposalMap.put(proposalValue, proposalValue);
				}
			}
		}
		AbstractAttributeEditor editor = getEditorForAttribute(attribute);
		if (editor != null) {
			decorateEditorWithError(fieldDecoration, fieldDecorationWarning, message, newPersonProposalMap, editor);
		}
		return 1;
	}

	/**
	 * @param bugzillaStatus
	 * @param resultDetail
	 * @param oneError
	 * @param fieldString
	 */
	private void updateTaskEditorPageMessageWithError(BugzillaStatus bugzillaStatus, String resultDetail,
			boolean oneError, String fieldString) {
		String resultString;
		final String titleString;
		switch (bugzillaStatus.getCode()) {
		case BugzillaStatus.ERROR_CONFIRM_MATCH:
			if (oneError) {
				resultString = MessageFormat.format(Messages.BugzillaTaskEditorPage_Message_one,
						Messages.BugzillaTaskEditorPage_Confirm, fieldString);
			} else {
				resultString = MessageFormat.format(Messages.BugzillaTaskEditorPage_Message_more,
						Messages.BugzillaTaskEditorPage_Confirm, fieldString);
			}
			titleString = Messages.BugzillaTaskEditorPage_ConfirmDetailTitle;
			break;
		case BugzillaStatus.ERROR_MATCH_FAILED:
			if (oneError) {
				resultString = MessageFormat.format(Messages.BugzillaTaskEditorPage_Message_one,
						Messages.BugzillaTaskEditorPage_Error, fieldString);
			} else {
				resultString = MessageFormat.format(Messages.BugzillaTaskEditorPage_Message_more,
						Messages.BugzillaTaskEditorPage_Error, fieldString);
			}
			titleString = Messages.BugzillaTaskEditorPage_ErrorDetailTitle;
			break;
		default:
			throw new RuntimeException("unexpected BugzillaStatus: " + bugzillaStatus.getCode()); //$NON-NLS-1$
		}

		final String resultDetailString = resultDetail;
		getTaskEditor().setMessage(resultString, IMessageProvider.ERROR, new HyperlinkAdapter() {
			@Override
			public void linkActivated(HyperlinkEvent event) {
				BugzillaResponseDetailDialog dialog = new BugzillaResponseDetailDialog(WorkbenchUtil.getShell(),
						titleString, resultDetailString);
				dialog.open();
			}
		});
	}

	/**
	 * @param fieldDecoration
	 * @param message
	 * @param newPersonProposalMap
	 * @param editor
	 */
	private void decorateEditorWithError(FieldDecoration fieldDecoration, FieldDecoration fieldDecorationWarning,
			String message, Map<String, String> newPersonProposalMap, AbstractAttributeEditor editor) {
		final Control control = editor.getControl();

		final ControlDecoration decoration = new ControlDecoration(control, SWT.LEFT | SWT.DOWN);
		decoration.setImage(
				newPersonProposalMap.size() == 1 ? fieldDecorationWarning.getImage() : fieldDecoration.getImage());
		IBindingService bindingService = PlatformUI.getWorkbench().getService(IBindingService.class);
		if (message != null && !message.equals("")) { //$NON-NLS-1$
			decoration.setDescriptionText(message);
			errorDecorations.add(decoration);
		} else {
			decoration.setDescriptionText(
					NLS.bind(Messages.BugzillaTaskEditorPage_Content_Assist_for_Error_Available, bindingService
							.getBestActiveBindingFormattedFor(ContentAssistCommandAdapter.CONTENT_PROPOSAL_COMMAND)));
			errorDecorations.add(decoration);

			final PersonAttributeEditor personEditor = ((PersonAttributeEditor) editor);
			final PersonProposalProvider personProposalProvider = (PersonProposalProvider) personEditor
					.getContentAssistCommandAdapter().getContentProposalProvider();
			personProposalProvider.setErrorProposals(newPersonProposalMap);

			editorsWithError.add(personEditor);
			if (newPersonProposalMap.size() == 1) {
				personEditor.setValue(newPersonProposalMap.keySet().iterator().next());

			}
			personEditor.getText().addModifyListener(new ModifyListener() {

				public void modifyText(ModifyEvent e) {
					decoration.hide();
					errorDecorations.remove(decoration);
					decoration.dispose();
					personProposalProvider.setErrorProposals(null);
				}
			});
		}
	}

	/**
	 * @param bugzillaResponse
	 */
	private void showSubmitResponse(final BugzillaRepositoryResponse bugzillaResponse) {
		StringBuilder message = new StringBuilder();
		for (String iterable_map : bugzillaResponse.getResponseData().keySet()) {
			if (message.length() > 0) {
				message.append("\n"); //$NON-NLS-1$
			}
			message.append(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.append(NLS.bind(Messages.BugzillaTaskEditorPage_Action_Line, iterable_list));
				List<String> responseList = responseMap.get(iterable_list);
				for (String string : responseList) {
					message.append(NLS.bind(Messages.BugzillaTaskEditorPage_Email_Line, string));
				}
			}
		}
		BugzillaResponseDetailDialog dialog = new BugzillaResponseDetailDialog(WorkbenchUtil.getShell(),
				Messages.BugzillaTaskEditorPage_submitted_Changes_Details, message.toString());
		dialog.open();
	}

}
