//------------------------------------------------------------------------------
// 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.util.ArrayList;
import java.util.List;

import org.eclipse.epf.authoring.ui.dialogs.ItemsFilterDialog;
import org.eclipse.epf.library.edit.IFilter;
import org.eclipse.epf.library.edit.command.IActionManager;
import org.eclipse.epf.library.edit.util.DescriptorPropUtil;
import org.eclipse.epf.library.edit.util.ProcessUtil;
import org.eclipse.epf.uma.BreakdownElement;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.Process;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableViewer;
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.layout.GridLayout;
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.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;


/**
 * The base class used to display relationships between descriptors
 * 
 * @author Shilpa Toraskar
 * @since 1.0
 * 
 */
public class RelationSection extends AbstractSection {
	protected ILabelProvider labelProvider = null;

	protected IStructuredContentProvider contentProvider = null;

	// element
	protected BreakdownElement element;

	// action manager
	protected IActionManager actionMgr;

	private FormToolkit toolkit;

	protected Button ctrl_add_1, ctrl_add_2, ctrl_add_3, ctrl_add_4;

	protected Button ctrl_remove_1, ctrl_remove_2, ctrl_remove_3, ctrl_remove_4;

	private Button ctrl_add_proc_1, ctrl_add_proc_2, ctrl_add_proc_3,
			ctrl_add_proc_4;;

	private Table ctrl_table_1, ctrl_table_2, ctrl_table_3, ctrl_table_4;

	protected TableViewer tableViewer1, tableViewer2, tableViewer3,
			tableViewer4;

	protected Text ctrl_brief_desc;

	protected String tabString;
	
	private String title, desc, table1, table2, table3, table4;

	private int tableCount;

	private boolean[] changesAllowed;

	Process process;

	IFilter descriptorProcessfilter;
	
	protected DescriptorPropUtil propUtil = DescriptorPropUtil.getDesciptorPropUtil();
	
	protected Process getProcess() {
		return process;
	}

	protected IFilter getFilterForDescriptors() {
		return descriptorProcessfilter;
	}

	protected String getDescriptorTabName() {
		return null;
	}


	/**
	 * @see org.eclipse.epf.authoring.ui.properties.AbstractSection#createControls(org.eclipse.swt.widgets.Composite, org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage)
	 */
	public void createControls(Composite parent,
			TabbedPropertySheetPage tabbedPropertySheetPage) {

		super.createControls(parent, tabbedPropertySheetPage);
		init();

		parent.setLayout(new GridLayout());
		parent.setLayoutData(new GridData(GridData.FILL_BOTH));

		// create section
		createSection(parent);

		// add listeners
		addListeners();

		// update controls
		updateControls();
	}

	protected void setTabData(String title, String desc, String table1, String table2, String table3, String table4, String tabString) {
		this.title = title;
		this.desc = desc;
		this.table1 = table1;
		this.table2 = table2;
		this.table3 = table3;
		this.table4 = table4;
		
		this.tabString = tabString;
	}

	protected void setTableData(int tableCount, boolean[] changesAllowed) {
		this.tableCount = tableCount;
		this.changesAllowed = changesAllowed;
	}

	protected void init() {
		// get descriptor object
		element = (BreakdownElement) getElement();

		// get toolkit
		toolkit = getWidgetFactory();

		// get action manager
		actionMgr = EPFPropertySheetPage.getActionManager();
	}


	/* (non-Javadoc)
	 * @see org.eclipse.ui.views.properties.tabbed.AbstractPropertySection#refresh()
	 */
	public void refresh() {
		try {
			if (getElement() instanceof BreakdownElement) {
				element = (BreakdownElement) getElement();

				initContentProvider1();
				initContentProvider2();
				initContentProvider3();
				initContentProvider4();

				// hide/show controls based on editable
				updateControls();
			}
		} catch (Exception ex) {
			logger
					.logError(
							"Error refreshing descriptor relation section: " + element, ex); //$NON-NLS-1$
		}
	}

