//------------------------------------------------------------------------------
// 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.authoring.ui.properties;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
import org.eclipse.emf.edit.provider.ItemProviderAdapter;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
import org.eclipse.epf.authoring.ui.AuthoringUIPlugin;
import org.eclipse.epf.authoring.ui.dialogs.ItemsFilterDialog;
import org.eclipse.epf.authoring.ui.editors.MethodElementEditor;
import org.eclipse.epf.authoring.ui.editors.MethodElementEditor.ModifyListener;
import org.eclipse.epf.authoring.ui.filters.DescriptorProcessFilter;
import org.eclipse.epf.authoring.ui.filters.ProcessSpecificWorkProductFilter;
import org.eclipse.epf.authoring.ui.filters.ProcessWorkProductFilter;
import org.eclipse.epf.common.utils.StrUtil;
import org.eclipse.epf.library.edit.IFilter;
import org.eclipse.epf.library.edit.TngAdapterFactory;
import org.eclipse.epf.library.edit.command.IActionManager;
import org.eclipse.epf.library.edit.itemsfilter.FilterConstants;
import org.eclipse.epf.library.edit.process.command.AssignWPToDeliverable;
import org.eclipse.epf.library.edit.process.command.LinkMethodElementCommand;
import org.eclipse.epf.library.edit.util.ProcessUtil;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.ui.LibraryUIText;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.Artifact;
import org.eclipse.epf.uma.BreakdownElement;
import org.eclipse.epf.uma.Deliverable;
import org.eclipse.epf.uma.Process;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.WorkProduct;
import org.eclipse.epf.uma.WorkProductDescriptor;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;


/**
 * The general tab section for Work Product Descriptor
 * 
 * @author Shilpa Toraskar
 * @since 1.0
 * 
 */
