/*
 * Copyright (c) 2005, 2018 IBM Corporation, CEA, 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:
 *   IBM - initial API and implementation
 *   Kenn Hussey - 323181, 522658, 528925, 531034, 533169
 *   Kenn Hussey (CEA) - 281326
 *
 */
package org.eclipse.uml2.uml.editor.presentation;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.common.CommonPlugin;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.command.CommandWrapper;
import org.eclipse.emf.common.command.CompoundCommand;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.ui.viewer.IViewerProvider;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.DiagnosticChain;
import org.eclipse.emf.common.util.TreeIterator;

import org.eclipse.emf.ecore.EAnnotation;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.Diagnostician;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.edit.command.AddCommand;
import org.eclipse.emf.edit.command.CommandParameter;
import org.eclipse.emf.edit.command.RemoveCommand;
import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.domain.IEditingDomainProvider;

import org.eclipse.emf.edit.provider.IItemLabelProvider;
import org.eclipse.emf.edit.ui.EMFEditUIPlugin;
import org.eclipse.emf.edit.ui.action.CollapseAllAction;
import org.eclipse.emf.edit.ui.action.ControlAction;
import org.eclipse.emf.edit.ui.action.CreateChildAction;
import org.eclipse.emf.edit.ui.action.CreateSiblingAction;
import org.eclipse.emf.edit.ui.action.EditingDomainActionBarContributor;
import org.eclipse.emf.edit.ui.action.ExpandAllAction;
import org.eclipse.emf.edit.ui.action.FindAction;
import org.eclipse.emf.edit.ui.action.LoadResourceAction;
import org.eclipse.emf.edit.ui.action.RevertAction;
import org.eclipse.emf.edit.ui.action.ValidateAction;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.action.IContributionManager;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.action.SubContributionItem;

import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.Viewer;

import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.PartInitException;

import org.eclipse.uml2.common.edit.command.ChangeCommand;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.editor.UMLEditorPlugin;
import org.eclipse.uml2.uml.util.UMLUtil;

/**
 * This is the action bar contributor for the UML model editor.
 * <!-- begin-user-doc -->
 * <!-- end-user-doc -->
 * @generated
 */
