/*******************************************************************************
 * Copyright (c) 2004, 2006 Sybase, Inc. 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:
 *     Sybase, Inc. - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.jsf.facesconfig.ui.page;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

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.domain.AdapterFactoryEditingDomain;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.domain.IEditingDomainProvider;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
import org.eclipse.emf.edit.ui.view.ExtendedPropertySheetPage;
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.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.jst.jsf.facesconfig.emf.ApplicationType;
import org.eclipse.jst.jsf.facesconfig.emf.FacesConfigPackage;
import org.eclipse.jst.jsf.facesconfig.emf.FacesConfigType;
import org.eclipse.jst.jsf.facesconfig.emf.FactoryType;
import org.eclipse.jst.jsf.facesconfig.emf.LifecycleType;
import org.eclipse.jst.jsf.facesconfig.ui.EditorPlugin;
import org.eclipse.jst.jsf.facesconfig.ui.FacesConfigEditor;
import org.eclipse.jst.jsf.facesconfig.ui.EditorMessages;
import org.eclipse.jst.jsf.facesconfig.ui.section.AbstractFacesConfigSection;
import org.eclipse.jst.jsf.facesconfig.ui.section.ApplicationSection;
import org.eclipse.jst.jsf.facesconfig.ui.section.FactorySection;
import org.eclipse.jst.jsf.facesconfig.ui.section.LifecycleSection;
import org.eclipse.jst.jsf.facesconfig.ui.section.LocaleConfigSection;
import org.eclipse.jst.jsf.facesconfig.ui.section.OthersPageBaseSection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.forms.IManagedForm;
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.views.contentoutline.ContentOutlinePage;
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
import org.eclipse.ui.views.properties.IPropertySheetPage;

/**
 * @author Zhi-peng Zhang, sfshi
 * @version
 */

/**
 * This class is the "Others" page.
 */