public class WorkProductDescriptorGeneralSection extends
		DescriptorGeneralSection {
	protected WorkProductDescriptor element;

	private Text ctrl_method_element;

	private Text ctrl_workProduct_type;

	private Text activityEntryState, activityExitState;

	private Button linkButton;


	private Table ctrl_table_1;

	private TableViewer viewer_1;

	private Button ctrl_add_1, ctrl_add_proc_1, ctrl_remove_1;

	private Section deliverableSection;

	private ModifyListener wpModelModifyListener;

	protected void init() {
		super.init();
		// get WorkProductDescriptor object
		element = (WorkProductDescriptor) getElement();
	}

	public void createControls(Composite parent,
			TabbedPropertySheetPage tabbedPropertySheetPage) {
		super.createControls(parent, tabbedPropertySheetPage);

	}

	private void toggleSection() {
		if (!(element.getWorkProduct() instanceof Deliverable)) {
			if (deliverableSection.isExpanded())
				deliverableSection.setExpanded(false);
			if (deliverableSection.isVisible())
				deliverableSection.setVisible(false);
		} else {
			if (!deliverableSection.isExpanded())
				deliverableSection.setExpanded(true);
			if (!deliverableSection.isVisible())
				deliverableSection.setVisible(true);
		}
	}

	private void createDeliverableSection(Composite composite) {
		String sectionTitle = PropertiesResources.WPDescriptor_DeliverablePart_SectionTitle; //$NON-NLS-1$
		String sectionDesc = PropertiesResources.WPDescriptor_DeliverablePart_SectionDescription; //$NON-NLS-1$
		String tableTitle = PropertiesResources.WPDescriptor_DeliverablePart_Table1; //$NON-NLS-1$

		Section section = FormUI.createSection(toolkit, composite,
				sectionTitle, sectionDesc);

		// create composite
		Composite sectionComposite = FormUI.createComposite(toolkit, section,
				2, false);

		Composite pane1 = FormUI.createComposite(toolkit, sectionComposite,
				GridData.FILL_BOTH);
		FormUI.createLabel(toolkit, pane1, tableTitle);

		int tableHeight = 80;
		ctrl_table_1 = FormUI.createTable(toolkit, pane1, tableHeight);
		viewer_1 = new TableViewer(ctrl_table_1);
		IStructuredContentProvider contentProvider = new AdapterFactoryContentProvider(
				getAdapterFactory()) {
			public Object[] getElements(Object object) {
				List newList = new ArrayList();
				List deliverableParts = element.getDeliverableParts();
				for (Iterator itor = deliverableParts.iterator(); itor
						.hasNext();) {
					WorkProductDescriptor wpDesc = (WorkProductDescriptor) itor
							.next();
					if (wpDesc.getSuperActivities() == null
							|| wpDesc.getSuperActivities() == null)
						newList.add(wpDesc);
				}
				return getFilteredList(newList).toArray();
			}
		};

		ILabelProvider labelProvider = new AdapterFactoryLabelProvider(
				TngAdapterFactory.INSTANCE.getPBS_ComposedAdapterFactory());
		viewer_1.setContentProvider(contentProvider);
		viewer_1.setLabelProvider(labelProvider);
		viewer_1.setInput(element);

		// create buttons for table2
		Composite pane2 = FormUI.createComposite(toolkit, sectionComposite,
				GridData.VERTICAL_ALIGN_CENTER
						| GridData.HORIZONTAL_ALIGN_CENTER);

		ctrl_add_1 = FormUI.createButton(toolkit, pane2, PropertiesResources.Process_Add); //$NON-NLS-1$
		ctrl_add_proc_1 = FormUI.createButton(toolkit, pane2,
				PropertiesResources.Process_AddFromProcess); 
		ctrl_remove_1 = FormUI.createButton(toolkit, pane2, PropertiesResources.Process_Remove); //$NON-NLS-1$

		toolkit.paintBordersFor(pane1);

		deliverableSection = section;
	}

	public void dispose() {
		super.dispose();

		// if (labelProvider != null)
		// {
		// labelProvider.dispose();
		// }
	}

	protected void createGeneralSection(Composite composite) {
		super.createGeneralSection(composite);

		// method element
		FormUI.createLabel(toolkit, generalComposite, PropertiesResources.Process_Type_WorkProduct); //$NON-NLS-1$
		ctrl_method_element = FormUI.createText(toolkit, generalComposite,
				SWT.DEFAULT, 1);
		ctrl_method_element.setText(getMethodElementName(element));
		ctrl_method_element.setEnabled(false);

		linkButton = FormUI
				.createButton(toolkit, generalComposite, SWT.PUSH, 1);
		linkButton.setText(PropertiesResources.Process_Button_LinkMethodElement); //$NON-NLS-1$

		FormUI.createLabel(toolkit, generalComposite, "", 1); //$NON-NLS-1$

		// type
		FormUI.createLabel(toolkit, generalComposite, PropertiesResources.WorkProduct_Type); //$NON-NLS-1$
		ctrl_workProduct_type = FormUI.createText(toolkit, generalComposite,
				SWT.DEFAULT, horizontalSpan);
		ctrl_workProduct_type.setText(getMethodElementType(element));
		ctrl_workProduct_type.setEnabled(false);

		// activityEntrystate
		FormUI.createLabel(toolkit, generalComposite, PropertiesResources.WorkProductDescriptor_ActivityEntryState); //$NON-NLS-1$
		activityEntryState = FormUI.createText(toolkit, generalComposite,
				SWT.DEFAULT, horizontalSpan);

		// activityExitstate
		FormUI.createLabel(toolkit, generalComposite, PropertiesResources.WorkProductDescriptor_ActivityExitState); //$NON-NLS-1$
		activityExitState = FormUI.createText(toolkit, generalComposite,
				SWT.DEFAULT, horizontalSpan);

		// CREATE DELIVERABLE SECTION
		createDeliverableSection(composite);
		toggleSection();

	}

	private String getMethodElementName(WorkProductDescriptor element) {
		String str = PropertiesResources.Process_None; 
		if (element.getWorkProduct() != null) {
			str = element.getWorkProduct().getName();
		}

		return str;
	}

	private String getMethodElementType(WorkProductDescriptor element) {
		String str = PropertiesResources.Process_None; 
		if (element.getWorkProduct() != null) {
			str = element.getWorkProduct().getType().getName();
		}

		return str;
	}

	protected void addListeners() {
		super.addListeners();

		activityEntryState.addFocusListener(new FocusAdapter() {
			public void focusGained(FocusEvent e) {
				((MethodElementEditor) getEditor()).setCurrentFeatureEditor(e.widget,
						UmaPackage.eINSTANCE.getWorkProductDescriptor_ActivityEntryState());
			}
		
			public void focusLost(FocusEvent e) {
				WorkProductDescriptor element = (WorkProductDescriptor) getElement();
				String oldContent = element.getActivityEntryState();
				if (((MethodElementEditor) getEditor()).mustRestoreValue(
						activityEntryState, oldContent)) {
					return;
				}
				String newContent = StrUtil.getPlainText(activityEntryState
						.getText());
				if (!newContent.equals(oldContent)) {
					boolean status = actionMgr
							.doAction(
									IActionManager.SET,
									element,
									UmaPackage.eINSTANCE
											.getWorkProductDescriptor_ActivityEntryState(),
									newContent, -1);
					if (status) {
						activityEntryState.setText(newContent);
					}
				}
			}
		});

		activityExitState.addFocusListener(new FocusAdapter() {
			public void focusGained(FocusEvent e) {
				((MethodElementEditor) getEditor()).setCurrentFeatureEditor(e.widget,
						UmaPackage.eINSTANCE.getWorkProductDescriptor_ActivityExitState());
			}
			
			public void focusLost(FocusEvent e) {
				WorkProductDescriptor element = (WorkProductDescriptor) getElement();
				String oldContent = element.getActivityExitState();
				if (((MethodElementEditor) getEditor()).mustRestoreValue(
						activityExitState, oldContent)) {
					return;
				}
				String newContent = StrUtil.getPlainText(activityExitState
						.getText());
				if (!newContent.equals(oldContent)) {
					boolean status = actionMgr
							.doAction(
									IActionManager.SET,
									element,
									UmaPackage.eINSTANCE
											.getWorkProductDescriptor_ActivityExitState(),
									newContent, -1);
					if (status) {
						activityExitState.setText(newContent);
					}
				}
			}
		});

		ctrl_table_1.addFocusListener(new FocusAdapter() {
			public void focusGained(FocusEvent e) {
				IStructuredSelection selection = (IStructuredSelection) viewer_1
						.getSelection();
				if (selection.size() > 0)
					ctrl_remove_1.setEnabled(true);
			}
		});

		ctrl_add_1.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				IFilter filter = new ProcessWorkProductFilter(
						getConfiguration(), null, FilterConstants.WORKPRODUCTS); //$NON-NLS-1$
				// block it's deliverable parts
				List existingElements = new ArrayList();
				existingElements
						.addAll(ProcessUtil
								.getAssociatedElementList(((WorkProductDescriptor) element)
										.getDeliverableParts()));
				// block itself
				existingElements.add(ProcessUtil
						.getAssociatedElement((WorkProductDescriptor) element));
				// also block it's parent work products, if any
				existingElements
						.addAll((Collection) getParentWorkProducts((WorkProductDescriptor) element));

				ItemsFilterDialog fd = new ItemsFilterDialog(PlatformUI
						.getWorkbench().getActiveWorkbenchWindow().getShell(),
						filter, element, FilterConstants.WORKPRODUCTS,
						existingElements);
				fd.setBlockOnOpen(true);
				fd.setTitle(FilterConstants.WORKPRODUCTS);
				fd.open();
				addItems(fd.getSelectedItems());
				viewer_1.refresh();

			}
		});

		ctrl_add_proc_1.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				String tabName = FilterConstants.WORK_PRODUCT_DESCRIPTORS;
				List existingElements = new ArrayList();
				existingElements.addAll(((WorkProductDescriptor) element)
						.getDeliverableParts());
				existingElements.add(element);

				existingElements
						.addAll(getParentDeliverables((WorkProductDescriptor) element));
				Process process = TngUtil.getOwningProcess(element);

				IFilter descriptorFilter = getDescriptorFilter();
				if (descriptorFilter != null && process != null) {
					ItemsFilterDialog fd = new ItemsFilterDialog(PlatformUI
							.getWorkbench().getActiveWorkbenchWindow()
							.getShell(), descriptorFilter, process, tabName,
							existingElements);
					fd.setBlockOnOpen(true);
					fd.setTitle(tabName);
					fd.open();
					addFromProcessItems(fd.getSelectedItems());
					viewer_1.refresh();
				}
			}
		});

		ctrl_remove_1.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				IStructuredSelection selection = (IStructuredSelection) viewer_1
						.getSelection();
				if (selection.size() > 0) {
					// update the model
					ArrayList rmItems = new ArrayList();
					rmItems.addAll(selection.toList());
					removeItems(rmItems);
					viewer_1.refresh();

					// clear the selection
					viewer_1.setSelection(null, true);

				}
			}
		});

		linkButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				String tabName = FilterConstants.WORKPRODUCTS; //$NON-NLS-1$
				Class workProductType = null;
				if (element.getWorkProduct() != null) {
					workProductType = element.getWorkProduct().getClass();
				}
				List existingElements = new ArrayList();
				if (element.getWorkProduct() != null) {
					WorkProduct wp = element.getWorkProduct();
					existingElements.add(wp);
					if (wp instanceof Artifact) {
						List subArtifacts = new ArrayList();
						getAllSubArtifacts((Artifact) wp, subArtifacts,
								((Artifact) wp).getContainedArtifacts());
						existingElements.addAll(subArtifacts);
					}
				}

				List list = ProcessUtil
						.getSiblings(TngAdapterFactory.INSTANCE
								.getPBS_ComposedAdapterFactory(), getAdapter(),
								element);

				for (Iterator itor = list.iterator(); itor.hasNext();) {
					Object obj = itor.next();
					if (obj instanceof WorkProductDescriptor) {
						WorkProductDescriptor wpDesc = (WorkProductDescriptor) obj;
						if ((!wpDesc.equals(element))
								&& (!wpDesc.getSuppressed().booleanValue())) {
							WorkProduct wp = wpDesc.getWorkProduct();

							if (wp != null) {
								existingElements.add(wp);

								if (wp instanceof Artifact) {
									List subArtifacts = new ArrayList();
									getAllSubArtifacts((Artifact) wp,
											subArtifacts, ((Artifact) wp)
													.getContainedArtifacts());
									existingElements.addAll(subArtifacts);
								}
							}
						}
					}
				}
				IFilter filter = new ProcessSpecificWorkProductFilter(
						getConfiguration(), null, tabName, workProductType);

				ItemsFilterDialog fd = new ItemsFilterDialog(PlatformUI
						.getWorkbench().getActiveWorkbenchWindow().getShell(),
						filter, element, tabName, existingElements);

				fd.setBlockOnOpen(true);
				fd.setViewerSelectionSingle(true);
				fd.setTitle(tabName);
				fd.open();
				setMethodElement(fd.getSelectedItems());

				// update method element control
				ctrl_method_element.setText(getMethodElementName(element));
			}

			public void widgetDefaultSelected(SelectionEvent e1) {
			}
		});
	}

	private void getAllSubArtifacts(Artifact artifact, List subArtifacts,
			List containedArtifacts) {
		for (Iterator itor = containedArtifacts.iterator(); itor.hasNext();) {
			Object obj = (Object) itor.next();
			if (obj instanceof Artifact) {
				if (!subArtifacts.contains(obj))
					subArtifacts.add(obj);
				getAllSubArtifacts((Artifact) obj, subArtifacts,
						((Artifact) obj).getContainedArtifacts());
			}
		}
	}

	protected void updateControls() {
		super.updateControls();
		activityEntryState.setEditable(editable);
		activityExitState.setEditable(editable);
		linkButton.setEnabled(editable);

		if (ctrl_add_1 != null)
			ctrl_add_1.setEnabled(editable);
		if (ctrl_add_proc_1 != null)
			ctrl_add_proc_1.setEnabled(editable);
		if (ctrl_remove_1 != null)
			ctrl_remove_1.setEnabled(editable);
	}

	/*
	 * @see org.eclipse.wst.common.ui.properties.view.ITabbedPropertySection#refresh()
	 */
	public void refresh() {
		try {
			if (getElement() instanceof WorkProductDescriptor) {
				element = (WorkProductDescriptor) getElement();

				super.refresh();

				// Model Modify listener for activity entry state and activity
				// exit state
				if (wpModelModifyListener != null) {
					activityEntryState
							.removeModifyListener(wpModelModifyListener);
					activityExitState
							.removeModifyListener(wpModelModifyListener);

				}

				wpModelModifyListener = getEditor().createModifyListener(
						(WorkProductDescriptor) element);

				if (wpModelModifyListener instanceof MethodElementEditor.ModifyListener) {
					((MethodElementEditor.ModifyListener) wpModelModifyListener)
							.setElement(element);
					((MethodElementEditor.ModifyListener) wpModelModifyListener)
							.setDisable(true);
				}

				ctrl_method_element.setText(getMethodElementName(element));
				ctrl_workProduct_type.setText(getMethodElementType(element));
				activityEntryState.setText(element.getActivityEntryState());
				activityExitState.setText(element.getActivityExitState());

				if (wpModelModifyListener instanceof MethodElementEditor.ModifyListener) {
					((MethodElementEditor.ModifyListener) wpModelModifyListener)
							.setDisable(false);
				}

				activityEntryState.addModifyListener(wpModelModifyListener);
				activityExitState.addModifyListener(wpModelModifyListener);

				if (viewer_1 != null) {
					viewer_1.refresh();
				}

				// hide/show certain sections.
				toggleSection();

			}

		} catch (Exception ex) {
			logger
					.logError(
							"Error refreshing WorkProductDescriptor general section : " + element, ex); //$NON-NLS-1$
		}
	}

	private void addItems(List items) {
		if (items != null) {
			List wps = new ArrayList();

			for (Iterator itor = items.iterator(); itor.hasNext();) {
				Object obj = itor.next();
				if ((obj instanceof WorkProduct)
						&& (!isPartOfDeliverable((WorkProduct) obj,
								(WorkProductDescriptor) element))) {
					wps.add((WorkProduct) obj);

				}
			}
			if (!wps.isEmpty()) {
				AssignWPToDeliverable cmd = new AssignWPToDeliverable(
						(WorkProductDescriptor) element, wps);
				actionMgr.execute(cmd);
			}
		}
		viewer_1.refresh();
	}

	protected IFilter getDescriptorFilter() {

		return new DescriptorProcessFilter(getConfiguration()) {
			protected boolean childAccept(Object obj) {
				if (obj instanceof Activity) {
					List list = new ArrayList();
					getActivitiesInScope(TngAdapterFactory.INSTANCE
							.getPBS_ComposedAdapterFactory(), element, list);
					if (list.contains(obj))
						return true;
					else
						return false;
				}
				if (obj instanceof WorkProductDescriptor)
					return true;
				return false;
			}
		};
	}

	private void addFromProcessItems(List items) {
		if (items != null) {
			for (Iterator itor = items.iterator(); itor.hasNext();) {
				Object obj = itor.next();
				if (obj instanceof WorkProductDescriptor) {
					WorkProduct wp = ((WorkProductDescriptor) obj)
							.getWorkProduct();
					if (wp != null) {
						if (!isPartOfDeliverable(wp,
								(WorkProductDescriptor) element)) {
							WorkProductDescriptor wpDesc = ProcessUtil
									.createWorkProductDescriptor(wp);
							actionMgr
									.doAction(
											IActionManager.ADD,
											element,
											UmaPackage.eINSTANCE
													.getWorkProductDescriptor_DeliverableParts(),
											wpDesc, -1);
						}
						actionMgr
								.doAction(
										IActionManager.ADD,
										element,
										UmaPackage.eINSTANCE
												.getWorkProductDescriptor_DeliverableParts(),
										obj, -1);
						
					} else {
						MessageFormat mf = new MessageFormat(
								PropertiesResources.Process_DeliverableAssignError); //$NON-NLS-1$
						Object[] args = {
								((WorkProductDescriptor) obj).getName(),
								((WorkProductDescriptor) element).getName() };
						AuthoringUIPlugin
								.getDefault()
								.getMsgDialog()
								.displayInfo(
										PropertiesResources.Process_AssignmentInfoTitle, mf.format(args)); //$NON-NLS-1$
					}
				}
			}
		}

	}

	private void removeItems(List items) {
		if (!items.isEmpty()) {
			for (Iterator itor = items.iterator(); itor.hasNext();) {
				Object obj = (Object) itor.next();
				if (obj instanceof WorkProductDescriptor) {
					actionMgr
							.doAction(
									IActionManager.REMOVE,
									element,
									UmaPackage.eINSTANCE
											.getWorkProductDescriptor_DeliverableParts(),
									(WorkProductDescriptor) obj, -1);
				}

				// find matching deliverable parts
				Object wpDesc = findDeliverableParts((Object) obj);
				actionMgr.doAction(IActionManager.REMOVE, element,
						UmaPackage.eINSTANCE
								.getWorkProductDescriptor_DeliverableParts(),
						wpDesc, -1);
			}
		}
	}

	private Object findDeliverableParts(Object obj) {
		List parts = ((WorkProductDescriptor) element).getDeliverableParts();

		for (Iterator itor = parts.iterator(); itor.hasNext();) {
			Object itorObject = itor.next();
			if (obj instanceof WorkProductDescriptor) {
				if (itorObject instanceof WorkProductDescriptor) {
					Object objWP = ((WorkProductDescriptor) obj)
							.getWorkProduct();
					Object itorWP = ((WorkProductDescriptor) itorObject)
							.getWorkProduct();
					if (objWP.equals(itorWP)) {
						return itorObject;
					}
				}
			}
		}

		return null;
	}

	/**
	 * Find parent process
	 * 
	 * @param element
	 * @return
	 */
	protected Object getProcess(BreakdownElement brElement) {
		AdapterFactory aFactory = TngAdapterFactory.INSTANCE
				.getPBS_ComposedAdapterFactory();
		ItemProviderAdapter adapter = (ItemProviderAdapter) aFactory.adapt(
				brElement, ITreeItemContentProvider.class);
		Object parent = adapter.getParent(brElement);
		while (!(parent instanceof Process)) {
			brElement = (BreakdownElement) parent;
			adapter = (ItemProviderAdapter) aFactory.adapt(brElement,
					ITreeItemContentProvider.class);
			parent = adapter.getParent(brElement);
		}
		return parent;
	}

	/**
	 * Get parent deliverables
	 * 
	 * @param brElement
	 * @return
	 */
	private List getParentDeliverables(BreakdownElement brElement) {
		List parentDeliverables = new ArrayList();
		AdapterFactory aFactory = TngAdapterFactory.INSTANCE
				.getPBS_ComposedAdapterFactory();
		ItemProviderAdapter adapter = (ItemProviderAdapter) aFactory.adapt(
				brElement, ITreeItemContentProvider.class);
		Object parent = adapter.getParent(brElement);
		while (!(parent instanceof Activity)) {
			brElement = (BreakdownElement) parent;
			if (parent instanceof WorkProductDescriptor) {
				WorkProductDescriptor wpdesc = (WorkProductDescriptor) parent;
				if (wpdesc.getWorkProduct() instanceof Deliverable) {
					parentDeliverables.add(wpdesc);
				}
			}
			adapter = (ItemProviderAdapter) aFactory.adapt(brElement,
					ITreeItemContentProvider.class);
			parent = adapter.getParent(brElement);
		}
		return parentDeliverables;
	}
	/**
	 * Find all sibling work products
	 * 
	 * @param element
	 * @return
	 */
	private Object getParentWorkProducts(BreakdownElement brElement) {
		HashSet workProducts = new HashSet();

		AdapterFactory aFactory = TngAdapterFactory.INSTANCE
				.getPBS_ComposedAdapterFactory();
		ItemProviderAdapter adapter = (ItemProviderAdapter) aFactory.adapt(
				brElement, ITreeItemContentProvider.class);
		Object parent = adapter.getParent(brElement);
		while (!(parent instanceof Activity)) {
			brElement = (BreakdownElement) parent;
			if (parent instanceof WorkProductDescriptor) {
				WorkProductDescriptor wpdesc = (WorkProductDescriptor) parent;
				if (wpdesc.getWorkProduct() instanceof Deliverable) {
					workProducts.add(wpdesc.getWorkProduct());
				}
			}
			adapter = (ItemProviderAdapter) aFactory.adapt(brElement,
					ITreeItemContentProvider.class);
			parent = adapter.getParent(brElement);
		}

		if (parent instanceof Activity) {
			List brElements = ((Activity) parent).getBreakdownElements();
			for (Iterator itor = brElements.iterator(); itor.hasNext();) {
				Object obj = (Object) itor.next();
				if (obj instanceof WorkProductDescriptor) {
					WorkProduct wp = ((WorkProductDescriptor) obj)
							.getWorkProduct();
					if (wp != null)
						workProducts.add(wp);
				}
			}
		}
		return workProducts;
	}

	public String getNamePrefix() {
		return LibraryUIText.TEXT_WORK_PRODUCT_DESCRIPTOR + ": "; //$NON-NLS-1$
	}

	private void setMethodElement(List items) {
		if ((items != null) && (items.size() >= 1)) {
			if (items.get(0) instanceof WorkProduct) {
				WorkProduct wp = (WorkProduct) items.get(0);

				List list = ProcessUtil
						.getSiblings(TngAdapterFactory.INSTANCE
								.getPBS_ComposedAdapterFactory(), getAdapter(),
								element);
				boolean canAssign = true;
				for (Iterator itor = list.iterator(); itor.hasNext();) {
					Object obj = itor.next();
					if (obj instanceof WorkProductDescriptor) {
						WorkProductDescriptor wpDesc = (WorkProductDescriptor) obj;
						if ((!wpDesc.equals(element))
								&& (!wpDesc.getSuppressed().booleanValue())) {
							WorkProduct exisingWP = wpDesc.getWorkProduct();
							if (wp.equals(exisingWP)) {
								canAssign = false;
								break;
							}
						}
					}
				}
				if (canAssign) {
					LinkMethodElementCommand cmd = new LinkMethodElementCommand(
							element, wp,
							UmaPackage.WORK_PRODUCT_DESCRIPTOR__WORK_PRODUCT);
					actionMgr.execute(cmd);

					// set selection to same element to enable correct actions
					getEditor().setSelection(getSelection());
				} else {
					MessageFormat mf = new MessageFormat(PropertiesResources.Process_InvalidLinkMethodElement); //$NON-NLS-1$
					Object[] args = { wp.getName() };
					AuthoringUIPlugin
							.getDefault()
							.getMsgDialog()
							.displayInfo(
									PropertiesResources.Process_LinkMethodElementTitle, mf.format(args)); //$NON-NLS-1$
				}
			}
		}
	}

	private boolean isPartOfDeliverable(WorkProduct wp,
			WorkProductDescriptor deliverable) {

		List deliverableParts = ProcessUtil
				.getAssociatedElementList(deliverable.getDeliverableParts());
		if (deliverableParts.contains(wp))
			return true;

		return false;
	}
}