public class UMLActionBarContributor
		extends EditingDomainActionBarContributor
		implements ISelectionChangedListener {

	/**
	 * This keeps track of the active editor.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected IEditorPart activeEditorPart;

	/**
	 * This keeps track of the current selection provider.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected ISelectionProvider selectionProvider;

	/**
	 * This action opens the Properties view.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected IAction showPropertiesViewAction = new Action(
		UMLEditorPlugin.INSTANCE.getString("_UI_ShowPropertiesView_menu_item")) //$NON-NLS-1$
	{

		@Override
		public void run() {
			try {
				getPage().showView("org.eclipse.ui.views.PropertySheet"); //$NON-NLS-1$
			} catch (PartInitException exception) {
				UMLEditorPlugin.INSTANCE.log(exception);
			}
		}
	};

	/**
	 * This action refreshes the viewer of the current editor if the editor
	 * implements {@link org.eclipse.emf.common.ui.viewer.IViewerProvider}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected IAction refreshViewerAction = new Action(
		UMLEditorPlugin.INSTANCE.getString("_UI_RefreshViewer_menu_item")) //$NON-NLS-1$
	{

		@Override
		public boolean isEnabled() {
			return activeEditorPart instanceof IViewerProvider;
		}

		@Override
		public void run() {
			if (activeEditorPart instanceof IViewerProvider) {
				Viewer viewer = ((IViewerProvider) activeEditorPart)
					.getViewer();
				if (viewer != null) {
					viewer.refresh();
				}
			}
		}
	};

	/**
	 * This will contain one {@link org.eclipse.emf.edit.ui.action.CreateChildAction} corresponding to each descriptor
	 * generated for the current selection by the item provider.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected Collection<IAction> createChildActions;

	/**
	 * This will contain a map of {@link org.eclipse.emf.edit.ui.action.CreateChildAction}s, keyed by sub-menu text.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected Map<String, Collection<IAction>> createChildSubmenuActions;

	/**
	 * This is the menu manager into which menu contribution items should be added for CreateChild actions.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected IMenuManager createChildMenuManager;

	/**
	 * This will contain one {@link org.eclipse.emf.edit.ui.action.CreateSiblingAction} corresponding to each descriptor
	 * generated for the current selection by the item provider.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected Collection<IAction> createSiblingActions;

	/**
	 * This will contain a map of {@link org.eclipse.emf.edit.ui.action.CreateSiblingAction}s, keyed by submenu text.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected Map<String, Collection<IAction>> createSiblingSubmenuActions;

	/**
	 * This is the menu manager into which menu contribution items should be added for CreateSibling actions.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected IMenuManager createSiblingMenuManager;

	/**
	 * This creates an instance of the contributor.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated NOT
	 */
	public UMLActionBarContributor() {
		super(ADDITIONS_LAST_STYLE);

		loadResourceAction = new LoadResourceAction();

		validateAction = new UMLValidateAction();
		controlAction = new UMLControlAction();

		findAction = FindAction.create();
		revertAction = new RevertAction();
		expandAllAction = new ExpandAllAction();
		collapseAllAction = new CollapseAllAction();
	}

	/**
	 * This adds Separators for editor additions to the tool bar.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void contributeToToolBar(IToolBarManager toolBarManager) {
		super.contributeToToolBar(toolBarManager);
		toolBarManager.add(new Separator("uml-settings")); //$NON-NLS-1$
		toolBarManager.add(new Separator("uml-additions")); //$NON-NLS-1$
	}

	/**
	 * This adds to the menu bar a menu and some separators for editor additions,
	 * as well as the sub-menus for object creation items.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void contributeToMenu(IMenuManager menuManager) {
		super.contributeToMenu(menuManager);

		IMenuManager submenuManager = new MenuManager(
			UMLEditorPlugin.INSTANCE.getString("_UI_UMLEditor_menu"), //$NON-NLS-1$
			"org.eclipse.uml2.umlMenuID"); //$NON-NLS-1$
		menuManager.insertAfter("additions", submenuManager); //$NON-NLS-1$
		submenuManager.add(new Separator("settings")); //$NON-NLS-1$
		submenuManager.add(new Separator("actions")); //$NON-NLS-1$
		submenuManager.add(new Separator("additions")); //$NON-NLS-1$
		submenuManager.add(new Separator("additions-end")); //$NON-NLS-1$

		// Prepare for CreateChild item addition or removal.
		//
		createChildMenuManager = new MenuManager(
			UMLEditorPlugin.INSTANCE.getString("_UI_CreateChild_menu_item")); //$NON-NLS-1$
		submenuManager.insertBefore("additions", createChildMenuManager); //$NON-NLS-1$

		// Prepare for CreateSibling item addition or removal.
		//
		createSiblingMenuManager = new MenuManager(
			UMLEditorPlugin.INSTANCE.getString("_UI_CreateSibling_menu_item")); //$NON-NLS-1$
		submenuManager.insertBefore("additions", createSiblingMenuManager); //$NON-NLS-1$

		// Force an update because Eclipse hides empty menus now.
		//
		submenuManager.addMenuListener(new IMenuListener() {

			public void menuAboutToShow(IMenuManager menuManager) {
				menuManager.updateAll(true);
			}
		});

		addGlobalActions(submenuManager);
	}

	/**
	 * When the active editor changes, this remembers the change and registers with it as a selection provider.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setActiveEditor(IEditorPart part) {
		super.setActiveEditor(part);
		activeEditorPart = part;

		// Switch to the new selection provider.
		//
		if (selectionProvider != null) {
			selectionProvider.removeSelectionChangedListener(this);
		}
		if (part == null) {
			selectionProvider = null;
		} else {
			selectionProvider = part.getSite().getSelectionProvider();
			selectionProvider.addSelectionChangedListener(this);

			// Fake a selection changed event to update the menus.
			//
			if (selectionProvider.getSelection() != null) {
				selectionChanged(new SelectionChangedEvent(selectionProvider,
					selectionProvider.getSelection()));
			}
		}
	}

	/**
	 * This implements {@link org.eclipse.jface.viewers.ISelectionChangedListener},
	 * handling {@link org.eclipse.jface.viewers.SelectionChangedEvent}s by querying for the children and siblings
	 * that can be added to the selected object and updating the menus accordingly.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void selectionChanged(SelectionChangedEvent event) {
		// Remove any menu items for old selection.
		//
		if (createChildMenuManager != null) {
			depopulateManager(createChildMenuManager,
				createChildSubmenuActions);
			depopulateManager(createChildMenuManager, createChildActions);
		}
		if (createSiblingMenuManager != null) {
			depopulateManager(createSiblingMenuManager,
				createSiblingSubmenuActions);
			depopulateManager(createSiblingMenuManager, createSiblingActions);
		}

		// Query the new selection for appropriate new child/sibling descriptors
		//
		Collection<?> newChildDescriptors = null;
		Collection<?> newSiblingDescriptors = null;

		ISelection selection = event.getSelection();
		if (selection instanceof IStructuredSelection
			&& ((IStructuredSelection) selection).size() == 1) {
			Object object = ((IStructuredSelection) selection)
				.getFirstElement();

			EditingDomain domain = ((IEditingDomainProvider) activeEditorPart)
				.getEditingDomain();

			newChildDescriptors = domain.getNewChildDescriptors(object, null);
			newSiblingDescriptors = domain.getNewChildDescriptors(null, object);
		}

		// Generate actions for selection; populate and redraw the menus.
		//
		createChildActions = generateCreateChildActions(newChildDescriptors,
			selection);
		createChildSubmenuActions = extractSubmenuActions(createChildActions);
		createSiblingActions = generateCreateSiblingActions(
			newSiblingDescriptors, selection);
		createSiblingSubmenuActions = extractSubmenuActions(
			createSiblingActions);

		if (createChildMenuManager != null) {
			populateManager(createChildMenuManager, createChildSubmenuActions,
				null);
			populateManager(createChildMenuManager, createChildActions, null);
			createChildMenuManager.update(true);
		}
		if (createSiblingMenuManager != null) {
			populateManager(createSiblingMenuManager,
				createSiblingSubmenuActions, null);
			populateManager(createSiblingMenuManager, createSiblingActions,
				null);
			createSiblingMenuManager.update(true);
		}
	}

	/**
	 * This generates a {@link org.eclipse.emf.edit.ui.action.CreateChildAction} for each object in <code>descriptors</code>,
	 * and returns the collection of these actions.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected Collection<IAction> generateCreateChildActionsGen(
			Collection<?> descriptors, ISelection selection) {
		Collection<IAction> actions = new ArrayList<IAction>();
		if (descriptors != null) {
			for (Object descriptor : descriptors) {
				actions.add(new CreateChildAction(activeEditorPart, selection,
					descriptor));
			}
		}
		return actions;
	}

	protected Collection<IAction> generateCreateChildActions(
			Collection<?> descriptors, ISelection selection) {
		List<IAction> createChildActions = (List<IAction>) generateCreateChildActionsGen(
			descriptors, selection);

		if (descriptors != null) {
			configureActions(createChildActions,
				new ArrayList<Object>(descriptors));
		}

		Collections.<IAction> sort(createChildActions,
			new Comparator<IAction>() {

				public int compare(IAction a1, IAction a2) {
					return CommonPlugin.INSTANCE.getComparator()
						.compare(a1.getText(), a2.getText());
				}
			});

		return createChildActions;
	}

	protected void configureActions(List<IAction> actions,
			List<Object> descriptors) {

		for (int i = 0, size = actions.size(); i < size; ++i) {
			IAction action = actions.get(i);
			Object descriptor = descriptors.get(i);

			if (descriptor instanceof CommandParameter) {
				EObject eObject = ((CommandParameter) descriptor).getEValue();

				if (eObject instanceof EAnnotation) {
					String source = ((EAnnotation) eObject).getSource();

					if (source != null) {
						action.setText(action.getText() + " - " + source); //$NON-NLS-1$
					}
				}
			}
		}
	}

	/**
	 * This generates a {@link org.eclipse.emf.edit.ui.action.CreateSiblingAction} for each object in <code>descriptors</code>,
	 * and returns the collection of these actions.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected Collection<IAction> generateCreateSiblingActionsGen(
			Collection<?> descriptors, ISelection selection) {
		Collection<IAction> actions = new ArrayList<IAction>();
		if (descriptors != null) {
			for (Object descriptor : descriptors) {
				actions.add(new CreateSiblingAction(activeEditorPart, selection,
					descriptor));
			}
		}
		return actions;
	}

	protected Collection<IAction> generateCreateSiblingActions(
			Collection<?> descriptors, ISelection selection) {
		List<IAction> createSiblingActions = (List<IAction>) generateCreateSiblingActionsGen(
			descriptors, selection);

		if (descriptors != null) {
			configureActions(createSiblingActions,
				new ArrayList<Object>(descriptors));
		}

		Collections.<IAction> sort(createSiblingActions,
			new Comparator<IAction>() {

				public int compare(IAction a1, IAction a2) {
					return CommonPlugin.INSTANCE.getComparator()
						.compare(a1.getText(), a2.getText());
				}
			});

		return createSiblingActions;
	}

	/**
	 * This populates the specified <code>manager</code> with {@link org.eclipse.jface.action.ActionContributionItem}s
	 * based on the {@link org.eclipse.jface.action.IAction}s contained in the <code>actions</code> collection,
	 * by inserting them before the specified contribution item <code>contributionID</code>.
	 * If <code>contributionID</code> is <code>null</code>, they are simply added.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected void populateManager(IContributionManager manager,
			Collection<? extends IAction> actions, String contributionID) {
		if (actions != null) {
			for (IAction action : actions) {
				if (contributionID != null) {
					manager.insertBefore(contributionID, action);
				} else {
					manager.add(action);
				}
			}
		}
	}

	/**
	 * This removes from the specified <code>manager</code> all {@link org.eclipse.jface.action.ActionContributionItem}s
	 * based on the {@link org.eclipse.jface.action.IAction}s contained in the <code>actions</code> collection.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected void depopulateManager(IContributionManager manager,
			Collection<? extends IAction> actions) {
		if (actions != null) {
			IContributionItem[] items = manager.getItems();
			for (int i = 0; i < items.length; i++) {
				// Look into SubContributionItems
				//
				IContributionItem contributionItem = items[i];
				while (contributionItem instanceof SubContributionItem) {
					contributionItem = ((SubContributionItem) contributionItem)
						.getInnerItem();
				}

				// Delete the ActionContributionItems with matching action.
				//
				if (contributionItem instanceof ActionContributionItem) {
					IAction action = ((ActionContributionItem) contributionItem)
						.getAction();
					if (actions.contains(action)) {
						manager.remove(contributionItem);
					}
				}
			}
		}
	}

	/**
	 * This extracts those actions in the <code>submenuActions</code> collection whose text is qualified and returns
	 * a map of these actions, keyed by submenu text.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected Map<String, Collection<IAction>> extractSubmenuActions(
			Collection<IAction> createActions) {
		Map<String, Collection<IAction>> createSubmenuActions = new LinkedHashMap<String, Collection<IAction>>();
		if (createActions != null) {
			for (Iterator<IAction> actions = createActions.iterator(); actions
				.hasNext();) {
				IAction action = actions.next();
				StringTokenizer st = new StringTokenizer(action.getText(), "|"); //$NON-NLS-1$
				if (st.countTokens() == 2) {
					String text = st.nextToken().trim();
					Collection<IAction> submenuActions = createSubmenuActions
						.get(text);
					if (submenuActions == null) {
						createSubmenuActions.put(text,
							submenuActions = new ArrayList<IAction>());
					}
					action.setText(st.nextToken().trim());
					submenuActions.add(action);
					actions.remove();
				}
			}
		}
		return createSubmenuActions;
	}

	/**
	 * This populates the specified <code>manager</code> with {@link org.eclipse.jface.action.MenuManager}s containing
	 * {@link org.eclipse.jface.action.ActionContributionItem}s based on the {@link org.eclipse.jface.action.IAction}s
	 * contained in the <code>submenuActions</code> collection, by inserting them before the specified contribution
	 * item <code>contributionID</code>.
	 * If <code>contributionID</code> is <code>null</code>, they are simply added.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected void populateManager(IContributionManager manager,
			Map<String, Collection<IAction>> submenuActions,
			String contributionID) {
		if (submenuActions != null) {
			for (Map.Entry<String, Collection<IAction>> entry : submenuActions
				.entrySet()) {
				MenuManager submenuManager = new MenuManager(entry.getKey());
				if (contributionID != null) {
					manager.insertBefore(contributionID, submenuManager);
				} else {
					manager.add(submenuManager);
				}
				populateManager(submenuManager, entry.getValue(), null);
			}
		}
	}

	/**
	 * This removes from the specified <code>manager</code> all {@link org.eclipse.jface.action.MenuManager}s and their
	 * {@link org.eclipse.jface.action.ActionContributionItem}s based on the {@link org.eclipse.jface.action.IAction}s
	 * contained in the <code>submenuActions</code> map.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected void depopulateManager(IContributionManager manager,
			Map<String, Collection<IAction>> submenuActions) {
		if (submenuActions != null) {
			IContributionItem[] items = manager.getItems();
			for (int i = 0; i < items.length; i++) {
				IContributionItem contributionItem = items[i];
				if (contributionItem instanceof MenuManager) {
					MenuManager submenuManager = (MenuManager) contributionItem;
					if (submenuActions
						.containsKey(submenuManager.getMenuText())) {
						depopulateManager(submenuManager,
							submenuActions.get(submenuManager.getMenuText()));
						manager.remove(contributionItem);
					}
				}
			}
		}
	}

	/**
	 * This populates the pop-up menu before it appears.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void menuAboutToShow(IMenuManager menuManager) {
		super.menuAboutToShow(menuManager);
		MenuManager submenuManager = null;

		submenuManager = new MenuManager(
			UMLEditorPlugin.INSTANCE.getString("_UI_CreateChild_menu_item")); //$NON-NLS-1$
		populateManager(submenuManager, createChildSubmenuActions, null);
		populateManager(submenuManager, createChildActions, null);
		menuManager.insertBefore("edit", submenuManager); //$NON-NLS-1$

		submenuManager = new MenuManager(
			UMLEditorPlugin.INSTANCE.getString("_UI_CreateSibling_menu_item")); //$NON-NLS-1$
		populateManager(submenuManager, createSiblingSubmenuActions, null);
		populateManager(submenuManager, createSiblingActions, null);
		menuManager.insertBefore("edit", submenuManager); //$NON-NLS-1$
	}

	/**
	 * This inserts global actions before the "additions-end" separator.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	protected void addGlobalActions(IMenuManager menuManager) {
		menuManager.insertAfter("additions-end", new Separator("ui-actions")); //$NON-NLS-1$ //$NON-NLS-2$
		menuManager.insertAfter("ui-actions", showPropertiesViewAction); //$NON-NLS-1$

		refreshViewerAction.setEnabled(refreshViewerAction.isEnabled());
		menuManager.insertAfter("ui-actions", refreshViewerAction); //$NON-NLS-1$

		super.addGlobalActions(menuManager);
	}

	/**
	 * This ensures that a delete action will clean up all references to deleted objects.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	protected boolean removeAllReferencesOnDelete() {
		return true;
	}

	protected static class UMLControlAction
			extends ControlAction {

		protected List<EObject> collectAllStereotypeApplications(
				EObject eObject, List<EObject> allStereotypeApplications) {

			if (eObject instanceof Element) {

				for (EObject stereotypeApplication : ((Element) eObject)
					.getStereotypeApplications()) {

					allStereotypeApplications.add(stereotypeApplication);

					collectAllStereotypeApplications(stereotypeApplication,
						allStereotypeApplications);
				}
			}

			for (TreeIterator<EObject> allProperContents = EcoreUtil
				.getAllProperContents(eObject, true); allProperContents
					.hasNext();) {

				EObject content = allProperContents.next();

				if (content instanceof Element) {

					for (EObject stereotypeApplication : ((Element) content)
						.getStereotypeApplications()) {

						allStereotypeApplications.add(stereotypeApplication);

						collectAllStereotypeApplications(stereotypeApplication,
							allStereotypeApplications);
					}
				}
			}

			return allStereotypeApplications;
		}

		@Override
		public boolean updateSelection(IStructuredSelection selection) {
			this.selection = selection;

			if (selection.size() != 1) {
				return false;
			}

			Object object = AdapterFactoryEditingDomain
				.unwrap(selection.getFirstElement());
			boolean result = domain.isControllable(object);
			eObject = result
				? (EObject) object
				: null;

			if (!AdapterFactoryEditingDomain.isControlled(object)) {
				setText(EMFEditUIPlugin.INSTANCE
					.getString("_UI_Control_menu_item")); //$NON-NLS-1$
				setDescription("_UI_Control_menu_item_description"); //$NON-NLS-1$

				command = null;
			} else {
				setText(EMFEditUIPlugin.INSTANCE
					.getString("_UI_Uncontrol_menu_item")); //$NON-NLS-1$
				setDescription("_UI_Uncontrol_menu_item_description"); //$NON-NLS-1$

				if (result) {
					CompoundCommand compoundCommand = new CompoundCommand(
						EMFEditUIPlugin.INSTANCE
							.getString("_UI_UncontrolCommand_label")); //$NON-NLS-1$		        		

					compoundCommand.append(new RemoveCommand(domain,
						eObject.eResource().getContents(), eObject));

					final List<EObject> allStereotypeApplications = collectAllStereotypeApplications(
						eObject, new ArrayList<EObject>());

					compoundCommand.append(new CommandWrapper() {

						@Override
						protected Command createCommand() {
							return new ChangeCommand(domain, new Runnable() {

								public void run() {

									for (EObject stereotypeApplication : allStereotypeApplications) {
										UMLUtil.StereotypeApplicationHelper
											.getInstance(null)
											.addToContainmentList(
												UMLUtil.getBaseElement(
													stereotypeApplication),
												stereotypeApplication, null);
									}
								}
							});
						}
					});

					command = compoundCommand;

					result = command.canExecute();
				}
			}

			return result;
		}

		@Override
		public void run() {

			if (command == null) {

				if (eObject == null) {
					return;
				}

				Resource resource = getResource();

				if (resource == null) {
					return;
				}

				CompoundCommand compoundCommand = new CompoundCommand(
					EMFEditUIPlugin.INSTANCE
						.getString("_UI_ControlCommand_label")); //$NON-NLS-1$		        		

				compoundCommand.append(
					new AddCommand(domain, resource.getContents(), eObject));

				final List<EObject> allStereotypeApplications = collectAllStereotypeApplications(
					eObject, new ArrayList<EObject>());

				compoundCommand.append(new CommandWrapper() {

					@Override
					protected Command createCommand() {
						return new ChangeCommand(domain, new Runnable() {

							public void run() {

								for (EObject stereotypeApplication : allStereotypeApplications) {
									UMLUtil.StereotypeApplicationHelper
										.getInstance(null).addToContainmentList(
											UMLUtil.getBaseElement(
												stereotypeApplication),
											stereotypeApplication, null);
								}
							}
						});
					}
				});

				command = compoundCommand;
			}

			super.run();
		}

	}

	protected static class UMLValidateAction
			extends ValidateAction {

		protected int count(EObject eObject) {
			int count = 1;

			if (eObject instanceof Element) {

				for (EObject stereotypeApplication : ((Element) eObject)
					.getStereotypeApplications()) {

					count += count(stereotypeApplication);
				}
			}

			for (EObject eContent : eObject.eContents()) {
				count += count(eContent);
			}

			return count;
		}

		@Override
		protected Diagnostic validate(final IProgressMonitor progressMonitor) {
			EObject eObject = (EObject) selectedObjects.iterator().next();

			progressMonitor.beginTask("", count(eObject)); //$NON-NLS-1$

			final AdapterFactory adapterFactory = domain instanceof AdapterFactoryEditingDomain
				? ((AdapterFactoryEditingDomain) domain).getAdapterFactory()
				: null;

			Diagnostician diagnostician = new Diagnostician() {

				@Override
				public String getObjectLabel(EObject eObject) {

					if (adapterFactory != null && !eObject.eIsProxy()) {
						IItemLabelProvider itemLabelProvider = (IItemLabelProvider) adapterFactory
							.adapt(eObject, IItemLabelProvider.class);

						if (itemLabelProvider != null) {
							return itemLabelProvider.getText(eObject);
						}
					}

					return super.getObjectLabel(eObject);
				}

				protected boolean doValidateStereotypeApplications(
						EObject eObject, DiagnosticChain diagnostics,
						Map<Object, Object> context) {
					List<EObject> stereotypeApplications = eObject instanceof Element
						? ((Element) eObject).getStereotypeApplications()
						: Collections.<EObject> emptyList();

					if (!stereotypeApplications.isEmpty()) {
						Iterator<EObject> i = stereotypeApplications.iterator();
						boolean result = validate(i.next(), diagnostics,
							context);

						while (i.hasNext() && (result || diagnostics != null)) {
							result &= validate(i.next(), diagnostics, context);
						}

						return result;
					} else {
						return true;
					}
				}

				@Override
				protected boolean doValidateContents(EObject eObject,
						DiagnosticChain diagnostics,
						Map<Object, Object> context) {
					boolean result = doValidateStereotypeApplications(eObject,
						diagnostics, context);

					if (result || diagnostics != null) {
						result &= super.doValidateContents(eObject, diagnostics,
							context);
					}

					return result;
				}

				@Override
				public boolean validate(EClass eClass, EObject eObject,
						DiagnosticChain diagnostics,
						Map<Object, Object> context) {
					progressMonitor.worked(1);
					return super.validate(eClass, eObject, diagnostics,
						context);
				}
			};

			progressMonitor.setTaskName(EMFEditUIPlugin.INSTANCE
				.getString("_UI_Validating_message", new Object[]{diagnostician //$NON-NLS-1$
					.getObjectLabel(eObject)}));

			return diagnostician.validate(eObject);
		}
	}

}
