//------------------------------------------------------------------------------
// 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.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.plugin.AbstractPlugin;
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.Providers;
import org.eclipse.epf.library.edit.TngAdapterFactory;
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.jface.preference.IPreferenceStore;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;

/**
 * The default method library adapter factory implementation.
 * 
 * @author Phong Nguyen Le
 * @since 1.0
 */
public class TngAdapterFactoryImpl implements TngAdapterFactory {
	
	private ExposedAdapterFactory wbsAdapterFactory = null;

	private ExposedAdapterFactory obsAdapterFactory = null;

	private ExposedAdapterFactory pbsAdapterFactory = null;

	private AdapterFactory[] wbsAdapterFactories = null;

	private AdapterFactory[] obsAdapterFactories = null;

	private AdapterFactory[] pbsAdapterFactories = null;

	private AdapterFactory[] procAdapterFactories = null;

	private ExposedAdapterFactory navigatorAdapterFactory;

	private ExposedAdapterFactory configurationAdapterFactory;

	private ExposedAdapterFactory configProcessViewAdapterFactory;

	private ExposedAdapterFactory itemsFilterAdapterFactory;

	private ExposedAdapterFactory pbsFilterAdapaterFactory;

	private ExposedAdapterFactory obsFilterAdapaterFactory;

	private 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) {
			WBSItemProviderAdapterFactory 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) {
					navigatorAdapterFactory = new ExposedAdapterFactory(
							new AdapterFactory[] {
									// new ResourceItemProviderAdapterFactory(),
									new org.eclipse.epf.library.edit.navigator.ItemProviderAdapterFactory(),
									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) {
					configurationAdapterFactory = new ExposedAdapterFactory(
							new AdapterFactory[] {
									// new ResourceItemProviderAdapterFactory(),
									new org.eclipse.epf.library.edit.configuration.ItemProviderAdapterFactory(),
									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);
	}

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

		static {
			CLASSES_EXCLUDED_FROM_SORTING.add(Activity.class);
			CLASSES_EXCLUDED_FROM_SORTING.add(CustomCategory.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 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();
					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);

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

	}

	private 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();
		AbstractPlugin authoringPlugin = Providers.getAuthoringPlugin();
		if (authoringPlugin != null) {
			IPreferenceStore prefStore = authoringPlugin.getPreferenceStore();
			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();
					AbstractPlugin authoringPlugin = Providers.getAuthoringPlugin();
					if (authoringPlugin != null) {
						IPreferenceStore prefStore = authoringPlugin
								.getPreferenceStore();
						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
					//
					final IPreferenceStore prefStore = authoringPlugin.getPreferenceStore();
					Suppression.setAutoInheritSuppressionStates(prefStore.getBoolean(LibraryEditConstants.PREF_INHERIT_SUPPRESSION_STATE));
					prefStore.addPropertyChangeListener(new IPropertyChangeListener() {

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

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

					procAdapterFactory = new ExposedAdapterFactory(
							procAdapterFactories);
				}
			}
		}

		return procAdapterFactory;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.library.edit.TngAdapterFactory#reset()
	 */
	public void reset() {
		Suppression.clearCachedSuppressions();

		TngUtil.umaItemProviderAdapterFactory.dispose();

		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
			//
			AbstractPlugin authoringPlugin = Providers.getAuthoringPlugin();
			if (authoringPlugin != null) {
				IPreferenceStore prefStore = authoringPlugin
						.getPreferenceStore();
				for (int i = 0; i < procAdapterFactories.length; i++) {
					Object adapterFactory = procAdapterFactories[i];
					if (adapterFactory instanceof IPropertyChangeListener) {
						prefStore
								.removePropertyChangeListener((IPropertyChangeListener) 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();
		}
	}

}