	/**
	 * Update controls based on editable boolean value. Controls could be
	 * editable or read-only after this.
	 */
	public void updateControls() {
		// System.out.println("Element "+element.getName() +
		// "Editable-"+editable);
		if (ctrl_add_1 != null)
			ctrl_add_1.setEnabled(editable);
		if (ctrl_add_2 != null)
			ctrl_add_2.setEnabled(editable);
		if (ctrl_add_3 != null)
			ctrl_add_3.setEnabled(editable);
		if (ctrl_add_4 != null)
			ctrl_add_4.setEnabled(editable);

		if (ctrl_add_proc_1 != null)
			ctrl_add_proc_1.setEnabled(editable);
		if (ctrl_add_proc_2 != null)
			ctrl_add_proc_2.setEnabled(editable);
		if (ctrl_add_proc_3 != null)
			ctrl_add_proc_3.setEnabled(editable);
		if (ctrl_add_proc_4 != null)
			ctrl_add_proc_4.setEnabled(editable);

		IStructuredSelection selection = (IStructuredSelection) tableViewer1
				.getSelection();
		if (selection.size() > 0 && editable) {
			ctrl_remove_1.setEnabled(true);
		} else {
			ctrl_remove_1.setEnabled(false);
		}

		if (tableViewer2 != null) {
			selection = (IStructuredSelection) tableViewer2.getSelection();
			if (selection.size() > 0 && editable) {
					if (ctrl_remove_2 != null)
				ctrl_remove_2.setEnabled(true);
			} else {
					if (ctrl_remove_2 != null)
				ctrl_remove_2.setEnabled(false);
			}
		}

		if (tableViewer3 != null) {
			selection = (IStructuredSelection) tableViewer3.getSelection();
			if (selection.size() > 0 && editable) {
				ctrl_remove_3.setEnabled(true);
			} else {
				ctrl_remove_3.setEnabled(false);
			}
		}

		if (tableViewer4 != null) {
			selection = (IStructuredSelection) tableViewer4.getSelection();
			if (selection.size() > 0 && editable) {
				ctrl_remove_4.setEnabled(true);
			} else {
				ctrl_remove_4.setEnabled(false);
			}
		}
	}

	/**
	 * Dispose all label and content providers
	 */
	public void dispose() {
		super.dispose();
		if (labelProvider != null) {
			labelProvider.dispose();
		}
		if (contentProvider != null) {
			contentProvider.dispose();
		}
	}

	/**
	 * Initialize content provider for the first table in properties view
	 *
	 */
	protected void initContentProvider1() {
	}

	/**
	 * Initialize content provider for the second table in properties view
	 *
	 */
	protected void initContentProvider2() {
	}

	/**
	 * Initialize content provider for the third table in properties view
	 *
	 */
	protected void initContentProvider3() {
	}

	/**
	 * Initialize content provider for the fourth table in properties view
	 *
	 */
	protected void initContentProvider4() {
	}
	
	protected void initLabelProvider1() {
		
	}
	
	protected void initLabelProvider2() {
		
	}

	protected void initLabelProvider3() {
		
	}
	
	protected void initLabelProvider4() {
		
	}

	/**
	 * Get list of descriptors from the process
	 * @return
	 * 			List of descriptors
	 */
	protected List getDescriptorsFromProcess() {
		return null;
	}

	/**
	 * Returns filter which allows filtering element based on method configuration 
	 * @return
	 * 		Filter
	 */
	protected IFilter getFilter() {
		return null;
	}

