/*******************************************************************************
 * Copyright (c) 2013 Frank Becker 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:
 *     Frank Becker - initial API and implementation
 *******************************************************************************/

package org.eclipse.mylyn.internal.bugzilla.rest.core;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.mylyn.commons.core.StatusHandler;
import org.eclipse.mylyn.internal.bugzilla.rest.core.response.data.Component;
import org.eclipse.mylyn.internal.bugzilla.rest.core.response.data.Field;
import org.eclipse.mylyn.internal.bugzilla.rest.core.response.data.FieldValues;
import org.eclipse.mylyn.internal.bugzilla.rest.core.response.data.FlagType;
import org.eclipse.mylyn.internal.bugzilla.rest.core.response.data.FlagTypes;
import org.eclipse.mylyn.internal.bugzilla.rest.core.response.data.Parameters;
import org.eclipse.mylyn.internal.bugzilla.rest.core.response.data.Product;
import org.eclipse.mylyn.internal.bugzilla.rest.core.response.data.SortableActiveEntry;
import org.eclipse.mylyn.internal.bugzilla.rest.core.response.data.StatusTransition;
import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
import org.eclipse.mylyn.tasks.core.data.TaskData;
import org.eclipse.mylyn.tasks.core.data.TaskOperation;

import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.google.common.collect.ImmutableSortedMap;
import com.google.common.collect.Ordering;

public class BugzillaRestConfiguration implements Serializable {

	private static final BugzillaRestCreateTaskSchema SCHEMA = BugzillaRestCreateTaskSchema.getDefault();

	private static final long serialVersionUID = 4173223872076958202L;

	private final String repositoryId;

	private Map<String, Field> fields;

	private Map<String, Product> products;

	private Parameters parameters;

	public BugzillaRestConfiguration(String repositoryId) {
		this.repositoryId = repositoryId;
	}

	public String getRepositoryId() {
		return repositoryId;
	}

	void setFields(Map<String, Field> fields) {
		Function<Field, String> getName = new Function<Field, String>() {
			public String apply(Field item) {
				return item.getName();
			}
		};
		Function<String, String> comparatorFunction = Functions.compose(getName, Functions.forMap(fields));
		Ordering<String> comparator = Ordering.natural().onResultOf(comparatorFunction);
		this.fields = ImmutableSortedMap.copyOf(fields, comparator);
	}

	public Map<String, Field> getFields() {
		return fields;
	}

	public Field getFieldWithName(String fieldName) {
		return fields.get(fieldName);
	}

	void setProducts(Map<String, Product> products) {
		Function<Product, String> getName = new Function<Product, String>() {
			public String apply(Product item) {
				return item.getName();
			}
		};
		Function<String, String> comparatorFunction = Functions.compose(getName, Functions.forMap(products));
		Ordering<String> comparator = Ordering.natural().onResultOf(comparatorFunction);
		this.products = ImmutableSortedMap.copyOf(products, comparator);
	}

	public Map<String, Product> getProducts() {
		return products;
	}

	public Product getProductWithName(String productName) {
		return products.get(productName);
	}

	void setParameters(Parameters parameters) {
		this.parameters = parameters;
	}

	public Parameters getParameters() {
		return parameters;
	}

	private Component getProductComponentWithName(@NonNull Product product, String name) {
		return product.getComponentWithName(name);
	}

