//------------------------------------------------------------------------------
// 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.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 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);
		}
	}

}