//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 IBM Corporation 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 Corporation - initial implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.library.edit.process.command;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.emf.common.command.AbstractCommand;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.epf.library.edit.IConfigurationApplicator;
import org.eclipse.epf.library.edit.LibraryEditPlugin;
import org.eclipse.epf.library.edit.Providers;
import org.eclipse.epf.library.edit.command.BatchCommand;
import org.eclipse.epf.library.edit.command.INestedCommandProvider;
import org.eclipse.epf.library.edit.command.IResourceAwareCommand;
import org.eclipse.epf.library.edit.ui.UserInteractionHelper;
import org.eclipse.epf.library.edit.util.ExtensionManager;
import org.eclipse.epf.library.edit.util.ProcessUtil;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.Descriptor;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodPackage;
import org.eclipse.epf.uma.MethodPlugin;
import org.eclipse.epf.uma.Process;
import org.eclipse.epf.uma.Role;
import org.eclipse.epf.uma.RoleDescriptor;
import org.eclipse.epf.uma.Task;
import org.eclipse.epf.uma.TaskDescriptor;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.WorkProductDescriptor;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.swt.widgets.Shell;


/**
 * Abstract base DropCommand class for breakdown structure editor
 * 
 * @author Phong Nguyen Le
 * @since 1.0
 */