	public void updateInitialTaskData(TaskData data) throws CoreException {
		setProductOptions(data);
		updateProductOptions(data);
		for (String key : data.getRoot().getAttributes().keySet()) {
			if (key.equals(BugzillaRestTaskSchema.getDefault().ADD_SELF_CC.getKey())
					|| key.equals(BugzillaRestTaskSchema.getDefault().NEW_COMMENT.getKey())
					|| key.equals(BugzillaRestTaskSchema.getDefault().DUPE_OF.getKey())
					|| key.equals(TaskAttribute.OPERATION)
					|| key.equals(BugzillaRestTaskSchema.getDefault().DATE_MODIFICATION.getKey())
					|| key.equals(BugzillaRestTaskSchema.getDefault().RESET_ASSIGNED_TO.getKey())) {
				continue;
			}
			TaskAttribute attribute = data.getRoot().getAttribute(key);
			if (!key.equals(SCHEMA.PRODUCT.getKey())) {
				String configName = mapTaskAttributeKey2ConfigurationFields(key);
				if ("addCC".equals(configName) || "removeCC".equals(configName)
						|| "reset_qa_contact".equals(configName)) {
					continue;
				}
				Field configField = getFieldWithName(configName);
				if (configField == null) {
					continue;
				}
				if (configName.equals("component") || configName.equals("version")
						|| configName.equals("target_milestone")) {
					if (attribute.getOptions().size() == 1 && attribute.getValue().isEmpty()) {
						attribute.setValue((String) attribute.getOptions().values().toArray()[0]);
					}
				} else {
					FieldValues[] val = configField.getValues();
					if (val != null && val.length > 0) {
						for (FieldValues fieldValues : val) {
							if (configName.equals("bug_status")) {
								if (fieldValues.getName() == null) {
									for (StatusTransition bugzillaRestBugStatusTransition : fieldValues
											.getCanChangeTo()) {
										attribute.putOption(bugzillaRestBugStatusTransition.getName(),
												bugzillaRestBugStatusTransition.getName());
									}
								}
							} else {
								attribute.putOption(fieldValues.getName(), fieldValues.getName());
							}

						}
					}
				}
			}
			if (attribute.getValue().isEmpty()) {
				String newValue = getValueFromParameter(key);
				if (newValue != null) {
					attribute.setValue(getValueFromParameter(key));
				}
			}

		}
		for (Field Field : fields.values()) {
			if (Field.isCustom() && Field.isOnBugEntry()) {
				TaskAttribute attribute = data.getRoot().createAttribute(Field.getName());
				if (attribute != null) {
					attribute.getMetaData().defaults().setLabel(Field.getDisplayName());
					attribute.getMetaData().setKind(TaskAttribute.KIND_DEFAULT);
					String type = getAttributeTypFromFieldTyp(Field.getType());
					attribute.getMetaData().setType(type);
					if (type.equals(TaskAttribute.TYPE_SINGLE_SELECT)) {
						attribute.getMetaData().setRequired(true);
					}

					FieldValues[] values1 = Field.getValues();
					if (values1 != null) {
						for (FieldValues FieldValues : values1) {
							attribute.putOption(FieldValues.getName(), FieldValues.getName());
						}
					}
					attribute.getMetaData().setReadOnly(false);
				}
			}
		}
		updateKeyword(data);
	}

	private String getValueFromParameter(String attributeId) {
		if (attributeId.equals(TaskAttribute.PRIORITY)) {
			return getParameters().getDefaultpriority();
		} else if (attributeId.equals(TaskAttribute.SEVERITY)) {
			return getParameters().getDefaultseverity();
		} else if (attributeId.equals("platform")) {
			if (getParameters().getDefaultplatform() == null || getParameters().getDefaultplatform().isEmpty()) {
				return "All";
			} else {
				return getParameters().getDefaultplatform();
			}
		} else if (attributeId.equals("os")) {
			if (getParameters().getDefaultopsys() == null || getParameters().getDefaultopsys().isEmpty()) {
				return "All";
			} else {
				return getParameters().getDefaultopsys();
			}
		}
		return "";
	}

	private String getAttributeTypFromFieldTyp(int fieldTyp) throws CoreException {
		switch (fieldTyp) {
		case 1://Free Text
			return TaskAttribute.TYPE_SHORT_TEXT;
		case 2: //DropDown
			return TaskAttribute.TYPE_SINGLE_SELECT;
		case 3: //Multiple-Selection Box
			return TaskAttribute.TYPE_MULTI_SELECT;
		case 4: //Large Text Box
			return TaskAttribute.TYPE_LONG_TEXT;
		case 5: //Date/Time
			return TaskAttribute.TYPE_DATETIME;
		case 6: //Bug Id
			return TaskAttribute.TYPE_INTEGER;
		case 7: //Bug URLs
			return TaskAttribute.TYPE_URL;
		default:
			Status status = new Status(IStatus.INFO, BugzillaRestCore.ID_PLUGIN,
					"unknown custom field type " + fieldTyp);
			StatusHandler.log(status);
			throw new CoreException(status);
		}
	}

