//------------------------------------------------------------------------------
// 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.forms;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.edit.provider.IItemLabelProvider;
import org.eclipse.emf.edit.provider.IViewerNotification;
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.emf.edit.ui.provider.ExtendedImageRegistry;
import org.eclipse.epf.authoring.ui.AuthoringUIHelpContexts;
import org.eclipse.epf.authoring.ui.AuthoringUIPlugin;
import org.eclipse.epf.authoring.ui.AuthoringUIResources;
import org.eclipse.epf.authoring.ui.editors.ConfigurationEditor;
import org.eclipse.epf.authoring.ui.editors.ConfigurationEditorInput;
import org.eclipse.epf.authoring.ui.views.ConfigurationViewer;
import org.eclipse.epf.authoring.ui.views.MessageView;
import org.eclipse.epf.library.ILibraryManager;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.configuration.ConfigurationClosure;
import org.eclipse.epf.library.configuration.ElementDependencyError;
import org.eclipse.epf.library.configuration.ErrorInfo;
import org.eclipse.epf.library.edit.TngAdapterFactory;
import org.eclipse.epf.library.edit.command.IActionManager;
import org.eclipse.epf.library.edit.navigator.ContentItemProvider;
import org.eclipse.epf.library.edit.navigator.MethodPackagesItemProvider;
import org.eclipse.epf.library.edit.navigator.PluginUIPackagesItemProvider;
import org.eclipse.epf.library.edit.navigator.ProcessesItemProvider;
import org.eclipse.epf.library.edit.ui.UserInteractionHelper;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.events.ILibraryChangeListener;
import org.eclipse.epf.library.services.ElementReference;
import org.eclipse.epf.library.services.SafeUpdateController;
import org.eclipse.epf.library.util.LibraryUtil;
import org.eclipse.epf.uma.CustomCategory;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodLibrary;
import org.eclipse.epf.uma.MethodPackage;
import org.eclipse.epf.uma.MethodPlugin;
import org.eclipse.epf.uma.Process;
import org.eclipse.epf.uma.ProcessComponent;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.ILabelProvider;
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.ITreeContentProvider;
import org.eclipse.jface.viewers.ITreeViewerListener;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeExpansionEvent;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
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.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.editor.FormEditor;
import org.eclipse.ui.forms.editor.FormPage;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.ui.forms.widgets.TableWrapData;
import org.eclipse.ui.forms.widgets.TableWrapLayout;

/**
 * The Configuration page in the Method Configuration editor.
 * 
 * @author Shashidhar Kannoori
 * @author Jinhua Xi
 * @author Shilpa Toraskar
 * @since 1.0
 */
public class ConfigurationPage extends FormPage implements ISelectionProvider {
	MethodConfiguration config = null;

	ConfigurationClosure closure = null;

	ConfigurationViewer treeViewer;

	ConfigPackageContentProvider contProvider;

	ISelectionChangedListener selectionChangedListener = null;

	ScrolledForm form = null;

	boolean isDirty = false;
	
	private boolean needUpdate = false;

	private String formPrefix = AuthoringUIResources.ConfigurationPage_FormPrefix; //$NON-NLS-1$

	// private EObject currentRootNode;
	private ArrayList expandedElements = new ArrayList();

	// private Text ctrl_name;

	// private Text ctrl_brief_desc;

	private List modifiedElements = new ArrayList();

	private Button closureButton;

	private Button fixWarningButton;

	private Button errorButton;

	// private Button dependentButton;

	private Button hideButton;

	// private Text despText;

	private Text elemDespContentText;

	// private Text nameText;

	protected Collection selectionChangedListeners = new ArrayList();

	// private ISelectionChangedListener parentSelectionChangedListener = null;

	protected ISelection currentSelection = StructuredSelection.EMPTY;

	private MessageView msgView;

	ISelectionChangedListener msgViewListener = null;

	private ConfigTreeFilter configFilter;

	private IActionManager actionMgr;

	private ILibraryChangeListener libListener = null;

	protected Adapter configurationChangedListener = null;

	/**
	 * Creates an instance
	 * @param editor
	 */
	public ConfigurationPage(FormEditor editor) {
		super(
				editor,
				AuthoringUIResources.ConfigurationPage_Description1, AuthoringUIResources.ConfigurationPage_Description2); 
	}

	/**
	 * @see org.eclipse.ui.forms.editor.FormPage#init(org.eclipse.ui.IEditorSite, org.eclipse.ui.IEditorInput)
	 */
	public void init(IEditorSite site, IEditorInput input) {
		setSite(site);
		setInput(input);

		ConfigurationEditorInput configInput = (ConfigurationEditorInput) input;
		config = configInput.getConfiguration();

		
		configurationChangedListener = new AdapterImpl() {
			public void notifyChanged(
					org.eclipse.emf.common.notify.Notification msg) {
				// System.out.println("$$$ catched modify config notification =
				// " + msg);
				int type = msg.getEventType();
				if (	type == org.eclipse.emf.common.notify.Notification.ADD
						|| type == org.eclipse.emf.common.notify.Notification.ADD_MANY
						|| type == org.eclipse.emf.common.notify.Notification.REMOVE
						||   type == org.eclipse.emf.common.notify.Notification.REMOVE_MANY) {					
					needUpdate = true;
					
//					This was done to refresh configuration plugin-package section page. But its not perfect
//					solution. Doesnt cover all the scenarios. So commenting it out.
//					Will have to think of alternate way to refresh plugin/package configuration page.
//					Low Priority
//						|| type == org.eclipse.emf.common.notify.Notification.REMOVE
//						|| type == org.eclipse.emf.common.notify.Notification.REMOVE_MANY ) {
//					
					
//					if (treeViewer != null)	{
//						treeViewer.refresh();
//						updateCheckStates();
//						showErrors();
//					}
				}
			}
		};
		config.eAdapters().add(configurationChangedListener);

	}