public abstract class BSDropCommand extends AbstractCommand implements
		IResourceAwareCommand {
	public static final Set DEFAULT_SYNCH_FEATURES = Collections.unmodifiableSet(new HashSet(Arrays.asList(
			new EStructuralFeature[] {
					UmaPackage.eINSTANCE.getNamedElement_Name(),
					UmaPackage.eINSTANCE.getMethodElement_BriefDescription(),
					UmaPackage.eINSTANCE.getDescribableElement_PresentationName(),
					UmaPackage.eINSTANCE.getTask_OptionalInput(),
					UmaPackage.eINSTANCE.getTask_MandatoryInput(),
					UmaPackage.eINSTANCE.getTask_Output(),
					UmaPackage.eINSTANCE.getTask_Steps(),				
					UmaPackage.eINSTANCE.getTask_PerformedBy(),
					UmaPackage.eINSTANCE.getTask_AdditionallyPerformedBy(),
					UmaPackage.eINSTANCE.getRole_ResponsibleFor(),
					UmaPackage.eINSTANCE.getArtifact_ContainedArtifacts(),
					UmaPackage.eINSTANCE.getDeliverable_DeliveredWorkProducts()
			}
	)));
	
	/**
	 * Map of linked element's feature to descriptor's feature
	 */
	public static final Map FEATURE_MAP = new HashMap();
	static {
		FEATURE_MAP.put(UmaPackage.eINSTANCE.getNamedElement_Name(), UmaPackage.eINSTANCE.getNamedElement_Name());
		FEATURE_MAP.put(UmaPackage.eINSTANCE.getMethodElement_BriefDescription(), UmaPackage.eINSTANCE.getMethodElement_BriefDescription());
		FEATURE_MAP.put(UmaPackage.eINSTANCE.getDescribableElement_PresentationName(), UmaPackage.eINSTANCE.getDescribableElement_PresentationName());
		FEATURE_MAP.put(UmaPackage.eINSTANCE.getTask_OptionalInput(), UmaPackage.eINSTANCE.getTaskDescriptor_OptionalInput());
		FEATURE_MAP.put(UmaPackage.eINSTANCE.getTask_MandatoryInput(), UmaPackage.eINSTANCE.getTaskDescriptor_MandatoryInput());
		FEATURE_MAP.put(UmaPackage.eINSTANCE.getTask_Output(), UmaPackage.eINSTANCE.getTaskDescriptor_Output());
		FEATURE_MAP.put(UmaPackage.eINSTANCE.getRole_ResponsibleFor(), UmaPackage.eINSTANCE.getRoleDescriptor_ResponsibleFor());
		FEATURE_MAP.put(UmaPackage.eINSTANCE.getDeliverable_DeliveredWorkProducts(), UmaPackage.eINSTANCE.getWorkProductDescriptor_DeliverableParts());
		FEATURE_MAP.put(UmaPackage.eINSTANCE.getTask_Steps(), UmaPackage.eINSTANCE.getTaskDescriptor_SelectedSteps());
//		FEATURE_MAP.put(UmaPackage.eINSTANCE.getEstimatedMethodElement_Estimate(), UmaPackage.eINSTANCE.getEstimatedMethodElement_Estimate());
		FEATURE_MAP.put(UmaPackage.eINSTANCE.getTask_AdditionallyPerformedBy(), UmaPackage.eINSTANCE.getTaskDescriptor_AdditionallyPerformedBy());
	}

	protected Activity activity;

	protected List dropElements;

	private Set modifiedResources;

	protected List elementsToAddToDefaultConfig;

	protected Set addedObjects;

	private Process process;

	private boolean addedToDefaultConfig = false;

	protected boolean synchronize = false;

	protected ArrayList taskDescList;

	protected ArrayList taskDescriptorsToUpdate;

//	protected Set descriptorsToRefresh;

	/**
	 * Map of descriptor to old refreshable feature map
	 */
	private Map descriptorToOldRefreshableFeaturesMap;

	/**
	 * Map of descriptor to map of feature to new values
	 */
//	protected Map descriptorToNewFeatureValuesMap;
//	private HashMap descriptorToOldFeatureValuesMap;	
	protected DescriptorUpdateBatchCommand batchCommand;

//	private HashMap wpdToOldResponsibleRoleMap;

	/**
	 * Map of TaskDescriptor to list of newly added steps
	 */
	private Map taskDescToNewStepsMap;

	private Map taskDescToOldEstimateMap;
	
	protected boolean canceled;

	private MethodConfiguration config;

	protected Set synchFeatures = DEFAULT_SYNCH_FEATURES;

	private BatchCommand refreshResponsibleForCommand;

	protected boolean executed;

//	protected Object UIContext;
	
	protected boolean runAsJob;
	
	private IProgressMonitor monitor;

	private int workedUnits;

	private ArrayList nestedCommands;

	/**
	 * @param activity
	 *            the activity that the given elements are dropped on
	 * @param dropElements
	 *            the elements to drop on the given activity
	 */
	public BSDropCommand(Activity activity, List dropElements) {
		this(activity, dropElements, null, null, false);
	}

	/**
	 * @param synch
	 *            if true, the command will clean the content and relationships
	 *            of existing descriptors and refresh them with the linked
	 *            MethodElement
	 */
	public BSDropCommand(Activity activity, List dropElements, boolean synch) {
		this(activity, dropElements, null, null, synch);
	}

	/**
	 * Synchronize the given content elements to its TaskDescriptors in the
	 * given activity using the given MethodConfiguration and list of
	 * synchronizable features.
	 * 
	 * @param activity
	 * @param dropElements
	 *            the elements to synchronize
	 * @param config
	 * @param synchFeatures
	 *            the synchronizable features, if <code>null</code> the DEFAULT_SYNCH_FEATURES will be used.
	 */
	public BSDropCommand(Activity activity, List dropElements,
			MethodConfiguration config, Set synchFeatures) {
		this(activity, dropElements, config, synchFeatures, true);
	}
	
	public BSDropCommand(Activity activity, List dropElements,
			MethodConfiguration config, Set synchFeatures, boolean synch) {
		super();
		this.activity = activity;
		process = TngUtil.getOwningProcess(activity);
		this.synchronize = synch;
		this.config = config;
		if (synchFeatures == null) {
			this.synchFeatures = DEFAULT_SYNCH_FEATURES;
		}
		else {
			this.synchFeatures = synchFeatures;
		}
		
		this.dropElements = dropElements;
	}
	
	protected IProgressMonitor getProgressMonitor() {
		if(monitor == null) {
			monitor = new NullProgressMonitor();
		}
		return monitor;
	}
	
	protected void prepareDropElements() {
		
		ArrayList elements = new ArrayList();
		getMethodConfiguration();
		for (Iterator iter = dropElements.iterator(); iter.hasNext();) {
			Object element = TngUtil.unwrap(iter.next());
			element = Providers.getConfigurationApplicator().resolve(element, config);
			if (!elements.contains(element)
					&& !(element instanceof EObject && ((EObject) element)
							.eIsProxy())) {				
				elements.add(element);
			}
		}
		dropElements = elements;
	}
	
//	/**
//	 * Sets UI context for this command, this can be a Shell object
//	 * @param UIContext
//	 */
//	public void setUIContext(Object UIContext) {
//		this.UIContext = UIContext;
//	}

	public MethodConfiguration getMethodConfiguration() {
		if(config == null) {
			config = TngUtil.getOwningProcess(activity).getDefaultContext();
		}
		return config;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.common.command.AbstractCommand#dispose()
	 */
	public void dispose() {
		if (dropElements != null) {
			dropElements.clear();
		}
		if (modifiedResources != null) {
			modifiedResources.clear();
		}
		if (elementsToAddToDefaultConfig != null) {
			elementsToAddToDefaultConfig.clear();
		}
		if (addedObjects != null) {
			addedObjects.clear();
		}
		if (descriptorToOldRefreshableFeaturesMap != null) {
			descriptorToOldRefreshableFeaturesMap.clear();
		}
		if (taskDescList != null) {
			taskDescList.clear();
		}
		if (taskDescToNewStepsMap != null) {
			taskDescToNewStepsMap.clear();
		}
		if (taskDescToOldEstimateMap != null) {
			taskDescToOldEstimateMap.clear();
		}
		if (refreshResponsibleForCommand != null) {
			refreshResponsibleForCommand.dispose();
		}
		if (taskDescriptorsToUpdate != null) {
			taskDescriptorsToUpdate.clear();
		}
		if(batchCommand != null) {
			batchCommand.dispose();
		}
		activity = process = null;
		super.dispose();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.library.edit.command.IResourceAwareCommand#getModifiedResources()
	 */
	public Collection getModifiedResources() {
		if (modifiedResources == null) {
			modifiedResources = new HashSet();
			if (activity.eResource() != null) {
				modifiedResources.add(activity.eResource());
			}
		}
		
		if(nestedCommands != null && !nestedCommands.isEmpty()) {
			for(int i = nestedCommands.size() - 1; i > -1; i--) {
				Command cmd = (Command) nestedCommands.get(i);
				if(cmd instanceof IResourceAwareCommand) {
					try {
						Collection resources = ((IResourceAwareCommand)cmd).getModifiedResources();
						if(resources != null) {
							modifiedResources.addAll(resources);
						}
					}
					catch(Exception e) {
						LibraryEditPlugin.getDefault().getLogger().logError(e);
					}
				}
			}

		}

		return modifiedResources;
	}

	/**
	 * Clears all the refreshable features of the given descriptor
	 * 
	 * @param descriptor
	 */
	private boolean clearDescriptor(Descriptor descriptor) {
		Set excludeSynchFeatures = new HashSet(DEFAULT_SYNCH_FEATURES);
		excludeSynchFeatures.removeAll(synchFeatures);
		Set excludeFeatures;
		if (excludeSynchFeatures.isEmpty()) {
			excludeFeatures = excludeSynchFeatures;
		}
		else {
			excludeFeatures = new HashSet();
			for (Iterator iter = excludeSynchFeatures.iterator(); iter.hasNext();) {
				EStructuralFeature feature = getDescriptorFeature((EStructuralFeature) iter.next());
				if(feature != null) {
					excludeFeatures.add(feature);
				}
			}
		}
		boolean ret = ProcessCommandUtil.clearDescriptor(descriptor,
				descriptorToOldRefreshableFeaturesMap, excludeFeatures);
		if (ret && descriptor instanceof TaskDescriptor) {
			if (taskDescriptorsToUpdate == null) {
				taskDescriptorsToUpdate = new ArrayList();
			}
			taskDescriptorsToUpdate.add(descriptor);
		}
		return ret;
	}

	/**
	 * @param feature
	 * @return
	 */
	private static EStructuralFeature getDescriptorFeature(EStructuralFeature linkedElementFeature) {
		return (EStructuralFeature) FEATURE_MAP.get(linkedElementFeature);
	}
	
	protected boolean preExecute() {
		prepareDropElements();
		
		boolean b = !dropElements.isEmpty();
		if (b) {
//			descriptorToNewFeatureValuesMap = new HashMap();
			batchCommand = new DescriptorUpdateBatchCommand(false, synchFeatures, config); //TODO: why clear must be false ???

//			if (synchronize) {
//				descriptorsToRefresh = new HashSet();
//			}
		}
		return b;
	}
	
	protected boolean collectElementsToAddToDefaultConfig() {
		if (elementsToAddToDefaultConfig == null) {
			elementsToAddToDefaultConfig = new ArrayList();
			for (Iterator iter = dropElements.iterator(); iter.hasNext();) {
				Object element = iter.next();
				switch (UserInteractionHelper.checkAgainstDefaultConfiguration(
						process, element)) {
				case 0:
					iter.remove();
					break;
				case 2:
					elementsToAddToDefaultConfig.add(element);
					break;
				case -1:
					return false;
				}
			}
		}
		return true;
	}

	/**
	 * Adds elements to the default configuration
	 * 
	 * @return true if default configuration has been modified, false otherwise
	 */
	private boolean addToDefaultConfiguration() {
		if (!addedToDefaultConfig && elementsToAddToDefaultConfig != null && !elementsToAddToDefaultConfig.isEmpty()) {
			if(addedObjects == null) {
				addedObjects = new HashSet();
			}
			else {
				addedObjects.clear();
			}
			for (Iterator iter = elementsToAddToDefaultConfig.iterator(); iter
			.hasNext();) {
				EObject element = (EObject) iter.next();
				ProcessUtil.addToDefaultConfiguration(process, element,
						addedObjects);
			}
			if (!addedObjects.isEmpty()) {
				getModifiedResources().add(
						process.getDefaultContext().eResource());
				return true;
			}
			addedToDefaultConfig = true;
		}
		return false;
	}
	
	protected int getTotalWork() {
		return 20;
	}
	
	protected void worked(int unitsOfWork) {
		monitor.worked(unitsOfWork);
		workedUnits = workedUnits + unitsOfWork;
	}
	
	protected int getRemainingWork() {
		int remaining = getTotalWork() - workedUnits;
		if(remaining < 0) {
			remaining = 0;
		}
		return remaining;
	}

	protected boolean updateDefaultConfigurationNeeded() {
		return !synchronize;
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.common.command.Command#execute()
	 */
	public void execute() {		
		// BusyIndicator.showWhile(Display.getCurrent(), new Runnable() {
		//			
		// public void run() {
		// canceled = !addToDefaultConfiguration();
		// }
		//			
		// });
		//		
		// //TODO: This caused NullPointerException or ThreadAccessError when
		// showing selection dialog is needed
		// //
		// IRunnableWithProgress runnable = new IRunnableWithProgress() {
		//
		// public void run(IProgressMonitor monitor) throws
		// InvocationTargetException, InterruptedException {
		// canceled = !preExecute();
		// }
		//			
		// };
		// UserInteractionHelper.runWithProgress(runnable, null);
		//		
		// if(!canceled) {
		// BusyIndicator.showWhile(Display.getCurrent(), new Runnable() {
		//				
		// public void run() {
		// redo();
		// }
		//				
		// });
		// }

//		BusyIndicator.showWhile(Display.getCurrent(), new Runnable() {
//
//			public void run() {
//				if ((!synchronize && addToDefaultConfiguration()) && preExecute()) {
//					redo();
//				}
//			}
//
//		});
		
		if(updateDefaultConfigurationNeeded()) {
			if(!collectElementsToAddToDefaultConfig()) {
				return;
			}
		}
		
		final String taskName = (label == null ? "" : label); //$NON-NLS-1$
		IRunnableWithProgress runnable = new IRunnableWithProgress() {

			public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
				try {
					monitor.beginTask(taskName, getTotalWork());
					BSDropCommand.this.monitor = monitor;
					worked(getRemainingWork() / 3);
					
					// this must be called before preExecute() to add required elements to configuration
					// so the command can realize data correctly
					//
					addToDefaultConfiguration();
					worked(getRemainingWork() / 3);
					
					if (preExecute()) {
						worked(getRemainingWork() / 3);
						redo();
					}
				}
				finally {
					monitor.done();
				}
			}
			
		};
		if(runAsJob) {
			UserInteractionHelper.runAsJob(runnable, taskName);
		}
		else {
//			UserInteractionHelper.runInUI(runnable, (Shell)null);
			UserInteractionHelper.runWithProgress(runnable, null);
		}
	}
	
	protected List getNestedCommands() {
		if(nestedCommands == null) {
			nestedCommands = new ArrayList();
		}
		return nestedCommands;
	}
	
	protected void executeNestedCommands() {
		List nestedCommandProviders = ExtensionManager.getNestedCommandProviders();
		if(!nestedCommandProviders.isEmpty()) {
			for (Iterator iter = nestedCommandProviders.iterator(); iter
			.hasNext();) {
				INestedCommandProvider cmdProvider = (INestedCommandProvider) iter.next();
				try {
					Command cmd = cmdProvider.createNestedCommand(this);
					if(cmd != null && cmd.canExecute()) {							
						cmd.execute();
						getNestedCommands().add(cmd);
					}
				}
				catch(Exception e) {
					LibraryEditPlugin.getDefault().getLogger().logError(e);
				}
			}
		}	
	}
	
	protected void undoNestedCommands() {
		if(nestedCommands != null && !nestedCommands.isEmpty()) {
			for(int i = nestedCommands.size() - 1; i > -1; i--) {
				Command cmd = (Command) nestedCommands.get(i);
				try {
					if(cmd.canUndo()) {
						cmd.undo();
					}
				}
				catch(Exception e) {
					LibraryEditPlugin.getDefault().getLogger().logError(e);
				}
				finally {
					try { cmd.dispose(); } catch(Exception e) {}
				}
			}
			nestedCommands.clear();
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.common.command.Command#redo()
	 */
	public void redo() {
		try {
			// add elements to the default configuration if needed
			//
			addToDefaultConfiguration();
			
			doExecute();
			updateDescriptors();
			
			executeNestedCommands();
			
			executed = true;
		}
		catch(RuntimeException e) {
			e.printStackTrace();
			LibraryEditPlugin.getDefault().getLogger().logError(e);
			throw e;
		}
	}

	/**
	 * Updates descriptors
	 */
	protected void updateDescriptors() {
		if (synchronize) {
			clearDescriptors();
		}

		// update new values;
		//
		batchCommand.execute();
		
		updateTaskDescriptors();

		setResponsibleRoles();
	}

//	/**
//	 * @param desc
//	 * @param feature
//	 * @param value
//	 */
//	protected void saveOldFeatureValue(Descriptor desc,
//			EStructuralFeature feature) {
//		if (descriptorToOldFeatureValuesMap == null) {
//			descriptorToOldFeatureValuesMap = new HashMap();
//		}
//		Object value = desc.eGet(feature);
//		if(feature.isMany()) {
//			value = new ArrayList((List)value);
//		}
//		Map featureMap = (Map) descriptorToOldFeatureValuesMap.get(desc);
//		if (featureMap == null) {
//			featureMap = new HashMap();
//			descriptorToOldFeatureValuesMap.put(desc, featureMap);
//		}
//		featureMap.put(feature, value);
//	}

	protected void undoUpdateDescriptors() {
		undoSetResponsibleRole();

		undoUpdateTaskDescriptors();

		// restore old values
		//
		batchCommand.undo();

		// restore value for refreshable features that had been cleared
		//
		if (synchronize) {
			undoClearDescriptors();
		}
	}

	/**
	 * 
	 */
	private void clearDescriptors() {
		if (descriptorToOldRefreshableFeaturesMap == null) {
			descriptorToOldRefreshableFeaturesMap = new HashMap();
			if (!batchCommand.getDescriptorsToRefresh().isEmpty()) {
				for (Iterator iter = batchCommand.getDescriptorsToRefresh().iterator(); iter
						.hasNext();) {
					clearDescriptor((Descriptor) iter.next());
				}
				// descriptorsToRefresh.clear();
			}
		}
	}

	/**
	 * Updates affected task descriptors with new data from method content
	 */
	private void updateTaskDescriptors() {
		if (taskDescriptorsToUpdate != null) {
			// refresh steps from the associated task
			//
			if(synchFeatures.contains(UmaPackage.eINSTANCE.getTask_Steps())) {
				if (taskDescToNewStepsMap == null) {
					taskDescToNewStepsMap = new HashMap();
				}
				IConfigurationApplicator configApplicator = Providers
				.getConfigurationApplicator();
				for (Iterator iter = taskDescriptorsToUpdate.iterator(); iter
				.hasNext();) {
					TaskDescriptor taskDesc = (TaskDescriptor) iter.next();
					Task task = taskDesc.getTask();
					if (task != null && !((EObject) task).eIsProxy()) {
						List steps = (List) configApplicator.getReference(task
								.getPresentation(), task, UmaPackage.eINSTANCE
								.getContentDescription_Sections(), config);
						
						// add those steps to TaskDescriptor if they are not there
						// yet.
						//
						ArrayList newSteps = new ArrayList();
						taskDesc.getSelectedSteps().retainAll(steps);
						for (Iterator iter1 = steps.iterator(); iter1.hasNext();) {
							Object step = iter1.next();
							if (!taskDesc.getSelectedSteps().contains(step)) {
								newSteps.add(step);
							}
						}
						if (!newSteps.isEmpty()) {
							taskDesc.getSelectedSteps().addAll(newSteps);
							taskDescToNewStepsMap.put(taskDesc, newSteps);
//							System.out
//							.println("BSDropCommand.updateTaskDescriptors(): changed");
						}
					}
				}
			}
			
		}
	}

	private void undoUpdateTaskDescriptors() {
		if (taskDescToNewStepsMap != null) {
			for (Iterator iter = taskDescToNewStepsMap.entrySet().iterator(); iter
					.hasNext();) {
				Map.Entry entry = (Map.Entry) iter.next();
				TaskDescriptor taskDesc = (TaskDescriptor) entry.getKey();
				taskDesc.getSelectedSteps().removeAll(
						(Collection) entry.getValue());
			}
		}
	}

	/**
	 * Go thru all the work product descriptors of this activity and set the
	 * responsible role for them if there is any
	 */
	private void setResponsibleRoles() {
		if(!synchFeatures.contains(UmaPackage.eINSTANCE.getRole_ResponsibleFor())) {
			return;
		}
		
		if(refreshResponsibleForCommand != null) {
			refreshResponsibleForCommand.dispose();
		}
		refreshResponsibleForCommand = new BatchCommand(true);
 
		List brElements = activity.getBreakdownElements();
		List wpDescList = new ArrayList();
		List roleDescriptors = new ArrayList();
		for (Iterator itor = brElements.iterator(); itor.hasNext();) {
			Object obj = itor.next();
			if (obj instanceof WorkProductDescriptor) {
				wpDescList.add(obj);
			} else if (obj instanceof RoleDescriptor) {
				roleDescriptors.add(obj);
			}
		}

		for (Iterator itor = roleDescriptors.iterator(); itor.hasNext();) {
			RoleDescriptor roleDesc = (RoleDescriptor) itor.next();
			Role role = roleDesc.getRole();
			if (role != null) {				
				List responsibleWorkProducts = (List) Providers.getConfigurationApplicator().getReference(role, UmaPackage.eINSTANCE.getRole_ResponsibleFor(), config);
				List responsibleWPDList = new ArrayList();
				for (int j = wpDescList.size() - 1; j > -1; j--) {
					WorkProductDescriptor wpDesc = (WorkProductDescriptor) wpDescList
							.get(j);
//					RoleDescriptor responsibleRoleDesc = AssociationHelper.getResponsibleRoleDescriptor(wpDesc);
//					if (responsibleWorkProducts.contains(wpDesc
//							.getWorkProduct())
//							&&  responsibleRoleDesc != roleDesc) {
//						wpdToOldResponsibleRoleMap.put(wpDesc, responsibleRoleDesc);
////						wpDesc.setResponsibleRole(roleDesc);
//						roleDesc.getResponsibleFor().add(wpDesc);
//					}
					
					if(responsibleWorkProducts.contains(wpDesc.getWorkProduct())) {
						responsibleWPDList.add(wpDesc);
					}
				}				
				if(!roleDesc.getResponsibleFor().equals(responsibleWPDList)) {
					refreshResponsibleForCommand.addFeatureValues(roleDesc, UmaPackage.eINSTANCE.getRoleDescriptor_ResponsibleFor(), responsibleWPDList);
				}
			}
		}
		
		refreshResponsibleForCommand.execute();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.common.command.AbstractCommand#undo()
	 */
	public void undo() {
		undoNestedCommands();
		
		// remove any object that had been added to the default configuration
		//
		if (addedObjects != null && !addedObjects.isEmpty()) {
			MethodConfiguration config = process.getDefaultContext();
			for (Iterator iter = addedObjects.iterator(); iter.hasNext();) {
				Object element = iter.next();
				if (element instanceof MethodPlugin) {
					config.getMethodPluginSelection().remove(element);
				} else if (element instanceof MethodPackage) {
					config.getMethodPackageSelection().remove(element);
				}
			}
			addedToDefaultConfig = false;
		}

		undoUpdateDescriptors();

		doUndo();
	}

	/**
	 * 
	 */
	private void undoClearDescriptors() {
		if(descriptorToOldRefreshableFeaturesMap != null) {
			for (Iterator iter = descriptorToOldRefreshableFeaturesMap.entrySet()
					.iterator(); iter.hasNext();) {
				Map.Entry entry = (Map.Entry) iter.next();
				Descriptor desc = (Descriptor) entry.getKey();
				Map featureMap = (Map) entry.getValue();
				for (Iterator iterator = featureMap.entrySet().iterator(); iterator
				.hasNext();) {
					entry = (Map.Entry) iterator.next();
					desc
					.eSet((EStructuralFeature) entry.getKey(), entry
							.getValue());
				}
			}
		}
	}

	/**
	 * Undoes the change made by
	 * {@link #setResponsibleRoles() setResponsibleRoles() }
	 */
	private void undoSetResponsibleRole() {
//		if(wpdToOldResponsibleRoleMap != null && !wpdToOldResponsibleRoleMap.isEmpty()) {
//			for (Iterator iter = wpdToOldResponsibleRoleMap.entrySet().iterator(); iter
//			.hasNext();) {
//				Map.Entry entry = (Map.Entry) iter.next();
//				WorkProductDescriptor wpd = (WorkProductDescriptor) entry.getKey();
//				((RoleDescriptor) entry.getValue()).getResponsibleFor().remove(wpd);
//			}
//		}
		if(refreshResponsibleForCommand != null) {
			refreshResponsibleForCommand.undo();
		}
	}

	protected boolean prepare() {
		return true;
	}
	
	protected abstract void doExecute();

	protected abstract void doUndo();

	public static interface IExecutor {
		boolean preExecute();

		void doExcecute();

		void doUndo();
	}

}