	private String mapTaskAttributeKey2ConfigurationFields(String taskAttributeKey) {
		String resultString;
		if (taskAttributeKey.equals("task.common.summary")) {
			resultString = "short_desc";
		} else if (taskAttributeKey.equals(TaskAttribute.PRODUCT) //
				|| taskAttributeKey.equals(TaskAttribute.RESOLUTION) //
				|| taskAttributeKey.equals(TaskAttribute.PRIORITY) //
				|| taskAttributeKey.equals(TaskAttribute.COMPONENT) //
				|| taskAttributeKey.equals(TaskAttribute.VERSION)) {
			resultString = taskAttributeKey.substring(12);
		} else if (taskAttributeKey.equals(TaskAttribute.STATUS)) {
			resultString = "bug_status";
		} else if (taskAttributeKey.equals(TaskAttribute.USER_ASSIGNED)) {
			resultString = "assigned_to";
		} else if (taskAttributeKey.equals(TaskAttribute.USER_CC)) {
			resultString = "cc";
		} else if (taskAttributeKey.equals(TaskAttribute.DESCRIPTION)) {
			resultString = "longdesc";
		} else if (taskAttributeKey.equals("description_is_private")) {
			resultString = "longdescs.isprivate";
		} else if (taskAttributeKey.equals("os")) {
			resultString = "op_sys";
		} else if (taskAttributeKey.equals("platform")) {
			resultString = "rep_platform";
		} else if (taskAttributeKey.equals(TaskAttribute.SEVERITY)) {
			resultString = "bug_severity";
		} else if (taskAttributeKey.equals("comment")) {
			resultString = "longdesc";
		} else if (taskAttributeKey.equals("blocks")) {
			resultString = "blocked";
		} else if (taskAttributeKey.equals("depends_on")) {
			resultString = "dependson";
		} else {

			resultString = taskAttributeKey;
		}
		return resultString;
	}

	private void setAttributeOptionsForProduct(TaskAttribute taskAttribute, Product actualProduct) {
		taskAttribute.clearOptions();
		if (taskAttribute.getId().equals(SCHEMA.TARGET_MILESTONE.getKey())) {
			internalSetAttributeOptions(taskAttribute, actualProduct.getMilestones());
		} else if (taskAttribute.getId().equals(SCHEMA.VERSION.getKey())) {
			internalSetAttributeOptions(taskAttribute, actualProduct.getVersions());
		} else if (taskAttribute.getId().equals(SCHEMA.COMPONENT.getKey())) {
			internalSetAttributeOptions(taskAttribute, actualProduct.getComponents());
		}
	}

	private void internalSetAttributeOptions(TaskAttribute taskAttribute, SortableActiveEntry[] actualProductEntry) {
		boolean found = false;
		String actualValue = taskAttribute.getValue();
		for (SortableActiveEntry SortableActiveEntry : actualProductEntry) {
			if (SortableActiveEntry.isActive()) {
				taskAttribute.putOption(SortableActiveEntry.getName(), SortableActiveEntry.getName());
				if (!found) {
					found = actualValue.equals(SortableActiveEntry.getName());
				}
			}
		}
		if (!found) {
			taskAttribute.setValue(""); //$NON-NLS-1$
		}
	}

	public boolean setProductOptions(@NonNull TaskData taskData) {
		TaskAttribute attributeProduct = taskData.getRoot().getMappedAttribute(SCHEMA.PRODUCT.getKey());
		if (attributeProduct != null) {
			SortedSet<String> products = new TreeSet<String>();
			Field configFieldComponent = getFieldWithName("component"); //$NON-NLS-1$
			FieldValues[] val = configFieldComponent.getValues();
			if (val != null && val.length > 0) {
				for (FieldValues fieldValues : val) {
					for (String visibilityValue : fieldValues.getVisibilityValues()) {
						if (!products.contains(visibilityValue)) {
							products.add(visibilityValue);
						}
					}
				}
				attributeProduct.clearOptions();
				for (String productName : products) {
					attributeProduct.putOption(productName, productName);
				}
			}

			return true;
		}
		return false;
	}