	protected void createSection(Composite composite) {
		int tableHeight = 80;

		// create section
		Section aSection = FormUI.createSection(toolkit, composite,
				title, desc);

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

		// create table 1
		int count = 0;
		{
			Composite pane1 = FormUI.createComposite(toolkit, sectionComposite,
					GridData.FILL_BOTH);
			FormUI.createLabel(toolkit, pane1, table1);

			ctrl_table_1 = FormUI.createTable(toolkit, pane1, tableHeight);
			tableViewer1 = new TableViewer(ctrl_table_1);
			initContentProvider1();
			if (isSyncFree()) {
				initLabelProvider1();
			} else {			
				tableViewer1.setLabelProvider(labelProvider);
			}
			tableViewer1.setInput(element);

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

			if (changesAllowed[count]) {
				ctrl_add_1 = FormUI.createButton(toolkit, pane2,
						PropertiesResources.Process_Add); 
				ctrl_add_proc_1 = FormUI
						.createButton(toolkit, pane2, PropertiesResources.Process_AddFromProcess); 
				ctrl_remove_1 = FormUI.createButton(toolkit, pane2,
						PropertiesResources.Process_Remove); 
				ctrl_remove_1.setEnabled(false);
			}
			toolkit.paintBordersFor(pane1);
		}
		count++;

		// create table2
		if (count < tableCount) {
			Composite pane3 = FormUI.createComposite(toolkit, sectionComposite,
					GridData.FILL_BOTH);
			FormUI.createLabel(toolkit, pane3, table2);

			ctrl_table_2 = FormUI.createTable(toolkit, pane3, tableHeight);
			tableViewer2 = new TableViewer(ctrl_table_2);
			initContentProvider2();
			if (isSyncFree()) {
				initLabelProvider2();
			} else {
				tableViewer2.setLabelProvider(labelProvider);
			}
			tableViewer2.setInput(element);

			// create buttons for table2
			Composite pane4 = FormUI.createComposite(toolkit, sectionComposite,
					GridData.VERTICAL_ALIGN_CENTER
							| GridData.HORIZONTAL_ALIGN_CENTER);
			if (changesAllowed[count]) {
				ctrl_add_2 = FormUI.createButton(toolkit, pane4,
						PropertiesResources.Process_Add); 
				ctrl_add_proc_2 = FormUI
						.createButton(toolkit, pane4, PropertiesResources.Process_AddFromProcess); 
				ctrl_remove_2 = FormUI.createButton(toolkit, pane4,
						PropertiesResources.Process_Remove); 
				ctrl_remove_2.setEnabled(false);
			}
			toolkit.paintBordersFor(pane3);
		}

		count++;

		// Create table3
		if (count < tableCount) {
			Composite pane5 = FormUI.createComposite(toolkit, sectionComposite,
					GridData.FILL_BOTH);
			FormUI.createLabel(toolkit, pane5, table3);

			ctrl_table_3 = FormUI.createTable(toolkit, pane5, tableHeight);
			tableViewer3 = new TableViewer(ctrl_table_3);
			initContentProvider3();
			if (isSyncFree()) {
				initLabelProvider3();
			} else {
				tableViewer3.setLabelProvider(labelProvider);
			}
			tableViewer3.setInput(element);

			// create buttons for table2
			Composite pane6 = FormUI.createComposite(toolkit, sectionComposite,
					GridData.VERTICAL_ALIGN_CENTER
							| GridData.HORIZONTAL_ALIGN_CENTER);
			if ((new Boolean(changesAllowed[count])).booleanValue()) {
				ctrl_add_3 = FormUI.createButton(toolkit, pane6,
						PropertiesResources.Process_Add); 
				ctrl_add_proc_3 = FormUI
						.createButton(toolkit, pane6, PropertiesResources.Process_AddFromProcess); 
				ctrl_remove_3 = FormUI.createButton(toolkit, pane6,
						PropertiesResources.Process_Remove); 
				ctrl_remove_3.setEnabled(false);
			}
			toolkit.paintBordersFor(pane5);
		}
		count++;

		if (count < tableCount) {
			Composite pane7 = FormUI.createComposite(toolkit, sectionComposite,
					GridData.FILL_BOTH);
			FormUI.createLabel(toolkit, pane7, table4);

			ctrl_table_4 = FormUI.createTable(toolkit, pane7, tableHeight);
			tableViewer4 = new TableViewer(ctrl_table_4);
			initContentProvider4();
			if (isSyncFree()) {
				initLabelProvider4();
			} else {
				tableViewer4.setLabelProvider(labelProvider);
			}
			tableViewer4.setInput(element);

			// create buttons for table4
			Composite pane8 = FormUI.createComposite(toolkit, sectionComposite,
					GridData.VERTICAL_ALIGN_CENTER
							| GridData.HORIZONTAL_ALIGN_CENTER);
			if ((new Boolean(changesAllowed[count])).booleanValue()) {
				ctrl_add_4 = FormUI.createButton(toolkit, pane8,
						PropertiesResources.Process_Add); 
				ctrl_add_proc_4 = FormUI
						.createButton(toolkit, pane8, PropertiesResources.Process_AddFromProcess); 
				ctrl_remove_4 = FormUI.createButton(toolkit, pane8,
						PropertiesResources.Process_Remove); 
				ctrl_remove_4.setEnabled(false);
			}
			toolkit.paintBordersFor(pane8);

		}

		// create brief description
		int heightHint = 40;
		// int horizontalSpan = 2;
		FormUI.createLabel(toolkit, sectionComposite, PropertiesResources.Process_briefDescription, heightHint); 
		ctrl_brief_desc = FormUI.createText(toolkit, sectionComposite,
				heightHint, heightHint);
		ctrl_brief_desc.setEditable(false);

		toolkit.paintBordersFor(sectionComposite);
	}

