//------------------------------------------------------------------------------
// 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.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.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.providers.CustomCategoryContentProvider;
import org.eclipse.epf.authoring.ui.providers.CustomCategoryLabelProvider;
import org.eclipse.epf.authoring.ui.providers.CustomCategoryTreeFilter;
import org.eclipse.epf.authoring.ui.views.ConfigurationViewer;
import org.eclipse.epf.authoring.ui.views.CustomCategoryTreeViewerWrapper;
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.ConfigurationData;
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.MethodElementUtil;
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.epf.uma.util.UmaUtil;
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.custom.BusyIndicator;
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;
	
	protected CustomCategoryTreeViewerWrapper addCCViewer;
	
	protected CustomCategoryTreeViewerWrapper subCCViewer;
	
	protected CustomCategoryTreeFilter addCCTreeFilter;

	protected CustomCategoryTreeFilter subCCTreeFilter;

	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);
		addCCViewer.setRoot(input);
		subCCViewer.setRoot(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();
		addCCViewer.expandAll();
		addCCViewer.collapseAll();
		subCCViewer.expandAll();
		subCCViewer.collapseAll();

		// 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());
		
		initializeCCViewers();

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

		// Create Viewer and Handle Listener for the viewer.
		createViewers(toolkit, 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);
		
		// set text widget to CC viewers so they can update description field
		addCCViewer.setTextWidget(elemDespContentText);
		subCCViewer.setTextWidget(elemDespContentText);

		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);
		
		addCCTreeFilter = new CustomCategoryTreeFilter(addCCViewer);
		addCCViewer.addTreeFilter(addCCTreeFilter);
		subCCTreeFilter = new CustomCategoryTreeFilter(subCCViewer);
		subCCViewer.addTreeFilter(subCCTreeFilter);
		
		// show the message view if there is error
		updateMessage();
	}
	
	private void initializeCCViewers() {
		// read from config and check the appropriate items in the CC viewers
    	List addCCs = new ArrayList(config.getAddedCategory());
    	initializeCCViewer(addCCViewer, addCCs);
    	List subCCs = new ArrayList(config.getSubtractedCategory());
    	initializeCCViewer(subCCViewer, subCCs);
    	
		addCCViewer.aboutToOpen();
		subCCViewer.aboutToOpen();
	}
	
	private void initializeCCViewer(CustomCategoryTreeViewerWrapper viewer, List elements) {
		if (!elements.isEmpty())
			viewer.updateSelections(elements);
	}

	private void createViewers(FormToolkit toolkit, Composite sectionClient) {
		Label treeTitleLabel = toolkit.createLabel(sectionClient,
				AuthoringUIResources.ConfigurationPage_TreeTitleLabel);
		{
			GridData gd = new GridData(GridData.BEGINNING
					| GridData.VERTICAL_ALIGN_END);
			treeTitleLabel.setLayoutData(gd);
			gd.horizontalSpan = 1;
		}

		Label addCCTitleLabel = toolkit.createLabel(sectionClient,
				AuthoringUIResources.ConfigurationPage_AddCCTitleLabel);
		{
			GridData gd = new GridData(GridData.BEGINNING
					| GridData.VERTICAL_ALIGN_END);
			addCCTitleLabel.setLayoutData(gd);
			gd.horizontalSpan = 1;
		}
		sectionClient.setLayoutData(new GridData(GridData.FILL_BOTH));
		GridLayout layout = new GridLayout(2, true);
		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;
			gridData.verticalSpan = 3;
			treeViewer.getTree().setLayoutData(gridData);
		}

		addCCViewer = new CustomCategoryTreeViewerWrapper(sectionClient, 200,
				LibraryService.getInstance().getCurrentMethodLibrary(),
				new CustomCategoryContentProvider(TngAdapterFactory.INSTANCE
						.getNavigatorView_ComposedAdapterFactory()),
				new CustomCategoryLabelProvider(TngAdapterFactory.INSTANCE
						.getNavigatorView_ComposedAdapterFactory()));

		Label subCCTitleLabel = toolkit.createLabel(sectionClient,
				AuthoringUIResources.ConfigurationPage_SubCCTitleLabel);
		{
			GridData gd = new GridData(GridData.BEGINNING
					| GridData.VERTICAL_ALIGN_END);
			subCCTitleLabel.setLayoutData(gd);
			gd.horizontalSpan = 1;
		}
		subCCViewer = new CustomCategoryTreeViewerWrapper(sectionClient, 200,
				LibraryService.getInstance().getCurrentMethodLibrary(),
				new CustomCategoryContentProvider(TngAdapterFactory.INSTANCE
						.getNavigatorView_ComposedAdapterFactory()),
				new CustomCategoryLabelProvider(TngAdapterFactory.INSTANCE
						.getNavigatorView_ComposedAdapterFactory()));

		
		// add listener so the 2 CC viewers are in sync
		// that is, when an item is checked in one, it is unchecked in the other
		addCCViewer.addCheckStateListener(new ICheckStateListener() {
			public void checkStateChanged(final CheckStateChangedEvent event) {
				//Potentially long operation - show a busy cursor
				BusyIndicator.showWhile(subCCViewer.getTree().getDisplay(), new Runnable() {
					public void run() {
						if (event.getChecked())
							subCCViewer.selectTreeCheck(event.getElement(), false);
					}
				});
			}
		});

		subCCViewer.addCheckStateListener(new ICheckStateListener() {
			public void checkStateChanged(final CheckStateChangedEvent event) {
				//Potentially long operation - show a busy cursor
				BusyIndicator.showWhile(addCCViewer.getTree().getDisplay(), new Runnable() {
					public void run() {
						if (event.getChecked())
							addCCViewer.selectTreeCheck(event.getElement(), false);
					}
				});
			}
		});
		
		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);
					}

				}
			}
		});
		
		ICheckStateListener CCCheckStateListener = new ICheckStateListener() {
			public void checkStateChanged(CheckStateChangedEvent event) {
				saveCustomCategorySelectionsToConfiguration();
			}
		};
		
		addCCViewer.addCheckStateListener(CCCheckStateListener);
		subCCViewer.addCheckStateListener(CCCheckStateListener);

		// 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
								|| o instanceof CustomCategory) {
							if (o instanceof ProcessComponent) {
								reInitializeConfigFactory();
							}
							refreshViewers();
							updateCheckStates();
							showErrors();
						}
					}
				}
			}
		};

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

	protected void showHideElements() {
		configFilter.setHide();
		addCCTreeFilter.toggleHideUnchecked();
		subCCTreeFilter.toggleHideUnchecked();
//		initializeCCViewers();
		refreshViewers();
		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();

		refreshViewers();

		updateCheckStates();

		saveConfiguration();

		updateMessage();

	}

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

		c.fixProblems();

		refreshViewers();
		
		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() {
		if (ConfigurationData.active) {
			ConfigurationData configData = LibraryService.getInstance()
								.getConfigurationManager(config)
										.getConfigurationData();
			
			configData.setEnableUpdate(false);
			boolean ret = saveConfiguration_();
			configData.setEnableUpdate(true);
	
			return ret;
		} else {
			return saveConfiguration_();
		}
	}
	
	private 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);
		}
	}
	
	/**
	 * Save configuration
	 * @return
	 * 		True if configuration is save successfully, false otherwise
	 */
	public boolean saveCustomCategorySelectionsToConfiguration() {
    	List oldAddCCs = new ArrayList(config.getAddedCategory());
    	List oldSubCCs = new ArrayList(config.getSubtractedCategory());
    	
    	Set<CustomCategory> newAddCCs = addCCViewer.getCheckedCustomCategories();
    	Set<CustomCategory> newSubCCs = subCCViewer.getCheckedCustomCategories();
    	
    	oldAddCCs.removeAll(newAddCCs);
    	oldSubCCs.removeAll(newSubCCs);
    	
    	newAddCCs.removeAll(config.getAddedCategory());
    	newSubCCs.removeAll(config.getSubtractedCategory());
		
		actionMgr = ((ConfigurationEditor) getEditor()).getActionManager();
		if (!oldAddCCs.isEmpty()) {
			if (actionMgr.doAction(IActionManager.REMOVE_MANY, config,
					UmaPackage.eINSTANCE
							.getMethodConfiguration_AddedCategory(),
							oldAddCCs, -1) == false) {
				return false;
			}
		}
		if (!newAddCCs.isEmpty()) {
			if (actionMgr.doAction(IActionManager.ADD_MANY, config,
					UmaPackage.eINSTANCE
							.getMethodConfiguration_AddedCategory(),
							newAddCCs, -1) == false) {
				return false;
			}
			
			if (ConfigurationData.active) {
				Map pluginMap = MethodElementUtil.buildMap(config.getMethodPluginSelection());
				HashSet newAddedPlugins = new HashSet();
				for (Iterator<CustomCategory> it = newAddCCs.iterator(); it.hasNext(); ) {
					CustomCategory cc = it.next();
					MethodPlugin plugin = UmaUtil.getMethodPlugin(cc);
					if (! pluginMap.containsKey(plugin.getGuid())) {
						if (! newAddedPlugins.contains(plugin)) {
							newAddedPlugins.add(plugin);
							config.getMethodPluginSelection().add(plugin);
						}
					}
				}
				if (! newAddedPlugins.isEmpty()) {
					LibraryUtil.validateMethodConfiguration(config);
				}
			}
			
		}
		if (!oldSubCCs.isEmpty()) {
			if (actionMgr.doAction(IActionManager.REMOVE_MANY, config,
					UmaPackage.eINSTANCE
							.getMethodConfiguration_SubtractedCategory(),
							oldSubCCs, -1) == false) {
				return false;
			}
		}
		if (!newSubCCs.isEmpty()) {
			if (actionMgr.doAction(IActionManager.ADD_MANY, config,
					UmaPackage.eINSTANCE
							.getMethodConfiguration_SubtractedCategory(),
							newSubCCs, -1) == false) {
				return false;
			}
		}

		return true;
	}


	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();
						refreshViewers();
						updateCheckStates();
						showErrors();
						needUpdate = false;
					}
				}
			};
			((ConfigurationEditor) getEditor()).addToSetFocusLiseners(lis);
		}
	}
	
	private void refreshViewers() {
		treeViewer.refresh();
		addCCViewer.refresh();
		subCCViewer.refresh();
	}
}