	public boolean updateProductOptions(@NonNull TaskData taskData) {
		if (taskData == null) {
			return false;
		}
		TaskAttribute attributeProduct = taskData.getRoot().getMappedAttribute(SCHEMA.PRODUCT.getKey());
		if (attributeProduct == null) {
			return false;
		}
		if (!attributeProduct.getValue().isEmpty()) {
			Product actualProduct = getProductWithName(attributeProduct.getValue());

			TaskAttribute attributeComponent = taskData.getRoot().getMappedAttribute(SCHEMA.COMPONENT.getKey());
			if (attributeComponent != null) {
				setAttributeOptionsForProduct(attributeComponent, actualProduct);
			}
			TaskAttribute attributeVersion = taskData.getRoot().getMappedAttribute(SCHEMA.VERSION.getKey());
			if (attributeVersion != null) {
				setAttributeOptionsForProduct(attributeVersion, actualProduct);
			}
			TaskAttribute attributeTargetMilestone = taskData.getRoot()
					.getMappedAttribute(SCHEMA.TARGET_MILESTONE.getKey());
			if (attributeTargetMilestone != null) {
				setAttributeOptionsForProduct(attributeTargetMilestone, actualProduct);
			}
		} else {
			for (Product product : getProducts().values()) {
				attributeProduct.putOption(product.getName(), product.getName());
			}
			TaskAttribute attributeComponent = taskData.getRoot().getMappedAttribute(SCHEMA.COMPONENT.getKey());
			if (attributeComponent != null) {
				setAllAttributeOptions(attributeComponent, getFieldWithName("component")); //$NON-NLS-1$
			}
			TaskAttribute attributeVersion = taskData.getRoot().getMappedAttribute(SCHEMA.VERSION.getKey());
			if (attributeVersion != null) {
				setAllAttributeOptions(attributeVersion, getFieldWithName("version")); //$NON-NLS-1$
			}
			TaskAttribute attributeTargetMilestone = taskData.getRoot()
					.getMappedAttribute(SCHEMA.TARGET_MILESTONE.getKey());
			if (attributeTargetMilestone != null) {
				setAllAttributeOptions(attributeTargetMilestone, getFieldWithName("target_milestone")); //$NON-NLS-1$
			}
		}
		return true;
	}

	private void setAllAttributeOptions(TaskAttribute updateAttribute, Field configField) {
		FieldValues[] val = configField.getValues();
		if (val != null && val.length > 0) {
			for (FieldValues fieldValues : val) {
				updateAttribute.putOption(fieldValues.getName(), fieldValues.getName());
			}
		}
	}

	public void addValidOperations(TaskData bugReport) {
		TaskAttribute attributeStatus = bugReport.getRoot().getMappedAttribute(TaskAttribute.STATUS);
		String attributeStatusValue = attributeStatus.getValue();
		TaskAttribute operationAttribute = bugReport.getRoot().getAttribute(TaskAttribute.OPERATION);
		if (operationAttribute == null) {
			operationAttribute = bugReport.getRoot().createAttribute(TaskAttribute.OPERATION);
		}
		TaskAttribute attribute = bugReport.getRoot()
				.createAttribute(TaskAttribute.PREFIX_OPERATION + attributeStatusValue);
		if (attributeStatusValue.equals("RESOLVED")) {
			attribute.getMetaData().putValue(TaskAttribute.META_ASSOCIATED_ATTRIBUTE_ID,
					BugzillaRestTaskSchema.getDefault().RESOLUTION.getKey());
		}

		TaskOperation.applyTo(attribute, attributeStatusValue, attributeStatusValue);
		// set as default
		TaskOperation.applyTo(operationAttribute, attributeStatusValue, attributeStatusValue);
		Field status = getFieldWithName("bug_status");
		for (FieldValues fieldValues : status.getValues()) {
			if (((attributeStatusValue == null || attributeStatusValue.isEmpty()) && fieldValues.getName() == null)
					|| (attributeStatusValue != null && attributeStatusValue.equals(fieldValues.getName()))) {
				for (StatusTransition statusTransition : fieldValues.getCanChangeTo()) {
					attribute = bugReport.getRoot()
							.createAttribute(TaskAttribute.PREFIX_OPERATION + statusTransition.name);
					TaskOperation.applyTo(attribute, statusTransition.name, statusTransition.name);
					if (statusTransition.name != null && statusTransition.name.equals("RESOLVED")) {
						TaskAttribute attrResolvedInput = attribute.getTaskData().getRoot().createAttribute(
								"resolutionInput");
						attrResolvedInput.getMetaData().setType(TaskAttribute.TYPE_SINGLE_SELECT);
						attribute.getMetaData().putValue(TaskAttribute.META_ASSOCIATED_ATTRIBUTE_ID, "resolutionInput");
						Field resolution = getFieldWithName("resolution");
						for (FieldValues resolutionValues : resolution.getValues()) {
							if (resolutionValues.getName().compareTo("DUPLICATE") != 0) {
								attrResolvedInput.putOption(resolutionValues.getName(), resolutionValues.getName());
							}
						}
					}
				}
			}
		}
		attribute = bugReport.getRoot().createAttribute(TaskAttribute.PREFIX_OPERATION + "duplicate");
		TaskOperation.applyTo(attribute, "duplicate", "Mark as Duplicate");
		TaskAttribute attrResolvedInput = attribute.getTaskData().getRoot().getAttribute(
				BugzillaRestTaskSchema.getDefault().DUPE_OF.getKey());
		if (attrResolvedInput == null) {
			attrResolvedInput = attribute.getTaskData().getRoot().createAttribute(
					BugzillaRestTaskSchema.getDefault().DUPE_OF.getKey());
		}
		attrResolvedInput.getMetaData().setType(TaskAttribute.TYPE_TASK_DEPENDENCY);
		attribute.getMetaData().putValue(TaskAttribute.META_ASSOCIATED_ATTRIBUTE_ID, attrResolvedInput.getId());
	}

