//------------------------------------------------------------------------------
// 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.library.edit.internal;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.common.command.Command;
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.Notifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.edit.command.CommandParameter;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.provider.IChangeNotifier;
import org.eclipse.emf.edit.provider.IDisposable;
import org.eclipse.emf.edit.provider.IItemLabelProvider;
import org.eclipse.emf.edit.provider.IItemPropertyDescriptor;
import org.eclipse.emf.edit.provider.IItemPropertySource;
import org.eclipse.emf.edit.provider.INotifyChangedListener;
import org.eclipse.emf.edit.provider.IStructuredItemContentProvider;
import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
import org.eclipse.emf.edit.provider.ItemProviderAdapter;
import org.eclipse.emf.edit.provider.ReflectiveItemProviderAdapterFactory;
import org.eclipse.epf.common.preferences.IPreferenceStoreWrapper;
import org.eclipse.epf.common.preferences.IPropertyChangeEventWrapper;
import org.eclipse.epf.common.preferences.IPropertyChangeListenerWrapper;
import org.eclipse.epf.library.edit.IConfigurable;
import org.eclipse.epf.library.edit.IConfigurator;
import org.eclipse.epf.library.edit.IFilter;
import org.eclipse.epf.library.edit.ILibraryItemProvider;
import org.eclipse.epf.library.edit.IWrapper;
import org.eclipse.epf.library.edit.LibraryEditPlugin;
import org.eclipse.epf.library.edit.Providers;
import org.eclipse.epf.library.edit.TngAdapterFactory;
import org.eclipse.epf.library.edit.configuration.PracticeItemProvider;
import org.eclipse.epf.library.edit.process.OBSItemProviderAdapterFactory;
import org.eclipse.epf.library.edit.process.PBSItemProviderAdapterFactory;
import org.eclipse.epf.library.edit.process.WBSItemProviderAdapterFactory;
import org.eclipse.epf.library.edit.util.Comparators;
import org.eclipse.epf.library.edit.util.ConfigurableComposedAdapterFactory;
import org.eclipse.epf.library.edit.util.ExposedAdapterFactory;
import org.eclipse.epf.library.edit.util.LibraryEditConstants;
import org.eclipse.epf.library.edit.util.ProcessUtil;
import org.eclipse.epf.library.edit.util.Suppression;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.ContentElement;
import org.eclipse.epf.uma.CustomCategory;
import org.eclipse.epf.uma.Milestone;
import org.eclipse.epf.uma.TaskDescriptor;
import org.eclipse.epf.uma.TeamProfile;
import org.osgi.framework.Bundle;

/**
 * The default method library adapter factory implementation.
 * 
 * @author Phong Nguyen Le
 * @since 1.0
 */
public class TngAdapterFactoryImpl implements TngAdapterFactory {
	private static final String WBS_ADAPTER_FACTORY_ID = "wbs"; //$NON-NLS-1$
	private static final String LIBRARY_ADAPTER_FACTORY_ID = "library"; //$NON-NLS-1$
	private static final String CONFIGURATION_ADAPTER_FACTORY_ID = "configuration"; //$NON-NLS-1$

	private ExposedAdapterFactory wbsAdapterFactory = null;

	private ExposedAdapterFactory obsAdapterFactory = null;

	private ExposedAdapterFactory pbsAdapterFactory = null;

	private AdapterFactory[] wbsAdapterFactories = null;

	private AdapterFactory[] obsAdapterFactories = null;

	private AdapterFactory[] pbsAdapterFactories = null;

	protected AdapterFactory[] procAdapterFactories = null;

	private ExposedAdapterFactory navigatorAdapterFactory;

	protected ExposedAdapterFactory configurationAdapterFactory;

	private ExposedAdapterFactory configProcessViewAdapterFactory;

	private ExposedAdapterFactory itemsFilterAdapterFactory;

	private ExposedAdapterFactory pbsFilterAdapaterFactory;

	private ExposedAdapterFactory obsFilterAdapaterFactory;

	protected ExposedAdapterFactory procAdapterFactory;

