/*******************************************************************************
 * Copyright (c) 2000, 2018 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Lars Vogel <Lars.Vogel@vogella.com> - Bug 474273
 *******************************************************************************/

package org.eclipse.ui.internal.activities;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
import org.eclipse.core.expressions.Expression;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.IJobFunction;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.activities.ActivityEvent;
import org.eclipse.ui.activities.ActivityManagerEvent;
import org.eclipse.ui.activities.CategoryEvent;
import org.eclipse.ui.activities.IActivity;
import org.eclipse.ui.activities.IActivityPatternBinding;
import org.eclipse.ui.activities.IActivityRequirementBinding;
import org.eclipse.ui.activities.ICategory;
import org.eclipse.ui.activities.ICategoryActivityBinding;
import org.eclipse.ui.activities.IIdentifier;
import org.eclipse.ui.activities.IMutableActivityManager;
import org.eclipse.ui.activities.ITriggerPointAdvisor;
import org.eclipse.ui.activities.IdentifierEvent;
import org.eclipse.ui.progress.UIJob;
import org.eclipse.ui.services.IEvaluationReference;
import org.eclipse.ui.services.IEvaluationService;

/**
 * An activity registry that may be altered.
 *
 * @since 3.0
 */
public final class MutableActivityManager extends AbstractActivityManager
		implements IMutableActivityManager, Cloneable {

	private Map<String, Activity> activitiesById = new HashMap<>();

	private Map<String, Set<IActivityRequirementBinding>> activityRequirementBindingsByActivityId = new HashMap<>();

	private Map<String, ActivityDefinition> activityDefinitionsById = new HashMap<>();

	private Map<String, Set<IActivityPatternBinding>> activityPatternBindingsByActivityId = new HashMap<>();

	private IActivityRegistry activityRegistry;

	private Map<String, Category> categoriesById = new HashMap<>();

	private Map<String, Set<ICategoryActivityBinding>> categoryActivityBindingsByCategoryId = new HashMap<>();

	private Map<String, CategoryDefinition> categoryDefinitionsById = new HashMap<>();

	private Set<String> definedActivityIds = new HashSet<>();

	private Set<String> definedCategoryIds = new HashSet<>();

	private Set<String> enabledActivityIds = new HashSet<>();

	private Map<String, Identifier> identifiersById = new HashMap<>();

	/**
	 * Avoid endless circular referencing of re-adding activity to evaluation
	 * listener, because of adding it the first time to evaluation listener.
	 */
	private boolean addingEvaluationListener = false;

	/**
	 * A list of identifiers that need to have their activity sets reconciled in the
	 * background job.
	 */
	private List<Identifier> deferredIdentifiers = Collections.synchronizedList(new LinkedList<>());

	/**
	 * The identifier update job. Lazily initialized.
	 */
	private Job deferredIdentifierJob = null;

	private final IActivityRegistryListener activityRegistryListener = activityRegistryEvent -> readRegistry(false);

	private Map<ActivityDefinition, IEvaluationReference> refsByActivityDefinition = new HashMap<>();

	/**
	 * Create a new instance of this class using the platform extension registry.
	 *
	 * @param triggerPointAdvisor
	 */
	public MutableActivityManager(ITriggerPointAdvisor triggerPointAdvisor) {
		this(triggerPointAdvisor, new ExtensionActivityRegistry(Platform.getExtensionRegistry()));
	}

	/**
	 * Create a new instance of this class using the provided registry.
	 *
	 * @param triggerPointAdvisor
	 *
	 * @param activityRegistry    the activity registry
	 */
	public MutableActivityManager(ITriggerPointAdvisor triggerPointAdvisor, IActivityRegistry activityRegistry) {
		Assert.isNotNull(activityRegistry);
		Assert.isNotNull(triggerPointAdvisor);

		this.advisor = triggerPointAdvisor;
		this.activityRegistry = activityRegistry;

		this.activityRegistry.addActivityRegistryListener(activityRegistryListener);

		readRegistry(true);
	}

	@Override
	synchronized public IActivity getActivity(String activityId) {
		if (activityId == null) {
			throw new NullPointerException();
		}

		Activity activity = activitiesById.get(activityId);

		if (activity == null) {
			activity = new Activity(activityId);
			updateActivity(activity);
			activitiesById.put(activityId, activity);
		}

		return activity;
	}

	@Override
	synchronized public ICategory getCategory(String categoryId) {
		if (categoryId == null) {
			throw new NullPointerException();
		}

		Category category = categoriesById.get(categoryId);

		if (category == null) {
			category = new Category(categoryId);
			updateCategory(category);
			categoriesById.put(categoryId, category);
		}

		return category;
	}

	@Override
	synchronized public Set<String> getDefinedActivityIds() {
		return Collections.unmodifiableSet(definedActivityIds);
	}

	@Override
	synchronized public Set<String> getDefinedCategoryIds() {
		return Collections.unmodifiableSet(definedCategoryIds);
	}

	@Override
	synchronized public Set<String> getEnabledActivityIds() {
		return Collections.unmodifiableSet(enabledActivityIds);
	}

	@Override
	synchronized public IIdentifier getIdentifier(String identifierId) {
		if (identifierId == null) {
			throw new NullPointerException();
		}

		Identifier identifier = identifiersById.get(identifierId);

		if (identifier == null) {
			identifier = new Identifier(identifierId);
			updateIdentifier(identifier);
			identifiersById.put(identifierId, identifier);
		}

		return identifier;
	}

	private void getRequiredActivityIds(Set<String> activityIds, Set<String> requiredActivityIds) {
		for (String activityId : activityIds) {
			IActivity activity = getActivity(activityId);
			Set<String> childActivityIds = new HashSet<>();
			Set<IActivityRequirementBinding> activityRequirementBindings = activity.getActivityRequirementBindings();
			for (IActivityRequirementBinding activityRequirementBinding : activityRequirementBindings) {
				childActivityIds.add(activityRequirementBinding.getRequiredActivityId());
			}
			childActivityIds.removeAll(requiredActivityIds);
			requiredActivityIds.addAll(childActivityIds);
			getRequiredActivityIds(childActivityIds, requiredActivityIds);
		}
	}

	private void notifyActivities(Map<String, ActivityEvent> activityEventsByActivityId) {
		for (Entry<String, ActivityEvent> entry : activityEventsByActivityId.entrySet()) {
			String activityId = entry.getKey();
			ActivityEvent activityEvent = entry.getValue();
			Activity activity = activitiesById.get(activityId);

			if (activity != null) {
				activity.fireActivityChanged(activityEvent);
			}
		}
	}

	private void notifyCategories(Map<String, CategoryEvent> categoryEventsByCategoryId) {
		for (Entry<String, CategoryEvent> entry : categoryEventsByCategoryId.entrySet()) {
			String categoryId = entry.getKey();
			CategoryEvent categoryEvent = entry.getValue();
			Category category = categoriesById.get(categoryId);

			if (category != null) {
				category.fireCategoryChanged(categoryEvent);
			}
		}
	}

	private void notifyIdentifiers(Map<String, IdentifierEvent> identifierEventsByIdentifierId) {
		for (Entry<String, IdentifierEvent> entry : identifierEventsByIdentifierId.entrySet()) {
			String identifierId = entry.getKey();
			IdentifierEvent identifierEvent = entry.getValue();
			Identifier identifier = identifiersById.get(identifierId);

			if (identifier != null) {
				identifier.fireIdentifierChanged(identifierEvent);
			}
		}
	}

	private void readRegistry(boolean setDefaults) {
		clearExpressions();
		Collection<ActivityDefinition> activityDefinitions = new ArrayList<>();
		activityDefinitions.addAll(activityRegistry.getActivityDefinitions());
		Map<String, ActivityDefinition> activityDefinitionsById = new HashMap<>(
				ActivityDefinition.activityDefinitionsById(activityDefinitions, false));

		for (Iterator<ActivityDefinition> iterator = activityDefinitionsById.values().iterator(); iterator.hasNext();) {
			ActivityDefinition activityDefinition = iterator.next();
			String name = activityDefinition.getName();

			if (name == null || name.isEmpty()) {
				iterator.remove();
			}
		}

		Collection<CategoryDefinition> categoryDefinitions = new ArrayList<>();
		categoryDefinitions.addAll(activityRegistry.getCategoryDefinitions());
		Map<String, CategoryDefinition> categoryDefinitionsById = new HashMap<>(
				CategoryDefinition.categoryDefinitionsById(categoryDefinitions, false));

		for (Iterator<CategoryDefinition> iterator = categoryDefinitionsById.values().iterator(); iterator.hasNext();) {
			CategoryDefinition categoryDefinition = iterator.next();
			String name = categoryDefinition.getName();

			if (name == null || name.isEmpty()) {
				iterator.remove();
			}
		}

		Map<String, Collection<ActivityRequirementBindingDefinition>> activityRequirementBindingDefinitionsByActivityId = ActivityRequirementBindingDefinition
				.activityRequirementBindingDefinitionsByActivityId(
						activityRegistry.getActivityRequirementBindingDefinitions());
		Map<String, Set<IActivityRequirementBinding>> activityRequirementBindingsByActivityId = new HashMap<>();

		for (Entry<String, Collection<ActivityRequirementBindingDefinition>> entry : activityRequirementBindingDefinitionsByActivityId
				.entrySet()) {
			String parentActivityId = entry.getKey();
			if (activityDefinitionsById.containsKey(parentActivityId)) {
				Collection<ActivityRequirementBindingDefinition> activityRequirementBindingDefinitions = entry
						.getValue();
				if (activityRequirementBindingDefinitions != null) {
					for (ActivityRequirementBindingDefinition activityRequirementBindingDefinition : activityRequirementBindingDefinitions) {
						String childActivityId = activityRequirementBindingDefinition.getRequiredActivityId();

						if (activityDefinitionsById.containsKey(childActivityId)) {
							IActivityRequirementBinding activityRequirementBinding = new ActivityRequirementBinding(
									childActivityId, parentActivityId);
							Set<IActivityRequirementBinding> activityRequirementBindings = activityRequirementBindingsByActivityId
									.get(parentActivityId);

							if (activityRequirementBindings == null) {
								activityRequirementBindings = new HashSet<>();
								activityRequirementBindingsByActivityId.put(parentActivityId,
										activityRequirementBindings);
							}

							activityRequirementBindings.add(activityRequirementBinding);
						}
					}
				}
			}
		}

		Map<String, Collection<ActivityPatternBindingDefinition>> activityPatternBindingDefinitionsByActivityId = ActivityPatternBindingDefinition
				.activityPatternBindingDefinitionsByActivityId(activityRegistry.getActivityPatternBindingDefinitions());
		Map<String, Set<IActivityPatternBinding>> activityPatternBindingsByActivityId = new HashMap<>();

		for (Entry<String, Collection<ActivityPatternBindingDefinition>> entry : activityPatternBindingDefinitionsByActivityId
				.entrySet()) {
			String activityId = entry.getKey();
			if (activityDefinitionsById.containsKey(activityId)) {
				Collection<ActivityPatternBindingDefinition> activityPatternBindingDefinitions = entry.getValue();
				if (activityPatternBindingDefinitions != null) {
					for (ActivityPatternBindingDefinition activityPatternBindingDefinition : activityPatternBindingDefinitions) {
						String pattern = activityPatternBindingDefinition.getPattern();

						if (pattern != null && pattern.length() != 0) {
							IActivityPatternBinding activityPatternBinding = new ActivityPatternBinding(activityId,
									pattern, activityPatternBindingDefinition.isEqualityPattern());
							Set<IActivityPatternBinding> activityPatternBindings = activityPatternBindingsByActivityId
									.get(activityId);

							if (activityPatternBindings == null) {
								activityPatternBindings = new HashSet<>();
								activityPatternBindingsByActivityId.put(activityId, activityPatternBindings);
							}

							activityPatternBindings.add(activityPatternBinding);
						}
					}
				}
			}
		}

		Map<String, Collection<CategoryActivityBindingDefinition>> categoryActivityBindingDefinitionsByCategoryId = CategoryActivityBindingDefinition
				.categoryActivityBindingDefinitionsByCategoryId(
						activityRegistry.getCategoryActivityBindingDefinitions());
		Map<String, Set<ICategoryActivityBinding>> categoryActivityBindingsByCategoryId = new HashMap<>();

		for (Entry<String, Collection<CategoryActivityBindingDefinition>> entry : categoryActivityBindingDefinitionsByCategoryId
				.entrySet()) {
			String categoryId = entry.getKey();
			if (categoryDefinitionsById.containsKey(categoryId)) {
				Collection<CategoryActivityBindingDefinition> categoryActivityBindingDefinitions = entry.getValue();
				if (categoryActivityBindingDefinitions != null) {
					for (CategoryActivityBindingDefinition categoryActivityBindingDefinition : categoryActivityBindingDefinitions) {
						String activityId = categoryActivityBindingDefinition.getActivityId();

						if (activityDefinitionsById.containsKey(activityId)) {
							ICategoryActivityBinding categoryActivityBinding = new CategoryActivityBinding(activityId,
									categoryId);
							Set<ICategoryActivityBinding> categoryActivityBindings = categoryActivityBindingsByCategoryId
									.get(categoryId);

							if (categoryActivityBindings == null) {
								categoryActivityBindings = new HashSet<>();
								categoryActivityBindingsByCategoryId.put(categoryId, categoryActivityBindings);
							}

							categoryActivityBindings.add(categoryActivityBinding);
						}
					}
				}
			}
		}

		this.activityRequirementBindingsByActivityId = activityRequirementBindingsByActivityId;
		this.activityDefinitionsById = activityDefinitionsById;
		this.activityPatternBindingsByActivityId = activityPatternBindingsByActivityId;
		this.categoryActivityBindingsByCategoryId = categoryActivityBindingsByCategoryId;
		this.categoryDefinitionsById = categoryDefinitionsById;
		boolean definedActivityIdsChanged = false;
		Set<String> definedActivityIds = new HashSet<>(activityDefinitionsById.keySet());

		Set<String> previouslyDefinedActivityIds = null;
		if (!definedActivityIds.equals(this.definedActivityIds)) {
			previouslyDefinedActivityIds = this.definedActivityIds;
			this.definedActivityIds = definedActivityIds;
			definedActivityIdsChanged = true;
		}

		boolean definedCategoryIdsChanged = false;
		Set<String> definedCategoryIds = new HashSet<>(categoryDefinitionsById.keySet());

		Set<String> previouslyDefinedCategoryIds = null;
		if (!definedCategoryIds.equals(this.definedCategoryIds)) {
			previouslyDefinedCategoryIds = this.definedCategoryIds;
			this.definedCategoryIds = definedCategoryIds;
			definedCategoryIdsChanged = true;
		}

		Set<String> enabledActivityIds = new HashSet<>(this.enabledActivityIds);
		getRequiredActivityIds(this.enabledActivityIds, enabledActivityIds);
		boolean enabledActivityIdsChanged = false;

		Set<String> previouslyEnabledActivityIds = null;
		if (!this.enabledActivityIds.equals(enabledActivityIds)) {
			previouslyEnabledActivityIds = this.enabledActivityIds;
			this.enabledActivityIds = enabledActivityIds;
			enabledActivityIdsChanged = true;
		}

		Map<String, ActivityEvent> activityEventsByActivityId = updateActivities(activitiesById.keySet());

		Map<String, CategoryEvent> categoryEventsByCategoryId = updateCategories(categoriesById.keySet());

		Map<String, IdentifierEvent> identifierEventsByIdentifierId = updateIdentifiers(identifiersById.keySet());

		if (definedActivityIdsChanged || definedCategoryIdsChanged || enabledActivityIdsChanged) {
			fireActivityManagerChanged(new ActivityManagerEvent(this, definedActivityIdsChanged,
					definedCategoryIdsChanged, enabledActivityIdsChanged, previouslyDefinedActivityIds,
					previouslyDefinedCategoryIds, previouslyEnabledActivityIds));
		}

		if (activityEventsByActivityId != null) {
			notifyActivities(activityEventsByActivityId);
		}

		if (categoryEventsByCategoryId != null) {
			notifyCategories(categoryEventsByCategoryId);
		}

		if (identifierEventsByIdentifierId != null) {
			notifyIdentifiers(identifierEventsByIdentifierId);
		}

		if (setDefaults) {
			setEnabledActivityIds(new HashSet<>(activityRegistry.getDefaultEnabledActivities()));
		}
	}

	private void clearExpressions() {
		IEvaluationService evaluationService = PlatformUI.getWorkbench().getService(IEvaluationService.class);
		Iterator<IEvaluationReference> i = refsByActivityDefinition.values().iterator();
		while (i.hasNext()) {
			IEvaluationReference ref = i.next();
			evaluationService.removeEvaluationListener(ref);
		}
		refsByActivityDefinition.clear();
	}

	@Override
	synchronized public void setEnabledActivityIds(Set<String> enabledActivityIds) {
		enabledActivityIds = new HashSet<>(enabledActivityIds);
		Set<String> requiredActivityIds = new HashSet<>(enabledActivityIds);
		getRequiredActivityIds(enabledActivityIds, requiredActivityIds);
		enabledActivityIds = requiredActivityIds;
		Set<String> deltaActivityIds = null;
		boolean activityManagerChanged = false;
		Map<String, ActivityEvent> activityEventsByActivityId = null;

		Set<String> previouslyEnabledActivityIds = null;
		// the sets are different so there may be work to do.
		if (!this.enabledActivityIds.equals(enabledActivityIds)) {
			previouslyEnabledActivityIds = this.enabledActivityIds;
			activityManagerChanged = true;

			// break out the additions to the current set
			Set<String> additions = new HashSet<>(enabledActivityIds);
			additions.removeAll(previouslyEnabledActivityIds);

			// and the removals
			Set<String> removals = new HashSet<>(previouslyEnabledActivityIds);
			removals.removeAll(enabledActivityIds);

			// remove from each set the expression-activities
			removeExpressionControlledActivities(additions);
			removeExpressionControlledActivities(removals);

			// merge the two sets into one delta - these are the changes that
			// need to be made after taking expressions into account
			deltaActivityIds = new HashSet<>(additions);
			deltaActivityIds.addAll(removals);

			if (deltaActivityIds.size() > 0) {
				// instead of blowing away the old set with the new we will
				// instead modify it based on the deltas
				// add in all the new activities to the current set
				enabledActivityIds.addAll(additions);
				// and remove the stale ones
				enabledActivityIds.removeAll(removals);
				// finally set the internal set of activities
				this.enabledActivityIds = enabledActivityIds;
				activityEventsByActivityId = updateActivities(deltaActivityIds);
			} else {
				return;
			}
		}

		updateListeners(activityManagerChanged, activityEventsByActivityId, deltaActivityIds,
				previouslyEnabledActivityIds);
	}

	/**
	 * Updates all the listeners to changes in the state.
	 *
	 * @param activityManagerChanged
	 * @param activityEventsByActivityId
	 * @param deltaActivityIds
	 * @param previouslyEnabledActivityIds
	 */
	private void updateListeners(boolean activityManagerChanged, Map<String, ActivityEvent> activityEventsByActivityId,
			Set<String> deltaActivityIds, Set<String> previouslyEnabledActivityIds) {
		// don't update identifiers if the enabled activity set has not changed
		if (activityManagerChanged) {
			Map<String, IdentifierEvent> identifierEventsByIdentifierId = updateIdentifiers(identifiersById.keySet(),
					deltaActivityIds);
			if (identifierEventsByIdentifierId != null) {
				notifyIdentifiers(identifierEventsByIdentifierId);
			}
		}
		if (activityEventsByActivityId != null) {
			notifyActivities(activityEventsByActivityId);
		}

		if (activityManagerChanged) {
			fireActivityManagerChanged(
					new ActivityManagerEvent(this, false, false, true, null, null, previouslyEnabledActivityIds));
		}
	}

	private void addExpressionEnabledActivity(String id) {
		Set<String> previouslyEnabledActivityIds = new HashSet<>(this.enabledActivityIds);
		this.enabledActivityIds.add(id);

		updateExpressionEnabledActivities(id, previouslyEnabledActivityIds);
	}

	private void removeExpressionEnabledActivity(String id) {
		Set<String> previouslyEnabledActivityIds = new HashSet<>(this.enabledActivityIds);
		this.enabledActivityIds.remove(id);

		updateExpressionEnabledActivities(id, previouslyEnabledActivityIds);
	}

	/**
	 * @param id
	 * @param previouslyEnabledActivityIds
	 */
	private void updateExpressionEnabledActivities(String id, Set<String> previouslyEnabledActivityIds) {
		Set<String> deltaActivityIds = new HashSet<>();
		deltaActivityIds.add(id);
		Map<String, ActivityEvent> activityEventsByActivityId = updateActivities(deltaActivityIds);

		updateListeners(true, activityEventsByActivityId, deltaActivityIds, previouslyEnabledActivityIds);
	}

	/**
	 * Removes from a list of activity changes all those that are based on
	 * expressions
	 *
	 * @param delta the set to modify
	 */
	private void removeExpressionControlledActivities(Set<String> delta) {

		for (Iterator<String> i = delta.iterator(); i.hasNext();) {
			String id = i.next();
			IActivity activity = activitiesById.get(id);
			Expression expression = activity.getExpression();

			if (expression != null) {
				i.remove();
			}
		}
	}

	private Map<String, ActivityEvent> updateActivities(Collection<String> activityIds) {
		Map<String, ActivityEvent> activityEventsByActivityId = new TreeMap<>();

		for (String activityId : activityIds) {
			Activity activity = activitiesById.get(activityId);

			if (activity != null) {
				ActivityEvent activityEvent = updateActivity(activity);

				if (activityEvent != null) {
					activityEventsByActivityId.put(activityId, activityEvent);
				}
			}
		}

		return activityEventsByActivityId;
	}

	private IPropertyChangeListener enabledWhenListener = event -> {
		if (addingEvaluationListener) {
			return;
		}

		Object nv = event.getNewValue();
		boolean enabledWhen = nv == null ? false : ((Boolean) nv).booleanValue();
		String id = event.getProperty();
		IActivity activity = activitiesById.get(id);
		if (activity.isEnabled() != enabledWhen) {
			if (enabledWhen) {
				addExpressionEnabledActivity(id);
			} else {
				removeExpressionEnabledActivity(id);
			}
		}
	};

	private ITriggerPointAdvisor advisor;

	private ActivityEvent updateActivity(Activity activity) {
		Set<IActivityRequirementBinding> activityRequirementBindings = activityRequirementBindingsByActivityId
				.get(activity.getId());
		boolean activityRequirementBindingsChanged = activity.setActivityRequirementBindings(
				activityRequirementBindings != null ? activityRequirementBindings : Collections.emptySet());
		Set<IActivityPatternBinding> activityPatternBindings = activityPatternBindingsByActivityId
				.get(activity.getId());
		boolean activityPatternBindingsChanged = activity.setActivityPatternBindings(
				activityPatternBindings != null ? activityPatternBindings : Collections.emptySet());
		ActivityDefinition activityDefinition = activityDefinitionsById.get(activity.getId());
		boolean definedChanged = activity.setDefined(activityDefinition != null);

		// enabledWhen comes into play
		IEvaluationReference ref = refsByActivityDefinition.get(activityDefinition);
		IEvaluationService evaluationService = PlatformUI.getWorkbench().getService(IEvaluationService.class);
		boolean newRef = false;
		if (activityDefinition != null && evaluationService != null) {
			activity.setExpression(activityDefinition.getEnabledWhen());
			if (ref == null && activityDefinition.getEnabledWhen() != null) {
				addingEvaluationListener = true;
				try {
					ref = evaluationService.addEvaluationListener(activityDefinition.getEnabledWhen(),
							enabledWhenListener, activityDefinition.getId());
					newRef = true;
				} finally {
					addingEvaluationListener = false;
				}
				if (ref != null) {
					refsByActivityDefinition.put(activityDefinition, ref);
				}
			}
		}
		final boolean enabledChanged;
		if (ref != null && evaluationService != null) {
			enabledChanged = activity.setEnabled(ref.evaluate(evaluationService.getCurrentState()));
			if (newRef && activity.isEnabled()) {
				// make sure this activity is in the enabled set for this
				// manager - event firing will be handled by the caller to this
				// method.
				this.enabledActivityIds.add(activity.getId());
			}
		} else {
			enabledChanged = activity.setEnabled(enabledActivityIds.contains(activity.getId()));
		}

		boolean nameChanged = activity.setName(activityDefinition != null ? activityDefinition.getName() : null);
		boolean descriptionChanged = activity
				.setDescription(activityDefinition != null ? activityDefinition.getDescription() : null);
		boolean defaultEnabledChanged = activity
				.setDefaultEnabled(activityRegistry.getDefaultEnabledActivities().contains(activity.getId()));
		if (activityRequirementBindingsChanged || activityPatternBindingsChanged || definedChanged || enabledChanged
				|| nameChanged || descriptionChanged || defaultEnabledChanged) {
			return new ActivityEvent(activity, activityRequirementBindingsChanged, activityPatternBindingsChanged,
					definedChanged, descriptionChanged, enabledChanged, nameChanged, defaultEnabledChanged);
		}

		return null;
	}

	private Map<String, CategoryEvent> updateCategories(Collection<String> categoryIds) {
		Map<String, CategoryEvent> categoryEventsByCategoryId = new TreeMap<>();

		for (String categoryId : categoryIds) {
			Category category = categoriesById.get(categoryId);

			if (category != null) {
				CategoryEvent categoryEvent = updateCategory(category);

				if (categoryEvent != null) {
					categoryEventsByCategoryId.put(categoryId, categoryEvent);
				}
			}
		}

		return categoryEventsByCategoryId;
	}

	private CategoryEvent updateCategory(Category category) {
		Set<ICategoryActivityBinding> categoryActivityBindings = categoryActivityBindingsByCategoryId
				.get(category.getId());
		boolean categoryActivityBindingsChanged = category.setCategoryActivityBindings(
				categoryActivityBindings != null ? categoryActivityBindings : Collections.emptySet());
		CategoryDefinition categoryDefinition = categoryDefinitionsById.get(category.getId());
		boolean definedChanged = category.setDefined(categoryDefinition != null);
		boolean nameChanged = category.setName(categoryDefinition != null ? categoryDefinition.getName() : null);
		boolean descriptionChanged = category
				.setDescription(categoryDefinition != null ? categoryDefinition.getDescription() : null);

		if (categoryActivityBindingsChanged || definedChanged || nameChanged || descriptionChanged) {
			return new CategoryEvent(category, categoryActivityBindingsChanged, definedChanged, descriptionChanged,
					nameChanged);
		}

		return null;
	}

	private IdentifierEvent updateIdentifier(Identifier identifier) {
		return updateIdentifier(identifier, definedActivityIds);
	}

	private IdentifierEvent updateIdentifier(Identifier identifier, Set<String> changedActivityIds) {
		String id = identifier.getId();
		Set<String> activityIds = new HashSet<>();

		boolean enabled = false;

		boolean activityIdsChanged = false;

		boolean enabledChanged = false;

		// short-circut logic. If all activities are enabled, then the
		// identifier must be as well. Return true and schedule the remainder of
		// the work to run in a background job.
		if (enabledActivityIds.size() == definedActivityIds.size()) {
			enabled = true;
			enabledChanged = identifier.setEnabled(enabled);
			identifier.setActivityIds(Collections.EMPTY_SET);
			deferredIdentifiers.add(identifier);
			getUpdateJob().schedule();
			if (enabledChanged) {
				return new IdentifierEvent(identifier, activityIdsChanged, enabledChanged);
			}
		} else {
			Set<String> activityIdsToUpdate = new HashSet<>(changedActivityIds);
			if (identifier.getActivityIds() != null) {
				activityIdsToUpdate.addAll(identifier.getActivityIds());
			}
			for (String activityId : activityIdsToUpdate) {
				Activity activity = (Activity) getActivity(activityId);

				if (activity.isMatch(id)) {
					activityIds.add(activityId);
				}
			}

			activityIdsChanged = identifier.setActivityIds(activityIds);

			if (advisor != null) {
				enabled = advisor.computeEnablement(this, identifier);
			}
			enabledChanged = identifier.setEnabled(enabled);

			if (activityIdsChanged || enabledChanged) {
				return new IdentifierEvent(identifier, activityIdsChanged, enabledChanged);
			}
		}
		return null;
	}

	private Map<String, IdentifierEvent> updateIdentifiers(Collection<String> identifierIds) {
		return updateIdentifiers(identifierIds, definedActivityIds);
	}

	private Map<String, IdentifierEvent> updateIdentifiers(Collection<String> identifierIds,
			Set<String> changedActivityIds) {
		Map<String, IdentifierEvent> identifierEventsByIdentifierId = new TreeMap<>();

		for (String identifierId : identifierIds) {
			Identifier identifier = identifiersById.get(identifierId);

			if (identifier != null) {
				IdentifierEvent identifierEvent = updateIdentifier(identifier, changedActivityIds);

				if (identifierEvent != null) {
					identifierEventsByIdentifierId.put(identifierId, identifierEvent);
				}
			}
		}

		return identifierEventsByIdentifierId;
	}

	/**
	 * Unhook this manager from its registry.
	 *
	 * @since 3.1
	 */
	public void unhookRegistryListeners() {
		activityRegistry.removeActivityRegistryListener(activityRegistryListener);
	}

	@Override
	synchronized public Object clone() {
		MutableActivityManager clone = new MutableActivityManager(advisor, activityRegistry);
		clone.setEnabledActivityIds(getEnabledActivityIds());
		return clone;
	}

	/**
	 * Return the identifier update job.
	 *
	 * @return the job
	 * @since 3.1
	 */
	private Job getUpdateJob() {
		if (deferredIdentifierJob == null) {
			deferredIdentifierJob = Job.create("Activity Identifier Update", (IJobFunction) monitor -> { //$NON-NLS-1$
				final Map<String, IdentifierEvent> identifierEventsByIdentifierId = new HashMap<>();

				while (!deferredIdentifiers.isEmpty()) {
					Identifier identifier = deferredIdentifiers.remove(0);
					Set<String> activityIds = new HashSet<>();
					for (String activityId : definedActivityIds) {
						Activity activity = (Activity) getActivity(activityId);

						if (activity.isMatch(identifier.getId())) {
							activityIds.add(activityId);
						}
					}

					boolean activityIdsChanged = identifier.setActivityIds(activityIds);
					if (activityIdsChanged) {
						IdentifierEvent identifierEvent = new IdentifierEvent(identifier, activityIdsChanged, false);
						identifierEventsByIdentifierId.put(identifier.getId(), identifierEvent);
					}
				}
				if (!identifierEventsByIdentifierId.isEmpty()) {
					UIJob notifyJob = new UIJob("Activity Identifier Update UI") { //$NON-NLS-1$
						@Override
						public IStatus runInUIThread(IProgressMonitor monitor) {
							notifyIdentifiers(identifierEventsByIdentifierId);
							return Status.OK_STATUS;
						}
					};
					notifyJob.setSystem(true);
					notifyJob.schedule();
				}
				return Status.OK_STATUS;
			});
			deferredIdentifierJob.setSystem(true);
		}
		return deferredIdentifierJob;
	}

}