	public boolean updateFlags(@NonNull TaskData taskData) {
		List<String> existingFlags = new ArrayList<String>();
		TaskAttribute attributeProduct = taskData.getRoot().getMappedAttribute(SCHEMA.PRODUCT.getKey());
		TaskAttribute attributeComponent = taskData.getRoot().getMappedAttribute(SCHEMA.COMPONENT.getKey());
		Product actualProduct = getProductWithName(attributeProduct.getValue());
		Component actualComponent = getProductComponentWithName(actualProduct, attributeComponent.getValue());
		FlagTypes flagTypes = actualComponent.getFlagTypes();

		for (TaskAttribute attribute : taskData.getRoot().getAttributes().values()) {
			if (attribute.getId().startsWith(TaskAttribute.PREFIX_ATTACHMENT)
					|| attribute.getId().equals(TaskAttribute.NEW_ATTACHMENT)) {
				List<String> existingAttachmentFlags = new ArrayList<String>();
				for (TaskAttribute attachmentAttribute : attribute.getAttributes().values()) {
					updateFlag(flagTypes.getAttachment(), existingAttachmentFlags, attachmentAttribute);
				}
				addMissingFlagsInternal(attribute, flagTypes.getAttachment(), existingAttachmentFlags);
			} else {
				updateFlag(flagTypes.getBug(), existingFlags, attribute);
			}
		}
		addMissingFlagsInternal(taskData.getRoot(), flagTypes.getBug(), existingFlags);

		return false;
	}

	private void updateFlag(FlagType[] flagTypes, List<String> existingAttachmentFlags, TaskAttribute flagAttribute) {
		if (flagAttribute.getId().startsWith(IBugzillaRestConstants.KIND_FLAG)) {
			TaskAttribute stateAttribute = flagAttribute.getAttribute("state"); //$NON-NLS-1$))
			stateAttribute.putOption("", ""); //$NON-NLS-1$ //$NON-NLS-2$
			String flagName = stateAttribute.getMetaData().getLabel();
			if (!existingAttachmentFlags.contains(flagName)) {
				existingAttachmentFlags.add(flagName);
			}
			for (FlagType flagType : flagTypes) {
				if (flagType.getName().equals(flagName)) {
					if (flagType.isRequestable()) {
						stateAttribute.putOption("?", "?"); //$NON-NLS-1$ //$NON-NLS-2$
					}
					updateRequestee(flagAttribute, flagType);
					break;
				}
			}
			stateAttribute.putOption("-", "-"); //$NON-NLS-1$ //$NON-NLS-2$
			stateAttribute.putOption("+", "+"); //$NON-NLS-1$ //$NON-NLS-2$
		}
	}