	private void reInitializeConfigFactory() {
		// the following may not be the most efficient way
		// need a fast way to update the closure
//		System.out.println("$$$ reInit closure for config add notification!");

		createConfigurationClosure();

		configFilter = new ConfigTreeFilter(closure);
	}

	/**
	 * Set input for connfiguration viewer
	 * @param input
	 */
	public void setInput(Object input) {
		treeViewer.setInput(input);

		// initially expand the whole tree before updating the tree
		// this is a workaround for the content provider to build the child -
		// parent lookup map
		treeViewer.expandAll();

		// update the tree with the default closure selection
		updateCheckStates();
	}

	/**
	 * @see org.eclipse.ui.forms.editor.FormPage#createFormContent(org.eclipse.ui.forms.IManagedForm)
	 */
	protected void createFormContent(IManagedForm managedForm) {
		// create form toolkit
		form = managedForm.getForm();
		form.setText(formPrefix + config.getName());
		FormToolkit toolkit = managedForm.getToolkit();

		TableWrapLayout layout = new TableWrapLayout();
		form.getBody().setLayout(layout);

		Section treeSection = toolkit.createSection(form.getBody(),
				Section.DESCRIPTION | Section.TWISTIE | Section.EXPANDED
						| Section.TITLE_BAR);
		createTreeContent(toolkit, treeSection);

		addListeners();

		// finally set the input.
		// RootContent inputNode = new RootContent(closure
		// .getConfigurationFactory().getMethodPlugins());
		setInput(LibraryService.getInstance().getCurrentMethodLibrary());
	}