	/**
	 * 
	 */
	public TngAdapterFactoryImpl() {
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.epf.uma.tng.TngAdapterFactory#getWBS_AdapterFactory()
	 */
	public ComposedAdapterFactory getWBS_ComposedAdapterFactory() {
		if (wbsAdapterFactory == null) {
			synchronized (this) {
				if (wbsAdapterFactory == null) {
					wbsAdapterFactory = new ExposedAdapterFactory(
							getWBS_AdapterFactories());
				}
			}
		}
		return wbsAdapterFactory;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.epf.uma.tng.TngAdapterFactory#getOBS_AdapterFactory()
	 */
	public ComposedAdapterFactory getOBS_ComposedAdapterFactory() {
		if (obsAdapterFactory == null) {
			synchronized (this) {
				if (obsAdapterFactory == null) {
					obsAdapterFactory = new ExposedAdapterFactory(
							getOBS_AdapterFactories());
				}
			}
		}
		return obsAdapterFactory;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.epf.uma.tng.TngAdapterFactory#getPBS_AdapterFactory()
	 */
	public ComposedAdapterFactory getPBS_ComposedAdapterFactory() {
		if (pbsAdapterFactory == null) {
			synchronized (this) {
				if (pbsAdapterFactory == null) {
					pbsAdapterFactory = new ExposedAdapterFactory(
							getPBS_AdapterFactories());
				}
			}
		}
		return pbsAdapterFactory;
	}

	private AdapterFactory[] getWBS_AdapterFactories() {
		if (wbsAdapterFactories == null) {
			AdapterFactory factory = createAdapterFactoryFromExtension(WBS_ADAPTER_FACTORY_ID);
			if(factory == null) {
				factory = new WBSItemProviderAdapterFactory();
			}
			wbsAdapterFactories = new AdapterFactory[] {
			// new ResourceItemProviderAdapterFactory(),
					factory,
					// new BSProcesstypesItemProviderAdapterFactory(factory),
					new ReflectiveItemProviderAdapterFactory() };
		}
		return wbsAdapterFactories;
	}

	private AdapterFactory[] getOBS_AdapterFactories() {
		if (obsAdapterFactories == null) {
			OBSItemProviderAdapterFactory factory = new OBSItemProviderAdapterFactory();
			obsAdapterFactories = new AdapterFactory[] {
			// new ResourceItemProviderAdapterFactory(),
					factory,
					// new BSProcesstypesItemProviderAdapterFactory(factory),
					new ReflectiveItemProviderAdapterFactory() };
		}
		return obsAdapterFactories;
	}

	private AdapterFactory[] getPBS_AdapterFactories() {
		if (pbsAdapterFactories == null) {
			PBSItemProviderAdapterFactory factory = new PBSItemProviderAdapterFactory();
			pbsAdapterFactories = new AdapterFactory[] {
			// new ResourceItemProviderAdapterFactory(),
					factory,
					// new BSProcesstypesItemProviderAdapterFactory(factory),
					new ReflectiveItemProviderAdapterFactory() };
		}
		return pbsAdapterFactories;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.library.edit.TngAdapterFactory#getNavigatorView_ComposedAdapterFactory()
	 */
	public ComposedAdapterFactory getNavigatorView_ComposedAdapterFactory() {
		if (navigatorAdapterFactory == null) {
			synchronized (this) {
				if (navigatorAdapterFactory == null) {
					AdapterFactory factory = createAdapterFactoryFromExtension(LIBRARY_ADAPTER_FACTORY_ID);
					if (factory == null) {
						factory = new org.eclipse.epf.library.edit.navigator.ItemProviderAdapterFactory();
					}
					navigatorAdapterFactory = new ExposedAdapterFactory(
							new AdapterFactory[] {
									// new
									// ResourceItemProviderAdapterFactory(),
									factory,
									new ReflectiveItemProviderAdapterFactory() });
				}
			}
		}
		return navigatorAdapterFactory;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.library.edit.TngAdapterFactory#getNavigatorView_ComposedAdapterFactory()
	 */
	// public ComposedAdapterFactory getFilterView_ComposedAdapterFactory() {
	// if(filterAdapterFactory == null) {
	// synchronized(this) {
	// if(filterAdapterFactory == null) {
	// filterAdapterFactory = new ComposedAdapterFactory(
	// new AdapterFactory[] {
	// new ResourceItemProviderAdapterFactory(),
	// new com.ibm.library.edit.filter.ItemProviderAdapterFactory(),
	// new ReflectiveItemProviderAdapterFactory()
	// });
	// }
	// }
	// }
	// return filterAdapterFactory;
	// }
	//    
	public ComposedAdapterFactory getConfigurationView_ComposedAdapterFactory() {
		if (configurationAdapterFactory == null) {
			synchronized (this) {
				if (configurationAdapterFactory == null) {
					AdapterFactory factory = createAdapterFactoryFromExtension(CONFIGURATION_ADAPTER_FACTORY_ID);
					if(factory == null) {
						factory = new org.eclipse.epf.library.edit.configuration.ItemProviderAdapterFactory();
					}
					configurationAdapterFactory = new ExposedAdapterFactory(
							new AdapterFactory[] {
									// new ResourceItemProviderAdapterFactory(),
									factory,
									new ReflectiveItemProviderAdapterFactory() });
				}
			}
		}
		return configurationAdapterFactory;

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.library.edit.TngAdapterFactory#getNavigatorView_FilterAdapterFactory(com.ibm.library.edit.IFilter)
	 */
	public AdapterFactory getConfigurationView_AdapterFactory(IFilter filter) {
		return new FilterAdapterFactory(
				getConfigurationView_ComposedAdapterFactory(), filter);
	}

	protected static class FilterItemProvider implements Adapter,
			IStructuredItemContentProvider, ITreeItemContentProvider,
			IItemLabelProvider, IItemPropertySource {
		private static final HashSet<Class<?>> CLASSES_EXCLUDED_FROM_SORTING = new HashSet<Class<?>>();

		static {
			CLASSES_EXCLUDED_FROM_SORTING.add(Activity.class);
			CLASSES_EXCLUDED_FROM_SORTING.add(CustomCategory.class);
			CLASSES_EXCLUDED_FROM_SORTING.add(TaskDescriptor.class);
			CLASSES_EXCLUDED_FROM_SORTING.add(TeamProfile.class);
		}

		private ItemProviderAdapter adapter;

		private IFilter filter;

		private boolean isAdapterConfigurable;

		FilterItemProvider(ItemProviderAdapter adapter, IFilter filter) {
			this.adapter = adapter;
			this.filter = filter;
			if (adapter instanceof IConfigurable) {
				isAdapterConfigurable = true;
				((IConfigurable) adapter).setFilter(filter);
			}

		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.emf.common.notify.Adapter#notifyChanged(org.eclipse.emf.common.notify.Notification)
		 */
		public void notifyChanged(Notification notification) {
			adapter.notifyChanged(notification);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.emf.common.notify.Adapter#getTarget()
		 */
		public Notifier getTarget() {
			return adapter.getTarget();
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.emf.common.notify.Adapter#setTarget(org.eclipse.emf.common.notify.Notifier)
		 */
		public void setTarget(Notifier newTarget) {
			adapter.setTarget(newTarget);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.emf.common.notify.Adapter#isAdapterForType(java.lang.Object)
		 */
		public boolean isAdapterForType(Object type) {
			return adapter.isAdapterForType(type);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.emf.edit.provider.IEditingDomainItemProvider#getChildren(java.lang.Object)
		 */
		public Collection<?> getChildren(Object object) {
			List<Object> children = null;
			fake_loop: do {
				
				// Order is not important, If adapter is ILibraryItemProvider
				// and replaceChildren is false and IConfigurable, it should  
				// go to isAdapterConfigurable, not to regular iteration.

				if (filter instanceof IConfigurator
						&& adapter instanceof ILibraryItemProvider) {
					IConfigurator configurator = (IConfigurator) filter;
					children = new ArrayList<Object>();
					boolean replaceChildren = false;
					for (Iterator iter = ((ILibraryItemProvider) adapter)
							.getChildrenFeatures(object).iterator(); iter
							.hasNext();) {
						EStructuralFeature feature = (EStructuralFeature) iter
								.next();
						Collection otherChildren = configurator.getChildren(
								object, feature);
						if (otherChildren != null) {
							replaceChildren = true;
							if (adapter instanceof IWrapper) {
								IWrapper wrapper = (IWrapper) adapter;
								for (Iterator iterator = otherChildren
										.iterator(); iterator.hasNext();) {
									Object child = iterator.next();
									children.add(wrapper.wrap((EObject) object,
											feature, child,
											CommandParameter.NO_INDEX));
								}
							} else {
								children.addAll(otherChildren);
							}
						}
					}
					if (replaceChildren) {
						break fake_loop;
					}
				} 
				if (isAdapterConfigurable) {
					Collection collection = adapter.getChildren(object);
					if (collection instanceof List) {
						children = (List) collection;
					} else {
						children = new ArrayList(collection);
					}
					break fake_loop;
				}
				
				// regular adapter
				children = new ArrayList(adapter.getChildren(object));
				for (Iterator iter = children.iterator(); iter.hasNext();) {
					Object element = (Object) iter.next();
					if (!filter.accept(element)) {
						iter.remove();
					}
				}
			} while (false);

			if (adapter instanceof PracticeItemProvider) {
				return ((PracticeItemProvider) adapter).getModifiedChildren(children);
			}
			
			// alphabetically sort the children
			//
			if (!TngUtil.isInstanceOf(CLASSES_EXCLUDED_FROM_SORTING, TngUtil
					.unwrap(object))) {
				Collections.sort(children,
						Comparators.PRESENTATION_NAME_COMPARATOR);
			}

			// System.out.println("FilterItemProvider.getChildren() returned " +
			// children);
			return children;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.emf.edit.provider.IEditingDomainItemProvider#getParent(java.lang.Object)
		 */
		public Object getParent(Object object) {
			return adapter.getParent(object);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.emf.edit.provider.IEditingDomainItemProvider#getNewChildDescriptors(java.lang.Object,
		 *      org.eclipse.emf.edit.domain.EditingDomain, java.lang.Object)
		 */
		public Collection getNewChildDescriptors(Object object,
				EditingDomain editingDomain, Object sibling) {
			return adapter.getNewChildDescriptors(object, editingDomain,
					sibling);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.emf.edit.provider.IEditingDomainItemProvider#createCommand(java.lang.Object,
		 *      org.eclipse.emf.edit.domain.EditingDomain, java.lang.Class,
		 *      org.eclipse.emf.edit.command.CommandParameter)
		 */
		public Command createCommand(Object object,
				EditingDomain editingDomain, Class commandClass,
				CommandParameter commandParameter) {
			return adapter.createCommand(object, editingDomain, commandClass,
					commandParameter);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.emf.edit.provider.IStructuredItemContentProvider#getElements(java.lang.Object)
		 */
		public Collection getElements(Object object) {
			return adapter.getElements(object);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.emf.edit.provider.ITreeItemContentProvider#hasChildren(java.lang.Object)
		 */
		public boolean hasChildren(Object object) {
			if (filter instanceof IConfigurator
					&& adapter instanceof ILibraryItemProvider) {
				// always return true to improve performance
				//
				return true;
			}
			if(object instanceof ContentElement){
				return adapter.hasChildren(object);
			}
			if(TngUtil.unwrap(object) instanceof Milestone) {
				return false;
			}
			return true;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.emf.edit.provider.IItemLabelProvider#getText(java.lang.Object)
		 */
		public String getText(Object object) {
			return adapter.getText(object);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.emf.edit.provider.IItemLabelProvider#getImage(java.lang.Object)
		 */
		public Object getImage(Object object) {
			return adapter.getImage(object);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.emf.edit.provider.IItemPropertySource#getPropertyDescriptors(java.lang.Object)
		 */
		public List getPropertyDescriptors(Object object) {
			return adapter.getPropertyDescriptors(object);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.emf.edit.provider.IItemPropertySource#getPropertyDescriptor(java.lang.Object,
		 *      java.lang.Object)
		 */
		public IItemPropertyDescriptor getPropertyDescriptor(Object object,
				Object propertyID) {
			return adapter.getPropertyDescriptor(object, propertyID);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.emf.edit.provider.IItemPropertySource#getEditableValue(java.lang.Object)
		 */
		public Object getEditableValue(Object object) {
			return adapter.getEditableValue(object);
		}

	}

	protected static class FilterAdapterFactory implements AdapterFactory,
			IChangeNotifier, IDisposable {

		private ComposedAdapterFactory adapterFactory;

		private IFilter filter;

		/**
		 * 
		 */
		public FilterAdapterFactory(ComposedAdapterFactory adapterFactory,
				IFilter filter) {
			this.adapterFactory = adapterFactory;
			if(adapterFactory instanceof ConfigurableComposedAdapterFactory) {
				((ConfigurableComposedAdapterFactory)adapterFactory).setFilter(filter);
			}
			this.filter = filter;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.emf.common.notify.AdapterFactory#isFactoryForType(java.lang.Object)
		 */
		public boolean isFactoryForType(Object type) {
			return adapterFactory.isFactoryForType(type);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.emf.common.notify.AdapterFactory#adapt(java.lang.Object,
		 *      java.lang.Object)
		 */
		public Object adapt(Object object, Object type) {
			Object adapter = adapterFactory.adapt(object, type);
			if (adapter == null || adapter instanceof FilterItemProvider
					|| !(adapter instanceof ItemProviderAdapter)) {
				return adapter;
			}
			return new FilterItemProvider((ItemProviderAdapter) adapter, filter);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.emf.common.notify.AdapterFactory#adapt(org.eclipse.emf.common.notify.Notifier,
		 *      java.lang.Object)
		 */
		public Adapter adapt(Notifier target, Object type) {
			Adapter adapter = adapterFactory.adapt(target, type);
			if (adapter == null || adapter instanceof FilterItemProvider
					|| !(adapter instanceof ItemProviderAdapter)) {
				return adapter;
			}
			return new FilterItemProvider((ItemProviderAdapter) adapter, filter);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.emf.common.notify.AdapterFactory#adaptNew(org.eclipse.emf.common.notify.Notifier,
		 *      java.lang.Object)
		 */
		public Adapter adaptNew(Notifier target, Object type) {
			return adapterFactory.adaptNew(target, type);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.emf.common.notify.AdapterFactory#adaptAllNew(org.eclipse.emf.common.notify.Notifier)
		 */
		public void adaptAllNew(Notifier notifier) {
			adapterFactory.adaptAllNew(notifier);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.emf.edit.provider.IChangeNotifier#fireNotifyChanged(org.eclipse.emf.common.notify.Notification)
		 */
		public void fireNotifyChanged(Notification notification) {
			adapterFactory.fireNotifyChanged(notification);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.emf.edit.provider.IChangeNotifier#addListener(org.eclipse.emf.edit.provider.INotifyChangedListener)
		 */
		public void addListener(INotifyChangedListener notifyChangedListener) {
			adapterFactory.addListener(notifyChangedListener);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.emf.edit.provider.IChangeNotifier#removeListener(org.eclipse.emf.edit.provider.INotifyChangedListener)
		 */
		public void removeListener(INotifyChangedListener notifyChangedListener) {
			adapterFactory.removeListener(notifyChangedListener);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.emf.edit.provider.IDisposable#dispose()
		 */
		public void dispose() {
			filter = null;
		}

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.library.edit.TngAdapterFactory#createWBSComposedAdapterFactory()
	 */
	public ComposedAdapterFactory createWBSComposedAdapterFactory() {
		AdapterFactory[] adapterFactories = new AdapterFactory[] {
		// new ResourceItemProviderAdapterFactory(),
				new WBSItemProviderAdapterFactory(),
				new ReflectiveItemProviderAdapterFactory() };
		return new ExposedAdapterFactory(adapterFactories);
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.epf.library.edit.TngAdapterFactory#createPublishingWBSAdapterFactory()
	 */
	public ComposedAdapterFactory createPublishingWBSAdapterFactory() {
		return new ExposedAdapterFactory(
				new AdapterFactory[] {
						new org.eclipse.epf.library.edit.process.publishing.WBSItemProviderAdapterFactory(),
						new ReflectiveItemProviderAdapterFactory()
				}
		);
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.library.edit.TngAdapterFactory#createTBSComposedAdapterFactory()
	 */
	public ComposedAdapterFactory createTBSComposedAdapterFactory() {
		AdapterFactory[] adapterFactories = new AdapterFactory[] {
		// new ResourceItemProviderAdapterFactory(),
				new OBSItemProviderAdapterFactory(),
				new ReflectiveItemProviderAdapterFactory() };
		return new ExposedAdapterFactory(adapterFactories);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.epf.library.edit.TngAdapterFactory#createPublishingTBSAdapterFactory()
	 */
	public ComposedAdapterFactory createPublishingTBSAdapterFactory() {
		return new ExposedAdapterFactory(
				new AdapterFactory[] {
						new org.eclipse.epf.library.edit.process.publishing.TBSItemProviderAdapterFactory(),
						new ReflectiveItemProviderAdapterFactory()
				}
		);
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.library.edit.TngAdapterFactory#createWPBSComposedAdapterFactory()
	 */
	public ComposedAdapterFactory createWPBSComposedAdapterFactory() {
		AdapterFactory[] adapterFactories = new AdapterFactory[] {
		// new ResourceItemProviderAdapterFactory(),
				new PBSItemProviderAdapterFactory(),
				new ReflectiveItemProviderAdapterFactory() };
		return new ExposedAdapterFactory(adapterFactories);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.library.edit.TngAdapterFactory#createProcessComposedAdapterFactory()
	 */
	public ComposedAdapterFactory createProcessComposedAdapterFactory() {
		org.eclipse.epf.library.edit.process.consolidated.ItemProviderAdapterFactory adapterFactory = new org.eclipse.epf.library.edit.process.consolidated.ItemProviderAdapterFactory();
		IPreferenceStoreWrapper prefStore = Providers.getAuthoringPluginPreferenceStore();
		if (prefStore != null) {
			adapterFactory.setColumnIndexToNameMap(ProcessUtil
					.toColumnIndexToNameMap(prefStore
							.getString(LibraryEditConstants.PREF_WBS_COLUMNS)));
		}
		AdapterFactory[] adapterFactories = new AdapterFactory[] {
		// new ResourceItemProviderAdapterFactory(),
				adapterFactory, new ReflectiveItemProviderAdapterFactory() };

		return new ExposedAdapterFactory(adapterFactories);
	}

	// Section for TNG Filter modification process.
	// filter modification code. Similar to getFilterView_AdapterFactory(IFilter
	// filter)
	public AdapterFactory getItemsFilter_AdapterFactory(IFilter filter) {
		return new FilterAdapterFactory(
				getItemsFilter_ComposedAdapterFactory(), filter);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.library.edit.TngAdapterFactory#getItemsFilter_ComposedAdapterFactory()
	 */
	public ComposedAdapterFactory getItemsFilter_ComposedAdapterFactory() {
		if (itemsFilterAdapterFactory == null) {
			synchronized (this) {
				if (itemsFilterAdapterFactory == null) {
					itemsFilterAdapterFactory = new ExposedAdapterFactory(
							new AdapterFactory[] {
									// new ResourceItemProviderAdapterFactory(),
									new org.eclipse.epf.library.edit.itemsfilter.ItemProviderAdapterFactory(),
									new ReflectiveItemProviderAdapterFactory() });
				}
			}
		}
		return itemsFilterAdapterFactory;
	}

	public AdapterFactory getPBSFilter_AdapterFactory(IFilter filter) {
		return new FilterAdapterFactory(getPBSFilter_ComposedAdapterFactory(),
				filter);
	}

	public ComposedAdapterFactory getPBSFilter_ComposedAdapterFactory() {
		if (pbsFilterAdapaterFactory == null) {
			synchronized (this) {
				if (pbsFilterAdapaterFactory == null) {
					pbsFilterAdapaterFactory = new ExposedAdapterFactory(
							new AdapterFactory[] {
									// new ResourceItemProviderAdapterFactory(),
									new org.eclipse.epf.library.edit.itemsfilter.PBSItemProviderAdapterFactory(),
									new ReflectiveItemProviderAdapterFactory() });
				}
			}
		}
		return pbsFilterAdapaterFactory;
	}

	public AdapterFactory getOBSFilter_AdapterFactory(IFilter filter) {
		return new FilterAdapterFactory(getOBSFilter_ComposedAdapterFactory(),
				filter);
	}

	public ComposedAdapterFactory getOBSFilter_ComposedAdapterFactory() {
		if (obsFilterAdapaterFactory == null) {
			synchronized (this) {
				if (obsFilterAdapaterFactory == null) {
					obsFilterAdapaterFactory = new ExposedAdapterFactory(
							new AdapterFactory[] {
									// new ResourceItemProviderAdapterFactory(),
									new org.eclipse.epf.library.edit.itemsfilter.OBSItemProviderAdapterFactory(),
									new ReflectiveItemProviderAdapterFactory() });
				}
			}
		}
		return obsFilterAdapaterFactory;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.library.edit.TngAdapterFactory#getProcessComposedAdapterFactory()
	 */
	public ComposedAdapterFactory getProcessComposedAdapterFactory() {
		if (procAdapterFactory == null) {
			synchronized (this) {
				if (procAdapterFactory == null) {
					org.eclipse.epf.library.edit.process.consolidated.ItemProviderAdapterFactory adapterFactory = new org.eclipse.epf.library.edit.process.consolidated.ItemProviderAdapterFactory();
					final IPreferenceStoreWrapper prefStore = Providers.getPreferenceStore();
					if (prefStore != null) {
						adapterFactory
								.setColumnIndexToNameMap(ProcessUtil
										.toColumnIndexToNameMap(prefStore
												.getString(LibraryEditConstants.PREF_WBS_COLUMNS)));
						prefStore.addPropertyChangeListener(adapterFactory);
						
						// Initialize "auto inherit suppression states" flag for calculating suppression
						// and add listener to its change
						//
						Suppression.setAutoInheritSuppressionStates(prefStore.getBoolean(LibraryEditConstants.PREF_INHERIT_SUPPRESSION_STATE));
						prefStore.addPropertyChangeListener(new IPropertyChangeListenerWrapper() {

							public void propertyChange(IPropertyChangeEventWrapper event) {
								if(LibraryEditConstants.PREF_INHERIT_SUPPRESSION_STATE.equals(event.getProperty())) {
									Suppression.setAutoInheritSuppressionStates(prefStore.getBoolean(LibraryEditConstants.PREF_INHERIT_SUPPRESSION_STATE));
								}
							}

						});
					}					
				
					procAdapterFactories = new AdapterFactory[] {
							adapterFactory,
							new ReflectiveItemProviderAdapterFactory() };

					procAdapterFactory = new ExposedAdapterFactory(
							procAdapterFactories);
				}
			}
		}

		return procAdapterFactory;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.library.edit.TngAdapterFactory#reset()
	 */
	public void reset() {
		if (navigatorAdapterFactory != null) {
			navigatorAdapterFactory.dispose();
		}

		if (itemsFilterAdapterFactory != null) {
			itemsFilterAdapterFactory.dispose();
			itemsFilterAdapterFactory = null;
		}
		
		if (obsFilterAdapaterFactory != null) {
			obsFilterAdapaterFactory.dispose();
			obsFilterAdapaterFactory = null;
		}
		
		if (pbsFilterAdapaterFactory != null) {
			pbsFilterAdapaterFactory.dispose();
			pbsFilterAdapaterFactory = null;
		}
		
		
		if (configProcessViewAdapterFactory != null) {
			configProcessViewAdapterFactory.dispose();
		}

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

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

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

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

		if (procAdapterFactory != null) {
			// remove adapter factory as property change listener from
			// preference store
			//
			IPreferenceStoreWrapper prefStore = Providers.getAuthoringPluginPreferenceStore();
			if (prefStore != null) {
				for (int i = 0; i < procAdapterFactories.length; i++) {
					Object adapterFactory = procAdapterFactories[i];
					if (adapterFactory instanceof IPropertyChangeListenerWrapper) {
						prefStore
								.removePropertyChangeListener((IPropertyChangeListenerWrapper) adapterFactory);
					}
				}
			}
			procAdapterFactory.dispose();
			procAdapterFactory = null;
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.epf.library.edit.TngAdapterFactory#createPublishingCBSAdapterFactory()
	 */
	public ComposedAdapterFactory createPublishingCBSAdapterFactory() {
		return new ExposedAdapterFactory(
				new AdapterFactory[] {
						new org.eclipse.epf.library.edit.process.publishing.CBSItemProviderAdapterFactory(),
						new ReflectiveItemProviderAdapterFactory()
				}
		);

	}

	/* (non-Javadoc)
	 * @see org.eclipse.epf.library.edit.TngAdapterFactory#createPublishingWPBSAdapterFactory()
	 */
	public ComposedAdapterFactory createPublishingWPBSAdapterFactory() {
		return new ExposedAdapterFactory(
				new AdapterFactory[] {
						new org.eclipse.epf.library.edit.process.publishing.WPBSItemProviderAdapterFactory(),
						new ReflectiveItemProviderAdapterFactory()
				}
		);

	}

	/* (non-Javadoc)
	 * @see org.eclipse.epf.library.edit.TngAdapterFactory#cleanUp()
	 */
	public void cleanUp() {
		Suppression.cleanUp();

		if (navigatorAdapterFactory != null) {
			navigatorAdapterFactory.cleanUp();
		}

		if (itemsFilterAdapterFactory != null) {
			itemsFilterAdapterFactory.cleanUp();
		}
		
		if (obsFilterAdapaterFactory != null) {
			obsFilterAdapaterFactory.cleanUp();
		}
		
		if (pbsFilterAdapaterFactory != null) {
			pbsFilterAdapaterFactory.cleanUp();
		}
		
		
		if (configProcessViewAdapterFactory != null) {
			configProcessViewAdapterFactory.cleanUp();
		}

		if (configurationAdapterFactory != null) {
			configurationAdapterFactory.cleanUp();
		}

		if (wbsAdapterFactory != null) {
			wbsAdapterFactory.cleanUp();
		}

		if (obsAdapterFactory != null) {
			obsAdapterFactory.cleanUp();
		}

		if (pbsAdapterFactory != null) {
			pbsAdapterFactory.cleanUp();
		}

		if (procAdapterFactory != null) {
			procAdapterFactory.cleanUp();
		}
	}

	private static AdapterFactory createAdapterFactoryFromExtension(String id) {
		// Process the contributors.
		//
		IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();
		IExtensionPoint extensionPoint = extensionRegistry.getExtensionPoint(LibraryEditPlugin.PLUGIN_ID, "adapterFactories"); //$NON-NLS-1$
		if (extensionPoint != null) {
			IExtension[] extensions = extensionPoint.getExtensions();
			for (int i = 0; i < extensions.length; i++) {
				IExtension extension = extensions[i];
				String pluginId = extension.getNamespaceIdentifier();
				Bundle bundle = Platform.getBundle(pluginId);
				IConfigurationElement[] configElements = extension
						.getConfigurationElements();
				for (int j = 0; j < configElements.length; j++) {
					IConfigurationElement configElement = configElements[j];
					try {
						String factoryId = configElement.getAttribute("id"); //$NON-NLS-1$
						if(id.equals(factoryId)) {
							String className = configElement.getAttribute("class"); //$NON-NLS-1$
							if(className != null) {
								Object factory = bundle.loadClass(className).newInstance();
								if(factory instanceof AdapterFactory) {
									return (AdapterFactory) factory;
								}
							}
						}
					} catch (Exception e) {
						LibraryEditPlugin.INSTANCE.log(e);
					}
				}
			}
		}
		return null;
	}

}