public class OthersPage extends FormPage implements IFacesConfigPage,
		ISelectionProvider, ISelectionChangedListener, IEditingDomainProvider {

    /**
     * The id of this page in the faces-config editor.
     */
	public static final String PAGE_ID = "org.eclipse.jst.jsf.facesconfig.ui.page.OthersPage";

	private final static Image BANNER_IMAGE = EditorPlugin.getDefault()
			.getImage("form_banner.gif");

	private List leftSections;

	private List rightSections;

	private Object input;

	private List selectionChangedListeners = new ArrayList();

	private IPropertySheetPage propertySheetPage;

	private IContentOutlinePage contentOutlinePage;

	private ISelection currentSelection;

	/**
	 * Constructor of OthersPage;
	 * 
	 * @param editor
	 *            the facesconfig editor;
	 */
	public OthersPage(FacesConfigEditor editor) {
		super(editor, "OthersPage",
				EditorMessages.FacesConfigEditor_Others_TabName);
	}

	protected void createFormContent(IManagedForm managedForm) {
		super.createFormContent(managedForm);
		ScrolledForm form = managedForm.getForm();
		form.setText(EditorMessages.OthersPage_Title);
		form.setBackgroundImage(BANNER_IMAGE);
		fillBody(managedForm, managedForm.getToolkit());
		managedForm.refresh();
	}

	private void initSection(OthersPageBaseSection section, String name,
			String description, ArrayList list) {
		section.getSection().setText(name);
		section.getSection().setDescription(description);
		section.initialize();
		section.addSelectionChangedListener(this);
		section.getSection().setExpanded(false);
		section.getSection().setLayoutData(
				new GridData(GridData.FILL_HORIZONTAL));
		list.add(section);
	}

	private void fillBody(IManagedForm managedForm, FormToolkit toolkit) {
		Composite body = managedForm.getForm().getBody();

		body.setLayout(new GridLayout());

		SashForm sashForm = new SashForm(body, SWT.NONE);
		managedForm.getToolkit().adapt(sashForm, false, false);
		sashForm.setMenu(body.getMenu());
		sashForm.setLayoutData(new GridData(GridData.FILL_BOTH));

		Composite leftContainer = toolkit.createComposite(sashForm);
		leftContainer.setLayout(new GridLayout());

		ArrayList sectionList = new ArrayList();

		OthersPageBaseSection section = new ApplicationSection(
				FacesConfigPackage.eINSTANCE.getActionListenerType(),
				leftContainer, managedForm, this, toolkit);
		initSection(section, EditorMessages.ActionListenerSection_Name,
				EditorMessages.ActionListenerSection_Description,
				sectionList);
		section.getSection().setLayoutData(new GridData(GridData.FILL_BOTH));
		section.getSection().setExpanded(true);

		section = new ApplicationSection(FacesConfigPackage.eINSTANCE
				.getDefaultRenderKitIdType(), leftContainer, managedForm, this,
				toolkit);
		initSection(section,
				EditorMessages.DefaultRenderKitIDSection_Name,
				EditorMessages.DefaultRenderKitIDSection_Description,
				sectionList);

		section = new LocaleConfigSection(FacesConfigPackage.eINSTANCE
				.getSupportedLocaleType(), leftContainer, managedForm, this,
				toolkit);
		initSection(section, EditorMessages.LocaleConfigSection_Name,
				EditorMessages.LocaleConfigSection_Description,
				sectionList);

		section = new ApplicationSection(FacesConfigPackage.eINSTANCE
				.getMessageBundleType(), leftContainer, managedForm, this,
				toolkit);
		initSection(section, EditorMessages.MessageBundleSection_Name,
				EditorMessages.MessageBundleSection_Description,
				sectionList);

		section = new ApplicationSection(FacesConfigPackage.eINSTANCE
				.getNavigationHandlerType(), leftContainer, managedForm, this,
				toolkit);
		initSection(section,
				EditorMessages.NavigationHandlerSection_Name,
				EditorMessages.NavigationHandlerSection_Description,
				sectionList);

		section = new ApplicationSection(FacesConfigPackage.eINSTANCE
				.getPropertyResolverType(), leftContainer, managedForm, this,
				toolkit);
		initSection(section,
				EditorMessages.PropertyResolverSection_Name,
				EditorMessages.PropertyResolverSection_Description,
				sectionList);

		section = new ApplicationSection(FacesConfigPackage.eINSTANCE
				.getStateManagerType(), leftContainer, managedForm, this,
				toolkit);
		initSection(section, EditorMessages.StateManagerSection_Name,
				EditorMessages.StateManagerSection_Description,
				sectionList);

		section = new ApplicationSection(FacesConfigPackage.eINSTANCE
				.getVariableResolverType(), leftContainer, managedForm, this,
				toolkit);
		initSection(section,
				EditorMessages.VariableResolverSection_Name,
				EditorMessages.VariableResolverSection_Description,
				sectionList);

		section = new ApplicationSection(FacesConfigPackage.eINSTANCE
				.getViewHandlerType(), leftContainer, managedForm, this,
				toolkit);
		initSection(section, EditorMessages.ViewHandlerSection_Name,
				EditorMessages.ViewHandlerSection_Description,
				sectionList);

		leftSections = sectionList;

		sectionList = new ArrayList();

		Composite rightContainer = toolkit.createComposite(sashForm);
		rightContainer.setLayout(new GridLayout());
		rightContainer.setLayoutData(new GridData(GridData.FILL_BOTH));

		section = new FactorySection(FacesConfigPackage.eINSTANCE
				.getApplicationFactoryType(), rightContainer, managedForm,
				this, toolkit);
		initSection(section,
				EditorMessages.ApplicationFactorySection_Name,
				EditorMessages.ApplicationFactorySection_Description,
				sectionList);
		section.getSection().setLayoutData(new GridData(GridData.FILL_BOTH));
		section.getSection().setExpanded(true);

		section = new FactorySection(FacesConfigPackage.eINSTANCE
				.getFacesContextFactoryType(), rightContainer, managedForm,
				this, toolkit);
		initSection(section,
				EditorMessages.FacesContextFactorySection_Name,
				EditorMessages.FacesContextFactorySection_Description,
				sectionList);

		section = new FactorySection(FacesConfigPackage.eINSTANCE
				.getLifecycleFactoryType(), rightContainer, managedForm, this,
				toolkit);
		initSection(section,
				EditorMessages.LifecycleFactorySection_Name,
				EditorMessages.LifecycleFactorySection_Description,
				sectionList);

		section = new FactorySection(FacesConfigPackage.eINSTANCE
				.getRenderKitFactoryType(), rightContainer, managedForm, this,
				toolkit);
		initSection(section,
				EditorMessages.RenderKitFactorySection_Name,
				EditorMessages.RenderKitFactorySection_Description,
				sectionList);

		section = new LifecycleSection(FacesConfigPackage.eINSTANCE
				.getPhaseListenerType(), rightContainer, managedForm, this,
				toolkit);
		initSection(section, EditorMessages.PhaseListenerSection_Name,
				EditorMessages.PhaseListenerSection_Description,
				sectionList);

		rightSections = sectionList;

		getSite().setSelectionProvider(this);
	}

	/**
	 * set input for this page when the it got activated at the first time; if
	 * it's not the first time, then refresh the page.
	 * 
	 * @see org.eclipse.ui.forms.editor.FormPage#setActive(boolean)
	 */
	public void setActive(boolean active) {
		super.setActive(active);
		if (active) {
			if (getInput() != ((FacesConfigEditor) getEditor())
					.getFacesConfig()) {
				setInput(((FacesConfigEditor) getEditor()).getFacesConfig());
			} else {
				this.refresh();
			}
		}
	}

	/**
	 * 
	 */
	public void setInput(Object input) {
		if (input instanceof FacesConfigType) {
			this.input = input;
			FacesConfigType facesConfig = (FacesConfigType) input;
			facesConfig.eAdapters().add(new FacesConfigOthersAdapter());
			setInputForApplicationSections(facesConfig);
			setInputForFactorySections(facesConfig);
			setInputForLifecycleSections(facesConfig);
		}
	}

	public boolean isEditor() {
		return true;
	}

	/**
	 * Reset the editor input for the application section
	 */
	public void resetApplicationInput() {
		if (getInput() instanceof FacesConfigType) {
			setInputForApplicationSections((FacesConfigType) getInput());
		}
	}

	/**
	 * Reset the editor input for the factory sections
	 */
	public void resetFactoryInput() {
		if (getInput() instanceof FacesConfigType) {
			setInputForFactorySections((FacesConfigType) getInput());
		}
	}

	/**
	 * Reset the editor input for the lifecycle section
	 */
	public void resetLifecycleInput() {
		if (getInput() instanceof FacesConfigType) {
			setInputForLifecycleSections((FacesConfigType) getInput());
		}
	}

	/**
	 * Sets the model for all Application sub-model elements to facesConfig
	 * @param facesConfig
	 */
	protected void setInputForApplicationSections(FacesConfigType facesConfig) {
		ApplicationType application;
		if (facesConfig.getApplication().size() > 0) {
			application = (ApplicationType) facesConfig.getApplication().get(0);
		} else {
			application = null;
		}
		for (Iterator it = leftSections.iterator(); it.hasNext();) {
			ApplicationSection section = (ApplicationSection) it.next();
			section.setInput(application);
		}
	}

	/**
	 * Sets the model for all Factory  sub-model elements to facesConfig
	 * @param facesConfig
	 */
	protected void setInputForFactorySections(FacesConfigType facesConfig) {
		FactoryType factory;
		if (facesConfig.getFactory().size() > 0) {
			factory = (FactoryType) facesConfig.getFactory().get(0);
		} else {
			factory = null;
		}

		for (Iterator it = rightSections.iterator(); it.hasNext();) {
			Object section = it.next();
			if (section instanceof FactorySection)
				((FactorySection) section).setInput(factory);
		}
	}

	/**
	 * Sets the model for all Lifecycle sub-model elements to facesConfig
	 * @param facesConfig
	 */
	protected void setInputForLifecycleSections(FacesConfigType facesConfig) {
		LifecycleType lifecycle;
		if (facesConfig.getLifecycle().size() > 0) {
			lifecycle = (LifecycleType) facesConfig.getLifecycle().get(0);

		} else {
			lifecycle = null;
		}
		for (Iterator it = rightSections.iterator(); it.hasNext();) {
			Object section = it.next();
			if (section instanceof LifecycleSection)
				((LifecycleSection) section).setInput(lifecycle);
		}
	}

	public Object getInput() {
		return input;
	}

	public void refresh() {

		// only refresh the expanded section;
		for (int i = 0, n = leftSections.size(); i < n; i++) {
			OthersPageBaseSection section = (OthersPageBaseSection) leftSections
					.get(i);
			if (section.getSection().isExpanded()) {
				section.refresh();
			}
		}

		for (int i = 0, n = rightSections.size(); i < n; i++) {
			OthersPageBaseSection section = (OthersPageBaseSection) leftSections
					.get(i);
			if (section.getSection().isExpanded()) {
				section.refresh();
			}
		}

	}

	/**
	 * set other sections' expand state to false, except this section;
	 * 
	 * @param section
	 *            the section that be expanded.
	 */
	public void closeOtherSections(AbstractFacesConfigSection section) {
		OthersPageBaseSection[] sections;
		if (leftSections.contains(section)) {
			sections = (OthersPageBaseSection[]) leftSections
					.toArray(new OthersPageBaseSection[leftSections.size()]);
		} else {
			sections = (OthersPageBaseSection[]) rightSections
					.toArray(new OthersPageBaseSection[rightSections.size()]);
		}
		for (int i = 0, n = sections.length; i < n; i++) {
			AbstractFacesConfigSection aSection = sections[i];
			if (aSection != section && aSection.getSection().isExpanded()) {
				aSection.getSection().setExpanded(false);
				GridData gd = new GridData(GridData.FILL_HORIZONTAL);
				aSection.getSection().setLayoutData(gd);
			}
		}
	}

	/**
	 * An adapter on faces config.
	 * 
	 * @author sfshi
	 * 
	 */
	class FacesConfigOthersAdapter extends AdapterImpl {
		public void notifyChanged(Notification msg) {
			if (msg.getEventType() == Notification.REMOVE
					|| msg.getEventType() == Notification.ADD) {
				if (msg.getFeature() == FacesConfigPackage.eINSTANCE
						.getFacesConfigType_Application()) {
					resetApplicationInput();
				} else if (msg.getFeature() == FacesConfigPackage.eINSTANCE
						.getFacesConfigType_Factory()) {
					resetFactoryInput();
				} else if (msg.getFeature() == FacesConfigPackage.eINSTANCE
						.getFacesConfigType_Lifecycle()) {
					resetLifecycleInput();
				}
			}
		}
	}

	public void addSelectionChangedListener(ISelectionChangedListener listener) {
		// TODO Auto-generated method stub

		selectionChangedListeners.add(listener);
	}

	public ISelection getSelection() {
		if (currentSelection != null)
			return currentSelection;

		return StructuredSelection.EMPTY;
	}

	public void removeSelectionChangedListener(
			ISelectionChangedListener listener) {
		// TODO Auto-generated method stub

		selectionChangedListeners.remove(listener);
	}

	public void selectionChanged(SelectionChangedEvent event) {
		currentSelection = event.getSelection();
		if (event.getSource() instanceof OthersPageBaseSection) {
			OthersPageBaseSection source = (OthersPageBaseSection) event
					.getSource();

			if (source.getSection().isExpanded()) {
				for (int i = 0, n = selectionChangedListeners.size(); i < n; i++) {
					((ISelectionChangedListener) selectionChangedListeners
							.get(i)).selectionChanged(event);
				}
			}
		}
	}

	/**
	 * get the section that is expanded.
	 * 
	 * @return the page section
	 */
	protected OthersPageBaseSection getActiveSection() {
		for (int i = 0, n = leftSections.size(); i < n; i++) {

			OthersPageBaseSection section = (OthersPageBaseSection) leftSections
					.get(i);
			if (section.getSection().isExpanded()) {
				return section;
			}
		}

		for (int i = 0, n = rightSections.size(); i < n; i++) {

			OthersPageBaseSection section = (OthersPageBaseSection) leftSections
					.get(i);
			if (section.getSection().isExpanded()) {
				return section;
			}
		}
		return null;

	}

	public Object getAdapter(Class adapter) {

		if (adapter == IPropertySheetPage.class) {
			return getPropertySheetPage();
		}

		if (adapter == IContentOutlinePage.class) {
			return getOutlinePage();
		}

		return super.getAdapter(adapter);
	}

	private IPropertySheetPage getPropertySheetPage() {

		AdapterFactoryEditingDomain editingDomain = (AdapterFactoryEditingDomain) getEditor()
				.getAdapter(EditingDomain.class);
		AdapterFactory adapterFactory = (AdapterFactory) getEditor()
				.getAdapter(AdapterFactory.class);
		if (propertySheetPage == null) {
			propertySheetPage = new ExtendedPropertySheetPage(editingDomain) {
				public void setSelectionToViewer(List selection) {
					// FacesConfigEditor.this.setSelectionToViewer(selection);
					// FacesConfigEditor.this.setFocus();
				}

				public void setActionBars(IActionBars actionBars) {
					super.setActionBars(actionBars);
					// getActionBarContributor().shareGlobalActions(this,
					// actionBars);
				}
			};
			((ExtendedPropertySheetPage) propertySheetPage)
					.setPropertySourceProvider(new AdapterFactoryContentProvider(
							adapterFactory));
			// this.addSelectionChangedListener((ExtendedPropertySheetPage)
			// propertySheetPage);
		}

		return propertySheetPage;

	}

	private IContentOutlinePage getOutlinePage() {

		if (contentOutlinePage == null) {
			// The content outline is just a tree.
			//
			class OthersContentOutlinePage extends ContentOutlinePage {
				public void createControl(Composite parent) {
					super.createControl(parent);
					TreeViewer contentOutlineViewer = getTreeViewer();
					contentOutlineViewer.addSelectionChangedListener(this);

					AdapterFactory adapterFactory = (AdapterFactory) getEditor()
							.getAdapter(AdapterFactory.class);
					// Set up the tree viewer.
					contentOutlineViewer
							.setContentProvider(new AdapterFactoryContentProvider(
									adapterFactory));
					contentOutlineViewer
							.setLabelProvider(new AdapterFactoryLabelProvider(
									adapterFactory));
					contentOutlineViewer.addFilter(new ViewerFilter() {

						public boolean select(Viewer viewer,
								Object parentElement, Object element) {
							return FacesConfigPackage.eINSTANCE
									.getApplicationType().isInstance(element)
									|| FacesConfigPackage.eINSTANCE
											.getFactoryType().isInstance(
													element)
									|| FacesConfigPackage.eINSTANCE
											.getLifecycleType().isInstance(
													element)
									|| FacesConfigPackage.eINSTANCE
											.getActionListenerType()
											.isInstance(element)
									|| FacesConfigPackage.eINSTANCE
											.getDefaultRenderKitIdType()
											.isInstance(element)
									|| FacesConfigPackage.eINSTANCE
											.getLocaleConfigType().isInstance(
													element)
									|| FacesConfigPackage.eINSTANCE
											.getDefaultLocaleType().isInstance(
													element)
									|| FacesConfigPackage.eINSTANCE
											.getSupportedLocaleType()
											.isInstance(element)
									|| FacesConfigPackage.eINSTANCE
											.getMessageBundleType().isInstance(
													element)
									|| FacesConfigPackage.eINSTANCE
											.getNavigationHandlerType()
											.isInstance(element)
									|| FacesConfigPackage.eINSTANCE
											.getPropertyResolverType()
											.isInstance(element)
									|| FacesConfigPackage.eINSTANCE
											.getStateManagerType().isInstance(
													element)
									|| FacesConfigPackage.eINSTANCE
											.getVariableResolverType()
											.isInstance(element)
									|| FacesConfigPackage.eINSTANCE
											.getViewHandlerType().isInstance(
													element)
									|| FacesConfigPackage.eINSTANCE
											.getApplicationFactoryType()
											.isInstance(element)
									|| FacesConfigPackage.eINSTANCE
											.getFacesContextFactoryType()
											.isInstance(element)
									|| FacesConfigPackage.eINSTANCE
											.getLifecycleFactoryType()
											.isInstance(element)
									|| FacesConfigPackage.eINSTANCE
											.getRenderKitFactoryType()
											.isInstance(element)
									|| FacesConfigPackage.eINSTANCE
											.getPhaseListenerType().isInstance(
													element)

							;
						}
					});

					contentOutlineViewer.setSorter(new ViewerSorter());
					contentOutlineViewer.setInput(getInput());
				}

			}

			contentOutlinePage = new OthersContentOutlinePage();

			// Listen to selection so that we can handle it is a special
			// way.
			//
			contentOutlinePage
					.addSelectionChangedListener(new ISelectionChangedListener() {
						// This ensures that we handle selections correctly.
						public void selectionChanged(SelectionChangedEvent event) {
							setSelection(event.getSelection());
						}
					});

		}

		return contentOutlinePage;

	}

	/**
	 * handle the selection changed event from outline page.
	 * 
	 * @param selection
	 */
	public void setSelection(ISelection selection) {

		if (selection instanceof IStructuredSelection) {
			IStructuredSelection ss = (IStructuredSelection) selection;
			if (ss.isEmpty())
				return;

			EObject object = (EObject) ss.getFirstElement();
			OthersPageBaseSection section = null;

			if (FacesConfigPackage.eINSTANCE.getActionListenerType()
					.isInstance(object)) {
				section = (OthersPageBaseSection) leftSections.get(0);
			} else if (FacesConfigPackage.eINSTANCE.getDefaultRenderKitIdType()
					.isInstance(object)) {
				section = (OthersPageBaseSection) leftSections.get(1);
			} else if (FacesConfigPackage.eINSTANCE.getLocaleConfigType()
					.isInstance(object)) {
				section = (OthersPageBaseSection) leftSections.get(2);
			} else if (FacesConfigPackage.eINSTANCE.getDefaultLocaleType()
					.isInstance(object)) {
				section = (OthersPageBaseSection) leftSections.get(2);
			} else if (FacesConfigPackage.eINSTANCE.getSupportedLocaleType()
					.isInstance(object)) {
				section = (OthersPageBaseSection) leftSections.get(2);
			} else if (FacesConfigPackage.eINSTANCE.getMessageBundleType()
					.isInstance(object)) {
				section = (OthersPageBaseSection) leftSections.get(3);
			} else if (FacesConfigPackage.eINSTANCE.getNavigationHandlerType()
					.isInstance(object)) {
				section = (OthersPageBaseSection) leftSections.get(4);
			} else if (FacesConfigPackage.eINSTANCE.getPropertyResolverType()
					.isInstance(object)) {
				section = (OthersPageBaseSection) leftSections.get(5);
			} else if (FacesConfigPackage.eINSTANCE.getStateManagerType()
					.isInstance(object)) {
				section = (OthersPageBaseSection) leftSections.get(6);
			} else if (FacesConfigPackage.eINSTANCE.getVariableResolverType()
					.isInstance(object)) {
				section = (OthersPageBaseSection) leftSections.get(7);
			} else if (FacesConfigPackage.eINSTANCE.getViewHandlerType()
					.isInstance(object)) {
				section = (OthersPageBaseSection) leftSections.get(8);
			} else if (FacesConfigPackage.eINSTANCE.getApplicationFactoryType()
					.isInstance(object)) {
				section = (OthersPageBaseSection) rightSections.get(0);
			} else if (FacesConfigPackage.eINSTANCE
					.getFacesContextFactoryType().isInstance(object)) {
				section = (OthersPageBaseSection) rightSections.get(1);
			} else if (FacesConfigPackage.eINSTANCE.getLifecycleFactoryType()
					.isInstance(object)) {
				section = (OthersPageBaseSection) rightSections.get(2);
			} else if (FacesConfigPackage.eINSTANCE.getRenderKitFactoryType()
					.isInstance(object)) {
				section = (OthersPageBaseSection) rightSections.get(3);
			} else if (FacesConfigPackage.eINSTANCE.getPhaseListenerType()
					.isInstance(object)) {
				section = (OthersPageBaseSection) rightSections.get(4);
			}
			if (section != null) {
				if (!section.getSection().isExpanded()) {
					this.closeOtherSections(section);
					GridData gd = new GridData(GridData.FILL_BOTH);
					section.getSection().setLayoutData(gd);
					section.getSection().setExpanded(true);
				}
				IStructuredSelection newselection = new StructuredSelection(
						object);
				section.getTableViewer().setSelection(newselection);
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.edit.domain.IEditingDomainProvider#getEditingDomain()
	 */
	public EditingDomain getEditingDomain() {
		return ((FacesConfigEditor) getEditor()).getEditingDomain();
	}
}