	public void addMissingFlags(TaskData taskData) {
		List<String> existingFlags = new ArrayList<String>();
		TaskAttribute attributeProduct = taskData.getRoot().getMappedAttribute(SCHEMA.PRODUCT.getKey());
		TaskAttribute attributeComponent = taskData.getRoot().getMappedAttribute(SCHEMA.COMPONENT.getKey());
		if (attributeProduct.getValue().equals("") || attributeComponent.getValue().equals("")) { //$NON-NLS-1$ //$NON-NLS-2$
			return;
		}
		Product actualProduct = getProductWithName(attributeProduct.getValue());
		Component actualComponent = getProductComponentWithName(actualProduct, attributeComponent.getValue());
		FlagTypes flagTypes = actualComponent.getFlagTypes();
		addMissingFlagsInternal(taskData.getRoot(), flagTypes.getBug(), existingFlags);
	}

	private void addMissingFlagsInternal(TaskAttribute rootTaskAttribute, FlagType[] flagTypes,
			List<String> existingFlags) {
		for (FlagType flagType : flagTypes) {
			if (existingFlags.contains(flagType.getName()) && !flagType.isMultiplicable()) {
				continue;
			}
			BugzillaRestFlagMapper mapper = new BugzillaRestFlagMapper();
			mapper.setRequestee(""); //$NON-NLS-1$
			mapper.setSetter(""); //$NON-NLS-1$
			mapper.setState(" "); //$NON-NLS-1$
			mapper.setName(flagType.getName());
			mapper.setNumber(0);
			mapper.setDescription(flagType.getDescription());
			mapper.setTypeId(flagType.getId());
			TaskAttribute attribute = rootTaskAttribute
					.createAttribute(IBugzillaRestConstants.KIND_FLAG_TYPE + flagType.getId());
			mapper.applyTo(attribute);
			TaskAttribute stateAttribute = attribute.getAttribute("state"); //$NON-NLS-1$))
			stateAttribute.putOption("", ""); //$NON-NLS-1$ //$NON-NLS-2$
			if (flagType.isRequestable()) {
				stateAttribute.putOption("?", "?"); //$NON-NLS-1$ //$NON-NLS-2$
			}
			updateRequestee(attribute, flagType);
			attribute.getMetaData().putValue(TaskAttribute.META_DESCRIPTION, flagType.getDescription());
			stateAttribute.putOption("-", "-"); //$NON-NLS-1$ //$NON-NLS-2$
			stateAttribute.putOption("+", "+"); //$NON-NLS-1$ //$NON-NLS-2$
		}
	}

	public void updateRequestee(TaskAttribute attribute, FlagType flagType) {
		TaskAttribute requestee = attribute.getAttribute("requestee"); //$NON-NLS-1$
		if (requestee == null) {
			requestee = attribute.createMappedAttribute("requestee"); //$NON-NLS-1$
			requestee.getMetaData().defaults().setType(TaskAttribute.TYPE_PERSON);
			requestee.setValue(""); //$NON-NLS-1$
		}
		requestee.getMetaData().setReadOnly(!flagType.isRequesteeble());
	}

	public void updateAttachmentFlags(@NonNull TaskAttribute attribute) {
		TaskAttribute attributeProduct = attribute.getParentAttribute().getMappedAttribute(SCHEMA.PRODUCT.getKey());
		TaskAttribute attributeComponent = attribute.getParentAttribute().getMappedAttribute(SCHEMA.COMPONENT.getKey());
		Product actualProduct = getProductWithName(attributeProduct.getValue());
		Component actualComponent = getProductComponentWithName(actualProduct, attributeComponent.getValue());
		FlagTypes flagTypes = actualComponent.getFlagTypes();

		List<String> existingAttachmentFlags = new ArrayList<String>();
		for (TaskAttribute attachmentAttribute : attribute.getAttributes().values()) {
			updateFlag(flagTypes.getAttachment(), existingAttachmentFlags, attachmentAttribute);
		}
		addMissingFlagsInternal(attribute, flagTypes.getAttachment(), existingAttachmentFlags);
	}

	public void updateKeyword(TaskData taskData) {
		TaskAttribute attributeKeywords = taskData.getRoot().getMappedAttribute(SCHEMA.KEYWORDS.getKey());
		Field keywords = getFieldWithName("keywords");
		FieldValues[] keywordList = keywords.getValues();
		attributeKeywords.clearOptions();
		for (FieldValues fieldValues : keywordList) {
			attributeKeywords.putOption(fieldValues.getName(), fieldValues.getDescription());
		}
	}

}