	/**
	 * addListerers
	 * 
	 */
	protected void addListeners() {
		/**
		 * First set of listeners
		 */
		int count = 0;
		if (count < tableCount) {
			ctrl_table_1.addFocusListener(new FocusAdapter() {
				public void focusGained(FocusEvent e) {
					IStructuredSelection selection = (IStructuredSelection) tableViewer1
							.getSelection();
					if ((selection.size() > 0) && editable)
						ctrl_remove_1.setEnabled(true);
				}
			});

			tableViewer1
					.addSelectionChangedListener(new ISelectionChangedListener() {
						public void selectionChanged(SelectionChangedEvent event) {
							IStructuredSelection selection = (IStructuredSelection) tableViewer1
									.getSelection();
							if ((selection.size() > 0) & editable) {
								if (isSyncFree()) {
									syncFreeUpdateBtnStatus1(selection);
								} else {
									ctrl_remove_1.setEnabled(true);
								}
							}
							
							if (selection.size() == 1) {
								String desc = ((MethodElement) selection
										.getFirstElement())
										.getBriefDescription();
								if (desc == null) {
									desc = ""; //$NON-NLS-1$
								}
								ctrl_brief_desc.setText(desc);
							} else if (selection.size() > 1) {
								ctrl_brief_desc
										.setText(PropertiesResources.Process_MultipleSelection + " - " + selection.size()); //$NON-NLS-1$ 
							}
						}
					});

			if (changesAllowed[count]) {
				ctrl_add_1.addSelectionListener(new SelectionAdapter() {
					public void widgetSelected(SelectionEvent e) {
						if (isSyncFree()) {
							IStructuredSelection selection = (IStructuredSelection) tableViewer1.getSelection();
							if (syncFreeAdd1(selection)) { 
								tableViewer1.refresh();
								return;
							}
						}
						
						IFilter filter = getFilter();
						List existingElements = null;
						if (isSyncFree()) {
							existingElements = getExistingContentElements1();
						} else {
							existingElements = ProcessUtil.getAssociatedElementList(getExistingElements1());
						}
						ItemsFilterDialog fd = new ItemsFilterDialog(PlatformUI
								.getWorkbench().getActiveWorkbenchWindow()
								.getShell(), filter, element, tabString,
								existingElements);

						fd.setBlockOnOpen(true);
						fd.setTitle(tabString);
						fd.open();
						addItems1(fd.getSelectedItems());
						tableViewer1.refresh();
					}
					
				});

				ctrl_add_proc_1.addSelectionListener(new SelectionAdapter() {
					public void widgetSelected(SelectionEvent e) {						
						descriptorProcessfilter = getFilterForDescriptors();
						process = getProcess();
						if (descriptorProcessfilter != null && process != null) {
							List existingElements = getExistingElements1();
							ItemsFilterDialog fd = new ItemsFilterDialog(
									PlatformUI.getWorkbench()
											.getActiveWorkbenchWindow()
											.getShell(),
									descriptorProcessfilter, process,
									getDescriptorTabName(), existingElements);

							fd.setBlockOnOpen(true);
							fd.open();
							addFromProcessItems1(fd.getSelectedItems());
							tableViewer1.refresh();
						}						
					}
				});

				ctrl_remove_1.addSelectionListener(new SelectionAdapter() {
					public void widgetSelected(SelectionEvent e) {
						if (isSyncFree()) {
							IStructuredSelection selection = (IStructuredSelection) tableViewer1.getSelection();
							if (syncFreeRemove1(selection)) {
								tableViewer1.refresh();
								ctrl_remove_1.setEnabled(false);
								return;
							}							
						} 
						
						IStructuredSelection selection = (IStructuredSelection) tableViewer1
								.getSelection();
						if (selection.size() > 0) {
							// update the model
							ArrayList rmItems = new ArrayList();
							rmItems.addAll(selection.toList());
							removeItems1(rmItems);
							tableViewer1.refresh();

							// clear the selection
							tableViewer1.setSelection(null, true);
							ctrl_brief_desc.setText(""); //$NON-NLS-1$
						}
						ctrl_remove_1.setEnabled(false);
					}
				
				});
			}
		}
		count++;

		/**
		 * Second set of listeners
		 */
		if (count < tableCount) {
			ctrl_table_2.addFocusListener(new FocusAdapter() {
				public void focusGained(FocusEvent e) {
					IStructuredSelection selection = (IStructuredSelection) tableViewer2
							.getSelection();
					if ((selection.size() > 0) && editable) {
						if (ctrl_remove_2 != null)
							ctrl_remove_2.setEnabled(true);
					}
				}
			});

			tableViewer2
					.addSelectionChangedListener(new ISelectionChangedListener() {
						public void selectionChanged(SelectionChangedEvent event) {
							IStructuredSelection selection = (IStructuredSelection) tableViewer2
									.getSelection();
							if ((selection.size() > 0) && editable) {
								if (isSyncFree()) {
									syncFreeUpdateBtnStatus2(selection);
								} else {
									ctrl_remove_2.setEnabled(true);
								}
							}
							if (selection.size() == 1) {
								String desc = ((MethodElement) selection
										.getFirstElement())
										.getBriefDescription();
								if (desc == null) {
									desc = ""; //$NON-NLS-1$
								}
								ctrl_brief_desc.setText(desc);
							} else if (selection.size() > 1) {
								ctrl_brief_desc
										.setText(PropertiesResources.Process_MultipleSelection + " - " + selection.size()); //$NON-NLS-1$ 
							}
						}
					});

			if (changesAllowed[count]) {
				ctrl_add_2.addSelectionListener(new SelectionAdapter() {
					public void widgetSelected(SelectionEvent e) {
						if (isSyncFree()) {
							IStructuredSelection selection = (IStructuredSelection) tableViewer2.getSelection();
							if (syncFreeAdd2(selection)) {								 	
								tableViewer2.refresh();
								return;
							}
						} 
						
						IFilter filter = getFilter();
						List existingElements = null;
						if (isSyncFree()) {
							existingElements = getExistingContentElements2();
						} else {
							existingElements = ProcessUtil.getAssociatedElementList(getExistingElements2());
						}
						ItemsFilterDialog fd = new ItemsFilterDialog(PlatformUI
								.getWorkbench().getActiveWorkbenchWindow()
								.getShell(), filter, element, tabString,
								existingElements);

						fd.setBlockOnOpen(true);
						fd.setTitle(tabString);
						fd.open();
						addItems2(fd.getSelectedItems());
						tableViewer2.refresh();
					}
				});

				ctrl_add_proc_2.addSelectionListener(new SelectionAdapter() {
					public void widgetSelected(SelectionEvent e) {
						descriptorProcessfilter = getFilterForDescriptors();
						process = getProcess();
						if (descriptorProcessfilter != null && process != null) {
							List existingElements = getExistingElements2();
							ItemsFilterDialog fd = new ItemsFilterDialog(
									PlatformUI.getWorkbench()
											.getActiveWorkbenchWindow()
											.getShell(),
									descriptorProcessfilter, process,
									getDescriptorTabName(), existingElements);

							fd.setBlockOnOpen(true);
							fd.open();
							addFromProcessItems2(fd.getSelectedItems());
							tableViewer2.refresh();
						}
					}
				});

				ctrl_remove_2.addSelectionListener(new SelectionAdapter() {
					public void widgetSelected(SelectionEvent e) {
						if (isSyncFree()) {
							IStructuredSelection selection = (IStructuredSelection) tableViewer2.getSelection();
							if (syncFreeRemove2(selection)) {
								tableViewer2.refresh();
								ctrl_remove_2.setEnabled(false);
								return;
							}							
						}						
						
						IStructuredSelection selection = (IStructuredSelection) tableViewer2
								.getSelection();
						if (selection.size() > 0) {
							// update the model
							ArrayList rmItems = new ArrayList();
							rmItems.addAll(selection.toList());
							removeItems2(rmItems);
							tableViewer2.refresh();

							// clear the selection
							tableViewer2.setSelection(null, true);
							ctrl_brief_desc.setText(""); //$NON-NLS-1$
						}
						ctrl_remove_2.setEnabled(false);
					}
				});
			}
		}
		count++;

		/**
		 * Third set of listeners
		 */
		if (count < tableCount) {
			ctrl_table_3.addFocusListener(new FocusAdapter() {
				public void focusGained(FocusEvent e) {
					IStructuredSelection selection = (IStructuredSelection) tableViewer3
							.getSelection();
					if ((selection.size() > 0) && editable)
						ctrl_remove_3.setEnabled(true);
				}
			});

			tableViewer3
					.addSelectionChangedListener(new ISelectionChangedListener() {
						public void selectionChanged(SelectionChangedEvent event) {
							IStructuredSelection selection = (IStructuredSelection) tableViewer3
									.getSelection();
							if ((selection.size() > 0) && editable)
								ctrl_remove_3.setEnabled(true);
							if (selection.size() == 1) {
								String desc = ((MethodElement) selection
										.getFirstElement())
										.getBriefDescription();
								if (desc == null) {
									desc = ""; //$NON-NLS-1$
								}
								ctrl_brief_desc.setText(desc);
							} else if (selection.size() > 1) {
								ctrl_brief_desc
										.setText(PropertiesResources.Process_MultipleSelection + " - " + selection.size()); //$NON-NLS-1$ 
							}
						}
					});

			if ((new Boolean(changesAllowed[count])).booleanValue()) {
				ctrl_add_3.addSelectionListener(new SelectionAdapter() {
					public void widgetSelected(SelectionEvent e) {
						IFilter filter = getFilter();
						List existingElements = ProcessUtil
								.getAssociatedElementList(getExistingElements3());
						ItemsFilterDialog fd = new ItemsFilterDialog(PlatformUI
								.getWorkbench().getActiveWorkbenchWindow()
								.getShell(), filter, element, tabString,
								existingElements);

						fd.setBlockOnOpen(true);
						fd.setTitle(tabString);
						fd.open();
						addItems3(fd.getSelectedItems());
						tableViewer3.refresh();

					}
				});

				ctrl_add_proc_3.addSelectionListener(new SelectionAdapter() {
					public void widgetSelected(SelectionEvent e) {
						descriptorProcessfilter = getFilterForDescriptors();
						process = getProcess();
						if (descriptorProcessfilter != null && process != null) {
							List existingElements = getExistingElements3();
							ItemsFilterDialog fd = new ItemsFilterDialog(
									PlatformUI.getWorkbench()
											.getActiveWorkbenchWindow()
											.getShell(),
									descriptorProcessfilter, process,
									getDescriptorTabName(), existingElements);

							fd.setBlockOnOpen(true);
							fd.open();
							addFromProcessItems3(fd.getSelectedItems());
							tableViewer3.refresh();
						}

					}
				});

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

							// clear the selection
							tableViewer3.setSelection(null, true);
							ctrl_brief_desc.setText(""); //$NON-NLS-1$
						}
						ctrl_remove_3.setEnabled(false);
					}
				});
			}
		}
		count++;

		/**
		 * Fouth set of listeners
		 */
		if (count < tableCount) {
			ctrl_table_4.addFocusListener(new FocusAdapter() {
				public void focusGained(FocusEvent e) {
					IStructuredSelection selection = (IStructuredSelection) tableViewer4
							.getSelection();
					if ((selection.size() > 0) && editable)
						ctrl_remove_4.setEnabled(true);
				}
			});

			tableViewer4
					.addSelectionChangedListener(new ISelectionChangedListener() {
						public void selectionChanged(SelectionChangedEvent event) {
							IStructuredSelection selection = (IStructuredSelection) tableViewer4
									.getSelection();
							if ((selection.size() > 0) & editable) {
								if (isSyncFree()) {
									syncFreeUpdateBtnStatus4(selection);
								} else {
									ctrl_remove_4.setEnabled(true);
								}
							}
							if (selection.size() == 1) {
								String desc = ((MethodElement) selection
										.getFirstElement())
										.getBriefDescription();
								if (desc == null) {
									desc = ""; //$NON-NLS-1$
								}
								ctrl_brief_desc.setText(desc);
							} else if (selection.size() > 1) {
								ctrl_brief_desc
										.setText(PropertiesResources.Process_MultipleSelection + " - " + selection.size()); //$NON-NLS-1$ 
							}
						}
					});

			if ((new Boolean(changesAllowed[count])).booleanValue()) {
				ctrl_add_4.addSelectionListener(new SelectionAdapter() {
					public void widgetSelected(SelectionEvent e) {
						if (isSyncFree()) {
							IStructuredSelection selection = (IStructuredSelection) tableViewer4.getSelection();
							if (syncFreeAdd4(selection)) {								 	
								tableViewer4.refresh();
								return;
							}
						} 
						
						IFilter filter = getFilter();
						List existingElements = null;
						if (isSyncFree()) {
							existingElements = getExistingContentElements4();
						} else {
							existingElements = ProcessUtil.getAssociatedElementList(getExistingElements4());
						}
						ItemsFilterDialog fd = new ItemsFilterDialog(PlatformUI
								.getWorkbench().getActiveWorkbenchWindow()
								.getShell(), filter, element, tabString,
								existingElements);

						fd.setBlockOnOpen(true);
						fd.setTitle(tabString);
						fd.open();
						addItems4(fd.getSelectedItems());
						tableViewer4.refresh();
					}
				});

				ctrl_add_proc_4.addSelectionListener(new SelectionAdapter() {
					public void widgetSelected(SelectionEvent e) {
						descriptorProcessfilter = getFilterForDescriptors();
						process = getProcess();
						if (descriptorProcessfilter != null && process != null) {
							List existingElements = getExistingElements4();
							ItemsFilterDialog fd = new ItemsFilterDialog(
									PlatformUI.getWorkbench()
											.getActiveWorkbenchWindow()
											.getShell(),
									descriptorProcessfilter, process,
									getDescriptorTabName(), existingElements);

							fd.setBlockOnOpen(true);
							fd.open();
							addFromProcessItems4(fd.getSelectedItems());
							tableViewer4.refresh();
						}
					}
				});

				ctrl_remove_4.addSelectionListener(new SelectionAdapter() {
					public void widgetSelected(SelectionEvent e) {
						if (isSyncFree()) {
							IStructuredSelection selection = (IStructuredSelection) tableViewer4.getSelection();
							if (syncFreeRemove4(selection)) {
								tableViewer4.refresh();
								ctrl_remove_4.setEnabled(false);
								return;
							}							
						}
						
						IStructuredSelection selection = (IStructuredSelection) tableViewer4
								.getSelection();
						if (selection.size() > 0) {
							// update the model
							ArrayList rmItems = new ArrayList();
							rmItems.addAll(selection.toList());
							removeItems4(rmItems);
							tableViewer4.refresh();

							// clear the selection
							tableViewer4.setSelection(null, true);
							ctrl_brief_desc.setText(""); //$NON-NLS-1$
						}
						ctrl_remove_4.setEnabled(false);
					}
				});
			}
		}
	}
	
	protected void addItems1(List list) {
	};

	protected void addItems2(List list) {
	};

	protected void addItems3(List list) {
	};

	protected void addItems4(List list) {
	};

	protected void addFromProcessItems1(List list) {
	};

	protected void addFromProcessItems2(List list) {
	};

	protected void addFromProcessItems3(List list) {
	};

	protected void addFromProcessItems4(List list) {
	};

	protected void removeItems1(List list) {
	};

	protected void removeItems2(List list) {
	};

	protected void removeItems3(List list) {
	};

	protected void removeItems4(List list) {
	};

	protected List getExistingElements1() {
		return null;
	};

	protected List getExistingElements2() {
		return null;
	};

	protected List getExistingElements3() {
		return null;
	};

	protected List getExistingElements4() {
		return null;
	};
	
	protected List getExistingContentElements1() {
		return null;
	}
	
	protected List getExistingContentElements2() {
		return null;
	}
	
	protected List getExistingContentElements4() {
		return null;
	}
	
	protected boolean syncFreeAdd1(IStructuredSelection selection) {
		return false;
	}
	
	protected boolean syncFreeAdd2(IStructuredSelection selection) {
		return false;
	}
	
	protected boolean syncFreeAdd4(IStructuredSelection selection) {
		return false;
	}
	
	protected boolean syncFreeRemove1(IStructuredSelection selection) {
		return false;
	}
	
	protected boolean syncFreeRemove2(IStructuredSelection selection) {
		return false;
	}
	
	protected boolean syncFreeRemove4(IStructuredSelection selection) {
		return false;
	}
	
	protected void syncFreeUpdateBtnStatus1(IStructuredSelection selection) {
		
	}
	
	protected void syncFreeUpdateBtnStatus2(IStructuredSelection selection) {
		
	}
	
	protected void syncFreeUpdateBtnStatus4(IStructuredSelection selection) {
		
	}
			
	public boolean isSyncFree() {
		return ProcessUtil.isSynFree();
	}
	
}