	/**
	 * Create tree content
	 * @param toolkit
	 * @param section
	 */
	public void createTreeContent(FormToolkit toolkit, Section section) {
		section.setText(AuthoringUIResources.ConfigurationPage_ConfigContent); //$NON-NLS-1$
		section
				.setDescription(AuthoringUIResources.ConfigurationPage_ConfigContentDescription); //$NON-NLS-1$
		section.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB));

		Composite sectionClient = toolkit.createComposite(section);
		section.setClient(sectionClient);
		GridLayout gl = new GridLayout();
		sectionClient.setLayout(gl);
		gl.numColumns = 6;

		PlatformUI.getWorkbench().getHelpSystem().setHelp(
				sectionClient.getParent(),
				AuthoringUIHelpContexts.CONFIGURATION_EDITOR_ALL_CONTEXT);

		Composite buttonComposite = toolkit.createComposite(sectionClient);
		{
			GridLayout gridLayout = new GridLayout();
			gridLayout.numColumns = 6;
			buttonComposite.setLayout(gridLayout);
			GridData gridData = new GridData(GridData.FILL_BOTH);
			gridData.horizontalSpan = 6;
			gridData.horizontalAlignment = 3;
			buttonComposite.setLayoutData(gridData);

		}

		hideButton = toolkit.createButton(buttonComposite, "", SWT.PUSH //$NON-NLS-1$
				| GridData.HORIZONTAL_ALIGN_END);
		hideButton.setImage(AuthoringUIPlugin.getDefault().getSharedImage(
				"hideUncheckedElem.gif")); //$NON-NLS-1$
		hideButton.setToolTipText(AuthoringUIResources.ConfigurationPage_hideToolTip); //$NON-NLS-1$
		hideButton.setLayoutData(new GridData(GridData.END));

		fixWarningButton = toolkit.createButton(buttonComposite, "", SWT.PUSH); //$NON-NLS-1$
		fixWarningButton.setImage(AuthoringUIPlugin.getDefault()
				.getSharedImage("addref_co.gif")); //$NON-NLS-1$
		fixWarningButton.setToolTipText(AuthoringUIResources.ConfigurationPage_AddMissingToolTip); //$NON-NLS-1$
		fixWarningButton.setLayoutData(new GridData(GridData.END));

		// Add the closure button.
		closureButton = toolkit.createButton(buttonComposite, "", SWT.PUSH); //$NON-NLS-1$
		closureButton.setImage(AuthoringUIPlugin.getDefault().getSharedImage(
				"closure_co.gif")); //$NON-NLS-1$
		closureButton.setToolTipText(AuthoringUIResources.ConfigurationPage_MakeClosureToolTip); //$NON-NLS-1$
		closureButton.setLayoutData(new GridData(GridData.END));
		// closureButton.setText("");

		errorButton = toolkit.createButton(buttonComposite, "", SWT.PUSH); //$NON-NLS-1$
		errorButton.setImage(AuthoringUIPlugin.getDefault().getSharedImage(
				"showConfigError.gif")); //$NON-NLS-1$
		errorButton.setToolTipText(AuthoringUIResources.ConfigurationPage_ShowErrorToolTip); //$NON-NLS-1$
		{
			GridData gd = new GridData(GridData.END
					| GridData.HORIZONTAL_ALIGN_END);
			gd.horizontalAlignment = 3;
			gd.horizontalSpan = 1;
			errorButton.setLayoutData(gd);
		}

		Label treeTitleLabel = toolkit
				.createLabel(
						sectionClient,
						AuthoringUIResources.ConfigurationPage_TreeTitleLabel); //$NON-NLS-1$
		{
			GridData gd = new GridData(GridData.BEGINNING
					| GridData.VERTICAL_ALIGN_END);
			treeTitleLabel.setLayoutData(gd);
			gd.horizontalSpan = 6;
		}

		// Create Viewer and Handle Listener for the viewer.
		createViewer(sectionClient);

		Label elemDespLabel = toolkit
				.createLabel(sectionClient, AuthoringUIResources.ConfigurationPage_Description); //$NON-NLS-1$
		GridData gd1 = new GridData();
		gd1.horizontalSpan = 6;
		elemDespLabel.setLayoutData(gd1);

		elemDespContentText = toolkit.createText(sectionClient, "", SWT.NONE //$NON-NLS-1$
				| SWT.MULTI | SWT.READ_ONLY | SWT.WRAP);
		GridData gd2 = new GridData(GridData.FILL_BOTH);
		gd2.grabExcessHorizontalSpace = true;
		gd2.horizontalSpan = 6;
		gd2.heightHint = 50;

		toolkit.paintBordersFor(sectionClient);
		toolkit.paintBordersFor(buttonComposite);
		elemDespContentText.setLayoutData(gd2);

		hideButton.setEnabled(true);
		hideButton.setVisible(true);
		errorButton.setEnabled(true);
		errorButton.setVisible(true);
		fixWarningButton.setEnabled(true);
		fixWarningButton.setVisible(true);
		closureButton.setEnabled(true);
		closureButton.setVisible(true);
	}
	
	private void createConfigurationClosure() {
		// refresh configuration from editor
		//
		FormEditor editor = getEditor();
		if(editor != null) {
			IEditorInput input = editor.getEditorInput();
			if(input instanceof ConfigurationEditorInput) {
				config = ((ConfigurationEditorInput)input).getConfiguration();
			}
		}
		
		closure = new ConfigurationClosure(config);
	}

	/**
	 * Initialize configuration factory
	 */
	public void initializeConfigFactory() {
		// loading the configuration closure might be slow,
		// display a progress bar
		IRunnableWithProgress runnable = new IRunnableWithProgress() {
			public void run(IProgressMonitor monitor)
					throws InvocationTargetException, InterruptedException {
				createConfigurationClosure();
			}

		};

		UserInteractionHelper.runWithProgress(runnable, AuthoringUIResources.ConfigurationPage_LoadingMessage); //$NON-NLS-1$

		AdapterFactory adapterFactory = TngAdapterFactory.INSTANCE
				.getNavigatorView_ComposedAdapterFactory();
		// AdapterFactory adapterFactory = configFactory.getAdapterFactory();
		contProvider = new ConfigPackageContentProvider(//configFactory,
				adapterFactory);
		treeViewer.setContentProvider(contProvider);
		treeViewer
				.setLabelProvider(new ConfigPackageLabelProvider(contProvider));

		configFilter = new ConfigTreeFilter(closure);
		treeViewer.addFilter(configFilter);

		// show the message view if there is error
		updateMessage();
	}

	private void createViewer(Composite sectionClient) {

		sectionClient.setLayoutData(new GridData(GridData.FILL_BOTH));
		GridLayout layout = new GridLayout();
		sectionClient.setLayout(layout);
		// create the library tree viewer
		treeViewer = new ConfigurationViewer(sectionClient);
		// treeViewer.getTree().setLayoutData(new GridData(GridData.FILL_BOTH));
		{
			GridData gridData = new GridData(GridData.FILL_BOTH
					| GridData.GRAB_HORIZONTAL);
			gridData.heightHint = 200;
			treeViewer.getTree().setLayoutData(gridData);
		}

		initializeConfigFactory();
	}

	private void addListeners() {
		addEditorSetFocusLiseners();		
		
		actionMgr = ((ConfigurationEditor) getEditor()).getActionManager();
		// nameText.addFocusListener(new FocusAdapter() {
		// public void focusLost(FocusEvent e) {
		// if (isTextNonEmpty(nameText)) {
		// String name = StrUtil.makeValidFileName(nameText.getText());
		// if (!name.equals(config.getName())) {
		// actionMgr.doAction(IActionManager.SET, config,
		// UmaPackage.eINSTANCE.getNamedElement_Name(),
		// name, -1);
		// form.setText(formPrefix + config.getName());
		// nameText.setText(name);
		// }
		// } else {
		// // Display a warning dialog for empty Name.
		// nameText.setText(config.getName());
		// MessageDialog.openWarning(PlatformUI.getWorkbench()
		// .getActiveWorkbenchWindow().getShell(),
		// "Enter Configuration Name",
		// "Name field cannot be empty!");
		// }
		// // config.setName(StrUtil.makeValidFileName(nameText.getText()));
		// // form.setText(formPrefix + config.getName());
		// }
		// });
		// despText.addFocusListener(new FocusAdapter() {
		// public void focusLost(FocusEvent e) {
		// // config.setBriefDescription(StrUtil.getPlainText(despText
		// // .getText()));
		// String desc1 = despText.getText();
		// if (!desc1.equals(config.getBriefDescription())) {
		// actionMgr.doAction(IActionManager.SET, config,
		// UmaPackage.eINSTANCE
		// .getMethodElement_BriefDescription(),
		// desc1, -1);
		// }
		// }
		// });
		closureButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				makeClosure();
			};
		});
		fixWarningButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				fixWarning();
			};
		});
		errorButton.addSelectionListener(new SelectionListener() {
			public void widgetSelected(SelectionEvent e) {
				showErrors();
			}

			public void widgetDefaultSelected(SelectionEvent e) {
			}
		});
		hideButton.addSelectionListener(new SelectionListener() {
			public void widgetSelected(SelectionEvent e) {
				showHideElements();
			}

			public void widgetDefaultSelected(SelectionEvent e) {
			}
		});
		treeViewer.addTreeListener(new ITreeViewerListener() {
			public void treeCollapsed(TreeExpansionEvent event) {
				Object element = event.getElement();
				expandedElements.remove(element);
			}

			public void treeExpanded(TreeExpansionEvent event) {
				Object element = event.getElement();
				expandedElements.add(element);

				// // this is a quick dirty fix for check state initialize issue
				// // better solution later. jxi 07/01/05
				// updateTree();
				//				
				// // restore the check state of the UI elements
				// Object obj = event.getElement();
				// boolean parentState = treeViewer.getChecked(obj);
				//				
				// ConfigPackageContentProvider cp =
				// (ConfigPackageContentProvider)treeViewer.getContentProvider();
				// Object[] children = cp.getChildren(obj);
				// if ( children != null )
				// {
				// for ( int i = 0; i < children.length; i++)
				// {
				// boolean check = false;
				// // if the folder is a UI folder, keep the check state
				// if ( children[i] instanceof MethodPlugin )
				// {
				// check =
				// config.getMethodPluginSelection().contains(children[i]);
				// }
				// else if ( children[i] instanceof MethodPackage )
				// {
				// check =
				// config.getMethodPackageSelection().contains(children[i]);
				// }
				// else
				// {
				// check = parentState;
				// }
				//						
				// boolean ret = treeViewer.setChecked(children[i], check);
				// if ( ret == false)
				// {
				// System.out.println("Can't set state");
				// }
				//
				// }
				// }
			}
		});

		// listen to the selection change of the current tree viewer
		if (selectionChangedListener == null) {
			// Create the listener
			selectionChangedListener = new ISelectionChangedListener() {
				// This just notifies those things that are affected by the
				// section.
				//
				public void selectionChanged(SelectionChangedEvent event) {
//					System.out
//							.println(AuthoringUIResources.ConfigurationPage_Selected + event.getSelection()); //$NON-NLS-1$
					setSelection(event.getSelection());
				}
			};

			treeViewer.addSelectionChangedListener(selectionChangedListener);
		}

		// add a check state change listener
		treeViewer.addCheckStateListener(new ICheckStateListener() {
			public void checkStateChanged(CheckStateChangedEvent event) {
				modifiedElements = new ArrayList();
				boolean checked = event.getChecked();
				updateCheckStates(event.getElement(), checked);

				/*
				 * // save the previous invalid elements List invalid =
				 * closure.getInvalidElements();
				 * 
				 * closure.setSelections(treeViewer.getCheckedElements());
				 * 
				 * if ( configFilter.isHiding() ) { treeViewer.refresh(); } else { //
				 * get the new error elements, add to the previous error
				 * elements, // and update them to update the error/warning
				 * images invalid.addAll(closure.getInvalidElements()); // also
				 * add the UI folders ConfigPackageContentProvider cp =
				 * (ConfigPackageContentProvider)treeViewer.getContentProvider();
				 * invalid.addAll(cp.getUIElements());
				 * 
				 * treeViewer.update(invalid.toArray(), null); }
				 */

				showErrors();
				if (!saveConfiguration()) {
					updateCheckStates(event.getElement(), false);

					for (int i = 0; i < modifiedElements.size(); i++) {
						treeViewer.setChecked(modifiedElements.get(i), false);
					}

				}
			}
		});

		// treeViewer.addTreeListener(new ITreeViewerListener(){
		//
		// public void treeCollapsed(TreeExpansionEvent event) {
		//				
		// }
		//
		// public void treeExpanded(TreeExpansionEvent event) {
		// //updateConfigSelection();
		//
		// // restore the check state of the UI elements
		// Object obj = event.getElement();
		// boolean parentState = treeViewer.getChecked(obj);
		//				
		// ConfigPackageContentProvider cp =
		// (ConfigPackageContentProvider)treeViewer.getContentProvider();
		// Object[] children = cp.getChildren(obj);
		// if ( children != null )
		// {
		// for ( int i = 0; i < children.length; i++)
		// {
		// boolean check = false;
		// // if the folder is a UI folder, keep the check state
		// if ( children[i] instanceof MethodPlugin )
		// {
		// check = config.getMethodPluginSelection().contains(children[i]);
		// }
		// else if ( children[i] instanceof MethodPackage )
		// {
		// check = config.getMethodPackageSelection().contains(children[i]);
		// }
		// else
		// {
		// check = parentState;
		// }
		//						
		// boolean ret = treeViewer.setChecked(children[i], check);
		// if ( ret == false)
		// {
		// System.out.println("Can't set state");
		// }
		//
		// }
		// }
		//				
		// }});

		// listen to the library changes and automatically update the
		// configuration view
		libListener = new ILibraryChangeListener() {
			public void libraryChanged(int option, Collection changedItems) {
				// for performance reason, we should not response to every
				// library change
				// only cover package and plugin changes
				if (option == ILibraryChangeListener.OPTION_DELETED
						|| option == ILibraryChangeListener.OPTION_NEWCHILD
						|| option == ILibraryChangeListener.OPTION_NEWCHILD) {
					if (changedItems != null && changedItems.size() > 0) {
						Object o = changedItems.toArray()[0];
						if (o instanceof MethodPlugin
								|| o instanceof ProcessComponent
								|| o instanceof MethodPackage) {
							if (o instanceof ProcessComponent) {
								reInitializeConfigFactory();
							}
							treeViewer.refresh();
							updateCheckStates();
							showErrors();
						}
					}
				}
			}
		};

		ILibraryManager manager = LibraryService.getInstance().getCurrentLibraryManager();
		if (manager != null) {
			manager.addListener(libListener);
		}
	}

	protected void showHideElements() {
		configFilter.setHide();
		updateCheckStates(); // neded to have this to update the check status
	}

	/**
	 * the UI selections contains UI folders, need to convert to the
	 * corresponding method element selections
	 * 
	 * @return Object[] the converted selections
	 */
	protected Object[] getConvertedSelections() {
		List items = new ArrayList();
		Object[] sels = treeViewer.getCheckedElements();

		ConfigPackageContentProvider cp = (ConfigPackageContentProvider) treeViewer
				.getContentProvider();
		for (int i = 0; i < sels.length; i++) {
			Object sel = cp.getUITargetElement(sels[i]);
			if (sel != null && !items.contains(sel)) {
				items.add(sel);
			}
		}

		return items.toArray();
	}

	protected void showErrors() {
		// ConfigurationClosure c = closure;
		// c.setSelections(treeViewer.getCheckedElements());

		// save the previous invalid elements
		List invalid = closure.getInvalidElements();

		// convert selections to method plugins and method packages
		closure.setSelections(getConvertedSelections());

		if (configFilter.isHiding()) {
			treeViewer.refresh();
		} else {
			// get the new error elements, add to the previous error elements,
			// and update them to update the error/warning images
			invalid.addAll(closure.getInvalidElements());

			// also add the UI folders
			ConfigPackageContentProvider cp = (ConfigPackageContentProvider) treeViewer
					.getContentProvider();
			invalid.addAll(cp.getUIElements());

			treeViewer.update(invalid.toArray(), null);
		}

		updateMessage();

	}

	/**
	 * @see org.eclipse.jface.viewers.ISelectionProvider#addSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener)
	 */
	public void addSelectionChangedListener(ISelectionChangedListener listener) {
		selectionChangedListeners.add(listener);
	}

	/**
	 * @see org.eclipse.jface.viewers.ISelectionProvider#removeSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener)
	 */
	public void removeSelectionChangedListener(
			ISelectionChangedListener listener) {
		selectionChangedListeners.remove(listener);
	}

	/**
	 * @see org.eclipse.jface.viewers.ISelectionProvider#getSelection()
	 */
	public ISelection getSelection() {
		return currentSelection;
	}

	/**
	 * @see org.eclipse.jface.viewers.ISelectionProvider#setSelection(org.eclipse.jface.viewers.ISelection)
	 */
	public void setSelection(ISelection selection) {
		currentSelection = selection;

		for (Iterator listeners = selectionChangedListeners.iterator(); listeners
				.hasNext();) {
			ISelectionChangedListener listener = (ISelectionChangedListener) listeners
					.next();
			listener
					.selectionChanged(new SelectionChangedEvent(this, selection));
		}

		// notify the message view
		IStructuredSelection sel = (IStructuredSelection) selection;
		Object[] selObjs = sel.toArray();
		if ((selObjs != null) && (selObjs.length > 0)) {
			Object node = selObjs[0];
			if (closure.getError(node) != null) {
				getMessageView().showError(node);
			}
		}

		// update the description field
		Object o = sel.getFirstElement();
		if (o instanceof MethodElement) {
			String briefDesc = ((MethodElement) o).getBriefDescription();
			elemDespContentText.setText(briefDesc != null ? briefDesc : ""); //$NON-NLS-1$
		}

	}

	/**
	 * Make configuration closure
	 *
	 */
	protected void makeClosure() {
		// set the selections to the closure
		ConfigurationClosure c = closure;
		// c.setSelections(treeViewer.getCheckedElements());
		c.makeClosure();

		treeViewer.refresh();

		updateCheckStates();

		saveConfiguration();

		updateMessage();

	}

	/**
	 * Fix all warnings 
	 */
	protected void fixWarning() {
		ConfigurationClosure c = closure;
		// c.setSelections(treeViewer.getCheckedElements());

		c.fixProblems();

		treeViewer.refresh();
		updateCheckStates();

		saveConfiguration();

		updateMessage();

	}

	private void updateCheckStates(Object element, boolean checked) {

		// Object element = event.getElement();

		if (checked == true) {
			ITreeContentProvider cp = (ITreeContentProvider) treeViewer
					.getContentProvider();
			checkParent(cp, element);
			// treeViewer.setChecked(element, true);
		} else
			treeViewer.setChecked(element, false);

		selectionChildren(element, checked);

	}

	/**
	 * Select/unselect all the children for the given element
	 * @param element
	 * @param checked
	 */
	public void selectionChildren(Object element, boolean checked) {
		ITreeContentProvider cp = (ITreeContentProvider) treeViewer
				.getContentProvider();
		Object[] childs = cp.getChildren(element);
		for (int i = 0; i < childs.length; i++) {
			treeViewer.setChecked(childs[i], checked);
			selectionChildren(childs[i], checked);
		}
	}

	private void updateCheckStates() {
		treeViewer.getTree().setVisible(false);
		// treeViewer.expandAll();

		try {
			Object content = treeViewer.getInput();
			if (content instanceof MethodLibrary) {

				// set the selection since the colsure may changed with make
				// closure or fix error
				// treeViewer.setCheckedElements(closure
				// .getSelection());
				Object[] selectionList = closure.getSelection();
				ConfigPackageContentProvider cp = (ConfigPackageContentProvider) treeViewer
						.getContentProvider();

				for (int i = 0; i < selectionList.length; i++) {
					Object element = selectionList[i];

					checkParent(cp, element);
					treeViewer.setChecked(element, true);
				}

				// also set the UI folders if the corresponding package is
				// selected
				for (Iterator it = new ArrayList(cp.getUIElements()).iterator(); it
						.hasNext();) {
					Object element = it.next();
					Object o = cp.getUITargetElement(element);
					if (o != null && closure.isSelected(o)) {
						checkParent(cp, element);
						treeViewer.setChecked(element, true);
					}
				}

				// restore the expand state
				treeViewer.setExpandedElements(expandedElements.toArray());

			}

		} finally {
			treeViewer.getTree().setVisible(true);
		}

	}

	private void checkParent(ITreeContentProvider cp, Object element) {
		if (element == null || element instanceof MethodLibrary /*
																 * || element ==
																 * currentRootNode
																 */) {
			return;
		}
		modifiedElements.add(element);
		Object parent = LibraryUtil.unwrap(cp.getParent(element));
		if (parent != null) {
			treeViewer.setChecked(parent, true);
			// configFactory.getCurrentConfiguration().add((EObject)parent,
			// false);
			checkParent(cp, parent);
		}

	}

	/**
	 * Get all parents
	 * @param list
	 * @param pkg
	 */
	public void getAllParents(List list, MethodPackage pkg) {
		MethodPackage parentPkg = ((MethodPackage) pkg).getParentPackage();
		if (parentPkg != null) {
			list.add(parentPkg);
			getAllParents(list, parentPkg);
		}
	}

	/**
	 * Check parents for the given element
	 * @param element
	 */
	public boolean setParentsChecked(Object element) {
		Widget widget = treeViewer.testFindItem(element);
		if (widget instanceof TreeItem) {
			TreeItem item = (TreeItem) widget;
			item = item.getParentItem();
			while (item != null) {
				item.setChecked(true);
				item = item.getParentItem();
			}
			return true;
		}
		return false;
	}

	/**
	 * @see org.eclipse.ui.forms.editor.FormPage#isDirty()
	 */
	public boolean isDirty() {
		return false;
		// return isDirty;
	}

	/**
	 * Set dirty flag
	 * @param dirty
	 */
	public void setDirty(boolean dirty) {
		isDirty = dirty;
	}

	/**
	 * Content provider for configuration packages
	 */
	public class ConfigPackageContentProvider extends
			AdapterFactoryContentProvider {
		//private ConfigurationFactory configFactory;

		// private boolean showMethodModelOnly = false;

		// there is a problem in the passed in AdapterFactory
		// it can't find the correct parent from the child
		// need to build a map of child to it's parent if the child is a UI
		// folder
		// clear the map when the input is set
		Map childUIParentMap = new HashMap();

		List uiFolders = new ArrayList();

		public List getUIElements() {
			return uiFolders;
		}

		/**
		 * Create an instance
		 * @param adapterFactory
		 */
		public ConfigPackageContentProvider(//ConfigurationFactory configFactory,
				AdapterFactory adapterFactory/* , boolean showMethodModelOnly */) {
			super(adapterFactory);
			// this.showMethodModelOnly = showMethodModelOnly;
		}

		/*
		public ConfigurationFactory getConfigFactory() {
			return configFactory;
		}
		*/

		// public void setShowMethodModelOnly(boolean showOnly) {
		// showMethodModelOnly = showOnly;
		// }

		/**
		 * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider#getChildren(java.lang.Object)
		 */
		public Object[] getChildren(Object parentElement) {
			// if (parentElement instanceof RootContent) {
			// return ((RootContent) parentElement).getChildren();
			// } else {
			// if (showMethodModelOnly) {
			// return null;
			// } else {
			Object[] items = getValidItems(parentElement, super
					.getChildren(parentElement));
			return items;
			// }
			// }
		}

		/**
		 * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider#getElements(java.lang.Object)
		 */
		public Object[] getElements(Object inputElement) {
			// if (inputElement instanceof RootContent) {
			// return ((RootContent) inputElement).getChildren();
			// } else {

			Object[] items = getValidItems(inputElement, super
					.getElements(inputElement));

			// if (showMethodModelOnly && items != null) {
			// List elements = new ArrayList();
			// for (int i = 0; i < items.length; i++) {
			// if (items[i] instanceof MethodPlugin) {
			// elements.add(items[i]);
			// }
			// }
			// return elements.toArray();
			//
			// } else {
			return items;
			// }
			// }
		}

		private boolean isUIFolder(Object e) {
			return (e instanceof ContentItemProvider
					|| e instanceof ProcessesItemProvider || e instanceof MethodPackagesItemProvider ||
					e instanceof PluginUIPackagesItemProvider
			/*
			 * || e instanceof StandardCategoriesItemProvider || e instanceof
			 * DisciplineCategoriesItemProvider || e instanceof
			 * DomainsItemProvider || e instanceof WorkProductTypesItemProvider ||
			 * e instanceof RoleSetsItemProvider || e instanceof
			 * ToolsItemProvider || (e instanceof CustomCategory) &&
			 * TngUtil.isRootCustomCategory((CustomCategory)e)
			 */
			);
		}

		public Object getUITargetElement(Object e) {
			if (e instanceof CustomCategory) {
				return ((CustomCategory) e).eContainer();
			} else if (e instanceof MethodElement) {
				return e;
			} else if (e instanceof ContentItemProvider) {
				return ((ContentItemProvider) e).getParent(null);
			} else if (e instanceof ProcessesItemProvider) {
				return ((ProcessesItemProvider) e).getParent(null);
			} else if (e instanceof ItemProviderAdapter) {
				Object target = ((ItemProviderAdapter) e).getTarget();
				if (target != null && target instanceof MethodElement) {
					return target;
				}
			}

			return null;
		}

		private Object[] getValidItems(Object parent, Object[] elements) {
			if (elements == null || elements.length == 0) {
				return elements;
			}

			List pkgs = new ArrayList();
			for (int i = 0; i < elements.length; i++) {
				Object e = LibraryUtil.unwrap(elements[i]);
				boolean uiFolder = isUIFolder(e);
				if (uiFolder || e instanceof MethodPackage
						|| e instanceof MethodPlugin) {
					pkgs.add(e);

					if (uiFolder) {
						uiFolders.add(e);
					}

					// if the parent is a UI folder, map the child to the parent
					// so that we can get the parent later
					// if ( !(parent instanceof MethodElement) )
					{
						childUIParentMap.put(e, parent);
					}
				} else {
					; // System.out.println("Ignored: " + e);
				}
			}

			return pkgs.toArray();
		}

		/**
		 * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider#getParent(java.lang.Object)
		 */
		public Object getParent(Object element) {
			// if (element instanceof RootContent) {
			// return null;
			// } else
			if (childUIParentMap.containsKey(element)) {
				return childUIParentMap.get(element);
			} else {
				return super.getParent(element);
			}
		}

		/**
		 * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider#hasChildren(java.lang.Object)
		 */
		public boolean hasChildren(Object element) {
			// if (element instanceof RootContent) {
			// return true;
			// } else
			// if (showMethodModelOnly) {
			// return false;
			// } else {
			Object[] children = getChildren(element);
			return (children != null && children.length > 0);

			// return treeNodeProvider.hasChildren(element);
			// return super.hasChildren(element);
			// }
		}

		/**
		 * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
		 */
		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
			super.inputChanged(viewer, oldInput, newInput);
			childUIParentMap.clear();
		}

		/**
		 * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider#notifyChanged(org.eclipse.emf.common.notify.Notification)
		 */
		public void notifyChanged(Notification notification) {
			super.notifyChanged(notification);

			if ((notification instanceof IViewerNotification)) {
				final IViewerNotification vnt = (IViewerNotification) notification;
				final Object element = vnt.getElement();
				final ConfigurationViewer ctrl = ((ConfigurationViewer) super.viewer);
				if (element != null && (vnt.getEventType() == Notification.ADD
						|| vnt.getEventType() == Notification.SET)) {

					SafeUpdateController.syncExec(new Runnable() {
						public void run() {
							ctrl.setChecked(element, true);
						}
					});
				}
			}
		}

		/**
		 * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider#dispose()
		 */
		public void dispose() {
			super.dispose();
			uiFolders.clear();
			childUIParentMap.clear();
			//configFactory = null;
		}
	}

	/**
	 * Label provider for configuration packages
	 */
	public class ConfigPackageLabelProvider extends LabelProvider {
		ConfigPackageContentProvider contentProvider;

		//ConfigurationFactory configFactory;

		AdapterFactoryLabelProvider afProvider;

		/**
		 * Creates an instance
		 * @param contentProvider
		 */
		public ConfigPackageLabelProvider(
				ConfigPackageContentProvider contentProvider) {
			this.contentProvider = contentProvider;
			afProvider = new AdapterFactoryLabelProvider(contentProvider
					.getAdapterFactory());
			//this.configFactory = contentProvider.getConfigFactory();
		}

		private ElementDependencyError getFirstChildError(Object e) {
			ElementDependencyError error = null;
			Object[] children = contentProvider.getChildren(e);
			if (children == null || children.length == 0) {
				return null;
			}

			for (int i = 0; i < children.length; i++) {
				Object object = children[i];
				if (object instanceof ItemProviderAdapter) {
					return getFirstChildError(object);
				} else {
					error = closure.getError(object);
					if (error != null) {
						return error;
					}
				}
			}

			return error;
		}

		/**
		 * This implements {@link ILabelProvider}.getImage by forwarding it to
		 * an object that implements
		 * {@link IItemLabelProvider#getImage IItemLabelProvider.getImage}
		 */
		public Image getImage(Object object) {
			// disable for now till it works
			ConfigurationClosure config1 = closure;
			if (config1 != null) {
				// no, this will show the error mark even if the child has no
				// error, not good
				// show the error if there is child error
				// while ( object instanceof ItemProviderAdapter)
				// {
				// object = contentProvider.getParent(object);
				// }

				ElementDependencyError error = null;
				if (object instanceof ItemProviderAdapter) {
					error = getFirstChildError(object);
				} else {
					error = closure.getError(object);
				}

				if (error != null) {
					if (error.isError() || error.isChildError()) {
						return PlatformUI.getWorkbench().getSharedImages()
								.getImage(ISharedImages.IMG_OBJS_WARN_TSK); // ISharedImages.IMG_OBJS_ERROR_TSK
						// show
						// warning
						// as
						// well
					} else if (error.isWarning() || error.isChildWarning()) {
						return PlatformUI.getWorkbench().getSharedImages()
								.getImage(ISharedImages.IMG_OBJS_WARN_TSK);
					}
				}
			}

			return afProvider.getImage(object);
		}

		protected Image getImageFromObject(Object object) {
			return ExtendedImageRegistry.getInstance().getImage(object);
		}

		/**
		 * This implements {@link ILabelProvider}.getText by forwarding it to
		 * an object that implements
		 * {@link IItemLabelProvider#getText IItemLabelProvider.getText}
		 */
		public String getText(Object object) {
			if (object instanceof ProcessComponent) {
				// return
				// ((ProcessComponent)object).getProcess().getPresentationName();
				Process proc = (Process) ((ProcessComponent) object)
						.getProcess();
				if (proc != null)
					return proc.getPresentationName();
				else
					// if process is null, return processcomponent name
					return ((ProcessComponent) object).getName();
			} else
				return afProvider.getText(object);
		}

		/**
		 * @see org.eclipse.jface.viewers.LabelProvider#dispose()
		 */
		public void dispose() {
			super.dispose();

			contentProvider = null;
			afProvider = null;
			//configFactory = null;
		}
	}

	/**
	 * Filter for configuration
	 * 
	 *
	 */
	public class ConfigTreeFilter extends ViewerFilter {
		boolean hideUncheckedNodes = false;

		CheckboxTreeViewer checkTree = null;

		ConfigurationClosure closure = null;

		ConfigPackageContentProvider cp = null;

		public ConfigTreeFilter(ConfigurationClosure closure) {
			this.closure = closure;
		}

		public void setHide() {
			hideUncheckedNodes = hideUncheckedNodes == true ? false : true;
			checkTree.refresh();
		}

		public boolean select(Viewer viewer, Object parentElement,
				Object element) {
			if (checkTree == null) {
				checkTree = (CheckboxTreeViewer) viewer;
				cp = (ConfigPackageContentProvider) checkTree
						.getContentProvider();
			}

			if (hideUncheckedNodes) {
				Object o = cp.getUITargetElement(element);
				return closure.isSelected(o);
			}
			return true;
		}

		public boolean isHiding() {
			return hideUncheckedNodes;
		}

		public void dispose() {
			checkTree = null;
			cp = null;
			closure = null;
		}
	}

	/**
	 * Save configuration
	 * @return
	 * 		True if configuration is save successfully, false otherwise
	 */
	public boolean saveConfiguration() {

		boolean oldNotify = config.eDeliver();
	    try
	    {
	    	//config.eSetDeliver(false);
	    	
			// remove the old entries
			List pkgList = config.getMethodPackageSelection();
			List plgList = config.getMethodPluginSelection();
	
			actionMgr = ((ConfigurationEditor) getEditor()).getActionManager();
			if (!plgList.isEmpty()) {
				if (actionMgr.doAction(IActionManager.REMOVE_MANY, config,
						UmaPackage.eINSTANCE
								.getMethodConfiguration_MethodPluginSelection(),
						plgList, -1) == false) {
					return false;
				}
			}
			if (!pkgList.isEmpty()) {
				if (actionMgr.doAction(IActionManager.REMOVE_MANY, config,
						UmaPackage.eINSTANCE
								.getMethodConfiguration_MethodPackageSelection(),
						pkgList, -1) == false) {
					return false;
				}
			}
	
			// add the new entries
			pkgList = new ArrayList();
			plgList = new ArrayList();
	
			// always get selection from closure
			// Object[] objs = treeViewer.getCheckedElements();
			// //modifiedList.toArray();
			Object[] objs = closure.getSelection();
	
			for (int i = 0; i < objs.length; i++) {
				if ( (objs[i] instanceof MethodPlugin) && !plgList.contains(objs[i]) ) {				
					plgList.add(objs[i]);
					
					// add all system packages into the package selection
					List pkgs = TngUtil.getAllSystemPackages((MethodPlugin)objs[i]);
					for (Iterator it = pkgs.iterator(); it.hasNext();) {
						Object pkg = it.next();
						if (!pkgList.contains(pkg)) {
							pkgList.add(pkg);
						}
					}
				}
				else if ( (objs[i] instanceof MethodPackage) && !pkgList.contains(objs[i]) ) {
					pkgList.add(objs[i]);
				}
			}
			
			actionMgr = ((ConfigurationEditor) getEditor()).getActionManager();
			if (!plgList.isEmpty()) {
				if (actionMgr.doAction(IActionManager.ADD_MANY, config,
						UmaPackage.eINSTANCE
								.getMethodConfiguration_MethodPluginSelection(),
						plgList, -1) == false) {
					return false;
				}
			}
			if (!pkgList.isEmpty()) {
				if (actionMgr.doAction(IActionManager.ADD_MANY, config,
						UmaPackage.eINSTANCE
								.getMethodConfiguration_MethodPackageSelection(),
						pkgList, -1) == false) {
					return false;
				}
			}
	
			return true;
		
		} finally {
			config.eSetDeliver(oldNotify);
		}
	}

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

		if (libListener != null) {
			ILibraryManager manager = LibraryService.getInstance().getCurrentLibraryManager();
			if (manager != null) {
				manager.removeListener(libListener);
			}
		}

		if (msgView != null && msgViewListener != null) {
			msgView.removeSelectionChangedListener(msgViewListener);
		}

		if (configFilter != null) {
			configFilter.dispose();
		}

		if (closure != null) {
			closure.dispose();
			closure = null;
		}

		config.eAdapters().remove(configurationChangedListener);
	}

	private MessageView getMessageView() {
		if (msgView == null || msgView.isDisposed()) {
			// add a listener for message selection changes
			msgView = MessageView.getView();
			msgView.configurationFactoryChanged(closure);

			msgViewListener = new ISelectionChangedListener() {
				public void selectionChanged(SelectionChangedEvent event) {
					IStructuredSelection sel = (IStructuredSelection) event
							.getSelection();
					Object[] selObjs = sel.toArray();
					if ((selObjs != null) && (selObjs.length > 0)) {
						EObject node = null;
						if (selObjs[0] instanceof ElementDependencyError) {
							node = (EObject) ((ElementDependencyError) selObjs[0])
									.getErrorElement();
						} else if (selObjs[0] instanceof ErrorInfo) {
							ErrorInfo info = (ErrorInfo) selObjs[0];
							// node = (EObject) info.getOwnerElement();

							// show the cause element
							node = (EObject) info.getCauseElement();

						}

						else if (selObjs[0] instanceof ElementReference) {
							node = (EObject) ((ElementReference) selObjs[0])
									.getRefElement();
							if (node != null) {
								node = node.eContainer();
							}
						}

						if (node != null) {
							treeViewer.setSelection(LibraryUtil
									.getSelectable(node));
						}
					}
				}
			};

			msgView.addSelectionChangedListener(msgViewListener);
		}

		return msgView;
	}

	private void updateMessage() {
		// if nothing to show, don't show the message view
		if (closure.hasProblem()
				|| ((msgView != null) && !msgView.isDisposed())) {
			getMessageView().updateMessage();
		}
	}

	/**
	 * Get configuration closure
	 */
	public ConfigurationClosure getClosure() {
		return closure;
	}
	
	private void addEditorSetFocusLiseners() {
		if (getEditor() instanceof ConfigurationEditor) {
			Listener lis = new Listener() {
				public void handleEvent (Event event) {
					if (event.data == ConfigurationPage.this && needUpdate && treeViewer != null)	{
						reInitializeConfigFactory();
						treeViewer.refresh();
						updateCheckStates();
						showErrors();
						needUpdate = false;
					}
				}
			};
			((ConfigurationEditor) getEditor()).addToSetFocusLiseners(lis);
		}
	}

}