/*******************************************************************************
 * Copyright (c) 2008, 2015 Mia-Software and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 *
 * Contributors:
 *    Nicolas Bros (Mia-Software) - initial API and implementation
 *    Nicolas Payneau (Mia-Software) - Enable editability
 *    Nicolas Guyomar (Mia-Software) - Code Synchronization
 *    Nicolas Guyomar (Mia_software) - Bug 333651 Remove of the MoDisco EPackage view and of the metamodel browsing button
 *    Gregoire Dupe (Mia-Software) - Bug 404263 - EditingDomainProvider does not work when using IResourceEditorInput
 *    Grégoire Dupé (Mia-Software) - Bug 471096 - MetaclassInstance features have to be moved to an EMF dedicated plug-in
 *    Gregoire Dupe (Mia-Software) - Bug 472182 - Missing debug information in EcoreBrowser.handleChangedResources(2636)
 *******************************************************************************/
package org.eclipse.modisco.infra.browser.editors;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.EventObject;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CancellationException;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IStorage;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
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.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.emf.common.command.BasicCommandStack;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.command.CommandStack;
import org.eclipse.emf.common.command.CommandStackListener;
import org.eclipse.emf.common.command.CommandWrapper;
import org.eclipse.emf.common.command.CompoundCommand;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.common.ui.MarkerHelper;
import org.eclipse.emf.common.ui.viewer.IViewerProvider;
import org.eclipse.emf.common.util.BasicDiagnostic;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.EValidator;
import org.eclipse.emf.ecore.plugin.EcorePlugin;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.util.EContentAdapter;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.edit.command.AddCommand;
import org.eclipse.emf.edit.command.CreateChildCommand;
import org.eclipse.emf.edit.command.DeleteCommand;
import org.eclipse.emf.edit.command.RemoveCommand;
import org.eclipse.emf.edit.command.SetCommand;
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.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.provider.IItemPropertyDescriptor;
import org.eclipse.emf.edit.provider.IItemPropertySource;
import org.eclipse.emf.edit.provider.ReflectiveItemProviderAdapterFactory;
import org.eclipse.emf.edit.provider.resource.ResourceItemProviderAdapterFactory;
import org.eclipse.emf.edit.ui.dnd.EditingDomainViewerDropAdapter;
import org.eclipse.emf.edit.ui.dnd.LocalTransfer;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
import org.eclipse.emf.edit.ui.provider.PropertyDescriptor;
import org.eclipse.emf.edit.ui.provider.PropertySource;
import org.eclipse.emf.edit.ui.util.EditUIMarkerHelper;
import org.eclipse.emf.edit.ui.util.EditUIUtil;
import org.eclipse.emf.edit.ui.view.ExtendedPropertySheetPage;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.FontDescriptor;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
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.ITreeSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.modisco.facet.util.core.Logger;
import org.eclipse.modisco.infra.browser.Messages;
import org.eclipse.modisco.infra.browser.MoDiscoBrowserPlugin;
import org.eclipse.modisco.infra.browser.actions.LoadFacetsAction;
import org.eclipse.modisco.infra.browser.core.DragAndDropOnLinkCommand;
import org.eclipse.modisco.infra.browser.core.DragAndDropOnModelElementCommand;
import org.eclipse.modisco.infra.browser.core.InstancesForMetaclass;
import org.eclipse.modisco.infra.browser.core.InstancesForMetaclasses;
import org.eclipse.modisco.infra.browser.core.MetaclassList;
import org.eclipse.modisco.infra.browser.core.ModelElementItemEx;
import org.eclipse.modisco.infra.browser.core.QueryItem;
import org.eclipse.modisco.infra.browser.core.SearchResults;
import org.eclipse.modisco.infra.browser.core.InstancesForMetaclasses.MetaclassesChangeListener;
import org.eclipse.modisco.infra.browser.custom.MetamodelView;
import org.eclipse.modisco.infra.browser.custom.core.CustomizationsCatalog;
import org.eclipse.modisco.infra.browser.dialogs.ErrorsDialog;
import org.eclipse.modisco.infra.browser.extensions.LoadingDepthRegistry;
import org.eclipse.modisco.infra.browser.extensions.listeners.DoubleClickListener;
import org.eclipse.modisco.infra.browser.preferences.PreferenceConstants;
import org.eclipse.modisco.infra.browser.queries.SelectedQueriesManager;
import org.eclipse.modisco.infra.browser.queries.SelectedQuery;
import org.eclipse.modisco.infra.browser.uicore.ChangeListener;
import org.eclipse.modisco.infra.browser.uicore.UnwrappingSelectionProvider;
import org.eclipse.modisco.infra.browser.uicore.internal.Activator;
import org.eclipse.modisco.infra.browser.uicore.internal.AppearanceConfiguration;
import org.eclipse.modisco.infra.browser.uicore.internal.CustomTreePainter;
import org.eclipse.modisco.infra.browser.uicore.internal.customization.CustomizationEngine;
import org.eclipse.modisco.infra.browser.uicore.internal.model.AttributeItem;
import org.eclipse.modisco.infra.browser.uicore.internal.model.BigListItem;
import org.eclipse.modisco.infra.browser.uicore.internal.model.ITreeElement;
import org.eclipse.modisco.infra.browser.uicore.internal.model.LinkItem;
import org.eclipse.modisco.infra.browser.uicore.internal.model.ModelElementItem;
import org.eclipse.modisco.infra.browser.uicore.internal.util.EMFUtil;
import org.eclipse.modisco.infra.browser.uicore.internal.util.ImageProvider;
import org.eclipse.modisco.infra.common.core.internal.builder.AbstractMoDiscoCatalog.ModiscoCatalogChangeListener;
import org.eclipse.modisco.infra.common.core.logging.MoDiscoLogger;
import org.eclipse.modisco.infra.common.ui.internal.controls.FormStyleSashForm;
import org.eclipse.modisco.infra.common.ui.internal.controls.Tooltip;
import org.eclipse.modisco.infra.common.ui.internal.editorInputs.IResourceEditorInput;
import org.eclipse.modisco.infra.common.ui.internal.util.DialogUtils;
import org.eclipse.modisco.infra.facet.Facet;
import org.eclipse.modisco.infra.facet.FacetSet;
import org.eclipse.modisco.infra.facet.core.FacetSetCatalog;
import org.eclipse.modisco.infra.facet.core.adapters.instances.MetaclassInstancesAdapterFactoryWithFacet;
import org.eclipse.modisco.infra.facet.core.adapters.instances.MetaclassInstancesAdapterWithFacet;
import org.eclipse.modisco.util.emf.core.internal.allinstances.MetaclassInstances;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
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.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.INavigationLocation;
import org.eclipse.ui.INavigationLocationProvider;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.IStorageEditorInput;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.WorkspaceModifyOperation;
import org.eclipse.ui.contexts.IContextActivation;
import org.eclipse.ui.contexts.IContextService;
import org.eclipse.ui.dialogs.SaveAsDialog;
import org.eclipse.ui.forms.widgets.ExpandableComposite;
import org.eclipse.ui.forms.widgets.Form;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.ui.ide.IGotoMarker;
import org.eclipse.ui.part.EditorPart;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.progress.IWorkbenchSiteProgressService;
import org.eclipse.ui.views.properties.IPropertyDescriptor;
import org.eclipse.ui.views.properties.IPropertySheetPage;
import org.eclipse.ui.views.properties.IPropertySource;
import org.eclipse.ui.views.properties.PropertySheet;
import org.eclipse.ui.views.properties.PropertySheetPage;
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;

/**
 * MoDisco model editor: a two pane editor. The left pane shows the list of
 * metaclasses and the right pane shows the list of instances of the metaclass
 * selected in the left pane.
 * <p>
 * The following pop-up menus can be contributed to this part:
 * <ul>
 * <li>{@link EcoreBrowser#MENU_ID}
 * <li>{@link MetaclassViewer#MENU_ID}
 * </ul>
 */
public class EcoreBrowser extends EditorPart implements ISelectionProvider, IMenuListener,
		IViewerProvider, INavigationLocationProvider, MetaclassesChangeListener,
		IEditingDomainProvider, IGotoMarker {

	public static final String MENU_ID = EcoreBrowser.EDITOR_ID + ".menu"; //$NON-NLS-1$

	private static final int MAIN_FORM_MARGIN_HEIGHT = 6;
	private static final int MAIN_FORM_MARGIN_WIDTH = 4;
	private static final int RIGHT_PANE_SASH_WEIGHT = 65;
	private static final int LEFT_PANE_SASH_WEIGHT = 35;
	private static final int SASH_WIDTH = 4;
	public static final String EDITOR_ID = "org.eclipse.modisco.infra.browser.editorID"; //$NON-NLS-1$
	private static final String PROPERTY_VIEW_ID = "org.eclipse.ui.views.PropertySheet"; //$NON-NLS-1$

	private ResourceSet fResourceSet;

	private Resource model;

	/** An adapter factory that uses the registry */
	private ComposedAdapterFactory adapterFactoryWithRegistry;

	/** The property sheet page. */
	private IPropertySheetPage propertySheetPage;

	/** The tree part of the model editor. */
	private TreeViewer treeViewer;

	private BrowserContentProvider fContentProvider;
	private BrowserLabelProvider fLabelProvider;

	/** The tree component (instances pane) */
	private Tree fTree;

	/** The list of metaclasses that appears in the left pane of the editor */
	private MetaclassViewer metaclassViewer;

	/** This listens to the tree viewer's selection. */
	private ISelectionChangedListener selectionChangedListener;

	/**
	 * This keeps track of all the
	 * {@link org.eclipse.jface.viewers.ISelectionChangedListener}s that are
	 * listening to this editor.
	 */
	private final Collection<ISelectionChangedListener> selectionChangedListeners = new ArrayList<ISelectionChangedListener>();

	/** This keeps track of the selection of the editor as a whole. */
	private ISelection editorSelection = StructuredSelection.EMPTY;

	/**
	 * Resources that have been removed since last activation.
	 */
	private final Collection<Resource> removedResources = new ArrayList<Resource>();

	/**
	 * Resources that have been changed since last activation.
	 */
	private final Collection<Resource> changedResources = new ArrayList<Resource>();

	private final Collection<Resource> savedResources = new ArrayList<Resource>();

	/** This listens for workspace changes. */
	private final IResourceChangeListener resourceChangeListener;

	private Job openModelJob = null;

	/**
	 * Controls whether the problem indication should be updated.
	 */
	private boolean updateProblemIndication = true;

	/**
	 * Map to store the diagnostic associated with a resource.
	 */
	private final Map<Resource, Diagnostic> resourceToDiagnosticMap = new LinkedHashMap<Resource, Diagnostic>();

	/**
	 * The MarkerHelper is responsible for creating workspace resource markers
	 * presented in Eclipse's Problems View.
	 */
	private final MarkerHelper markerHelper = new EditUIMarkerHelper();

	/** Whether the Browser has finished loading */
	private boolean loaded = false;

	/** List of actions that must be done once the browser is loaded */
	private final List<Runnable> doWhenLoaded = new ArrayList<Runnable>();

	private Collection<EPackage> referencedEPackages = null;

	private Composite typesPaneComposite;

	private Composite instancesPaneComposite;

	private Button errorsButton;

	/**
	 * This keeps track of the editing domain that is used to track all changes
	 * to the model.
	 */
	private AdapterFactoryEditingDomain editingDomain;
	/**
	 * The configuration of this editor, which is passed to the adapters, so
	 * that they can use it to change their behavior accordingly
	 */
	private final BrowserConfiguration browserConfiguration;

	/** The composite in which the editor is displayed */
	private Composite parentComposite;

	/** The search box */
	private Text searchBox;

	/** The search job, to allow cancellation in case of a big model */
	private Job searchJob = null;

	/**
	 * The input of the tree viewer, saved before filtering by search, and
	 * restored afterwards
	 */
	private Object savedInput;

	/** A listener on changes to fonts settings */
	private IPropertyChangeListener fontChangeListener;

	/** Listens to changes in the loaded customizations, and updates the viewers */
	private ChangeListener fCustomizationEngineChangeListener = null;

	/** Listens to changes in the Facet catalog, and updates the viewers */
	private ModiscoCatalogChangeListener fFacetsChangeListener = null;

	/** Allows optimized refreshes of the viewer */
	private Job refreshJob = null;

	private FormStyleSashForm sashForm;
	// Initialize to HORIZONTAL representation
	private int styleSashForm = SWT.HORIZONTAL;
	private CustomTreePainter customTreePainter;

	private FormToolkit fFormToolkit;
	private Form form;
	private LeftPane leftPane;
	private TreeToolBar instancesToolBar;

	private BrowserSettingsPersistence settingsPersistence;

	/** Indicates the editor is being disposed */
	private boolean disposing = false;

	private BasicDiagnostic fDiagnostic;

	/**
	 * This listens for when the Properties view becomes active
	 */
	private final IPartListener partListener = new IPartListener() {
		public void partActivated(final IWorkbenchPart p) {
			if (p instanceof PropertySheet) {
				if (((PropertySheet) p).getCurrentPage() == EcoreBrowser.this
						.getPropertySheetPage()) {
					getActionBarContributor().setActiveEditor(EcoreBrowser.this);
					handleActivate();
				}
			} else if (p == EcoreBrowser.this) {
				handleActivate();
			}
		}

		public void partBroughtToTop(final IWorkbenchPart p) {
			// Ignore.
		}

		public void partClosed(final IWorkbenchPart p) {
			// Ignore.
		}

		public void partDeactivated(final IWorkbenchPart p) {
			// Ignore.
		}

		public void partOpened(final IWorkbenchPart p) {
			// Ignore.
		}
	};

	/** Create the Mia Ecore model editor. */
	public EcoreBrowser() {
		super();
		this.browserConfiguration = new BrowserConfiguration(this);

		// load user settings
		this.browserConfiguration.getAppearanceConfiguration().load();

		this.resourceChangeListener = new WorkspaceChangeListener(this);
	}

	/** Set the selection into the tree viewer */
	public void setSelectionToViewer(final Collection<?> selection) {
		final Collection<?> theSelection = selection;

		if (theSelection != null && !theSelection.isEmpty()) {
			Runnable runnable = new Runnable() {
				public void run() {
					if (EcoreBrowser.this.treeViewer != null) {
						EcoreBrowser.this.treeViewer.setSelection(new StructuredSelection(
								theSelection.toArray()), true);
					}
				}
			};
			getSite().getShell().getDisplay().asyncExec(runnable);
		}
	}

	/** @return the viewer as required by the {@link IViewerProvider} interface. */
	public Viewer getViewer() {
		return this.treeViewer;
	}

	public MetaclassViewer getMetaclassViewer() {
		return this.metaclassViewer;
	}

	/**
	 * Create a context menu for the viewer, add a listener, and register the
	 * menu for extension.
	 */
	protected void createContextMenuFor(final StructuredViewer viewer) {
		final MenuManager contextMenu = new MenuManager("#PopUp"); //$NON-NLS-1$
		contextMenu.setRemoveAllWhenShown(true);
		contextMenu.addMenuListener(this);
		final Menu menu = contextMenu.createContextMenu(viewer.getControl());
		viewer.getControl().setMenu(menu);
		getSite().registerContextMenu(EcoreBrowser.MENU_ID, contextMenu,
				new UnwrappingSelectionProvider(viewer));
	}

	/** Load a resource based on the editor's input. */
	protected Resource createModel() {
		Resource result = null;
		Exception exception = null;
		// this.fResourceSet.setURIConverter(createURIConverter());
		this.fResourceSet.getURIConverter().getURIMap().putAll(EcorePlugin.computePlatformURIMap());
		final URI resourceURI = EditUIUtil.getURI(getEditorInput());
		try {
			final IEditorInput editorInput = getEditorInput();
			if (editorInput instanceof FileEditorInput) {
				// Load the resource
				ResourceSet resourceSet = this.editingDomain.getResourceSet();
				synchronized (resourceSet) {
					result = resourceSet.getResource(resourceURI, true);
				}
				this.fResourceSet = this.editingDomain.getResourceSet();
			} else if (editorInput instanceof IResourceEditorInput) {
				IResourceEditorInput resourceEditorInput = (IResourceEditorInput) editorInput;
				result = resourceEditorInput.getResource();
				// this.fResourceSet.getResources().add(result);
				ResourceSet resourceSet = result.getResourceSet();
				if (resourceSet != null) {
					this.fResourceSet = resourceSet;
				}
				setPartName(resourceEditorInput.getName());
			} else if (editorInput instanceof IStorageEditorInput) {
				IStorageEditorInput storageEditorInput = (IStorageEditorInput) editorInput;
				IStorage storage = storageEditorInput.getStorage();
				InputStream inputStream = storage.getContents();
				Resource resource = this.fResourceSet.createResource(URI.createURI(resourceURI
						.toString()));
				resource.load(inputStream, Collections.emptyMap());
				result = resource;
			} else {
				final String resolveURI = resourceURI.toString();
				final EPackage ePackage = this.fResourceSet.getPackageRegistry().getEPackage(
						resolveURI);
				if (ePackage != null) {
					result = ePackage.eResource();
					if (result != null) {
						this.fResourceSet.getResources().add(result);
						setPartName(ePackage.getName());
					}
				} else {
					Display.getDefault().asyncExec(new Runnable() {
						public void run() {
							MessageDialog.openWarning(getSite().getShell(),
									Messages.EcoreBrowser_cannotOpenModelFromURI, NLS.bind(
											Messages.EcoreBrowser_cannotFindEPackageWithThatURI,
											resolveURI));
						}
					});
				}
			}
			initializeEditingDomain(this.fResourceSet);
		} catch (final Exception e) {
			exception = e;
			MoDiscoBrowserPlugin.logException(e);
			Display.getDefault().asyncExec(new Runnable() {
				public void run() {
					MessageDialog.openError(EcoreBrowser.this.parentComposite.getShell(),
							Messages.EcoreBrowser_errorLoadingModel, e.toString());
				}
			});
			this.fResourceSet.getResource(resourceURI, false);
		}
		this.fResourceSet.setURIConverter(BrowserUtils.createURIConverter());

		// look for errors in the Resource
		if (result != null) {
			Diagnostic diagnostic = analyzeResourceProblems(result, exception);
			if (diagnostic.getSeverity() != Diagnostic.OK) {
				this.resourceToDiagnosticMap.put(result, diagnostic);
			}
		}

		this.editingDomain.getResourceSet().eAdapters().add(this.problemIndicationAdapter);

		return result;
	}

	@Override
	protected void setPartName(final String partName) {
		Display.getDefault().syncExec(new Runnable() {
			public void run() {
				EcoreBrowser.super.setPartName(partName);
			}
		});
	}

	protected static final String LOADING_MESSAGE = Messages.EcoreBrowser_loadingModelPlaceholder;

	public static final String HUMAN_READABLE_NAME = Messages.EcoreBrowser_MoDisco_Model_Browser;

	/** Create the editor composite. */
	@Override
	public void createPartControl(final Composite parent) {

		this.fFormToolkit = new FormToolkit(parent.getDisplay());
		this.form = this.fFormToolkit.createForm(parent);

		this.parentComposite = parent;
		parent.setLayout(new FillLayout());

		initializeEditingDomain();

		final FillLayout fillLayout = new FillLayout();
		fillLayout.marginWidth = EcoreBrowser.MAIN_FORM_MARGIN_WIDTH;
		fillLayout.marginHeight = EcoreBrowser.MAIN_FORM_MARGIN_HEIGHT;
		this.form.getBody().setLayout(fillLayout);

		// use an adapter factory that looks in the registry
		this.browserConfiguration.getAppearanceConfiguration().setAdapterFactory(
				this.adapterFactoryWithRegistry);

		this.browserConfiguration.setSelectedQueriesManager(new SelectedQueriesManager());
		this.sashForm = new FormStyleSashForm(this.form.getBody(), this.styleSashForm,
				this.fFormToolkit) {
			@Override
			protected void createContents() {
				createLeftPane(this);
				createTreePane(this);
			}
		};
		this.sashForm.setSashWidth(EcoreBrowser.SASH_WIDTH);

		setupInitialTreeFont();

		this.sashForm.setWeights(new int[] { EcoreBrowser.LEFT_PANE_SASH_WEIGHT,
				EcoreBrowser.RIGHT_PANE_SASH_WEIGHT });

		// keep track of the selection, to be able to restore it when using the
		// "back" button
		addSelectionChangedListener(new ISelectionChangedListener() {
			public void selectionChanged(final SelectionChangedEvent event) {
				markNavigationLocation();
			}
		});

		createContextMenuFor(this.treeViewer);
		DragAdapter.create(this.treeViewer);

		int dndOperations = DND.DROP_COPY | DND.DROP_MOVE | DND.DROP_LINK;
		Transfer[] transfers = new Transfer[] { LocalTransfer.getInstance() };
		EditingDomainViewerDropAdapter editingDomainViewerDropAdapter = new EditingDomainViewerDropAdapter(
				this.editingDomain, this.treeViewer);
		this.treeViewer.addDropSupport(dndOperations, transfers, editingDomainViewerDropAdapter);

		getMetaclassViewer().setInput(EcoreBrowser.LOADING_MESSAGE);
		this.treeViewer.setInput(EcoreBrowser.LOADING_MESSAGE);

		createAttributeItemTooltip();
	}

	private void createAttributeItemTooltip() {
		Tooltip tooltip = new Tooltip() {
			@Override
			protected String getText(final TreeItem item) {
				Object data = item.getData();
				if (data instanceof AttributeItem) {
					AttributeItem attributeItem = (AttributeItem) data;
					if (!attributeItem.getText().contains(attributeItem.getValueText())) {
						return attributeItem.getValueText();
					}
				}
				return null;
			}

			@Override
			protected void positionTooltip(final TreeItem treeItem, final Point pt,
					final Point tooltipSize) {
				Point point = EcoreBrowser.this.treeViewer.getTree().toDisplay(
						treeItem.getBounds().x, treeItem.getBounds().y);
				pt.x = point.x;
				pt.y = point.y;
			}
		};
		tooltip.installOn(this.treeViewer.getTree());
	}

	/**
	 * Load the model in the background, to avoid freezing the UI during this
	 * long-running operation.
	 * <p>
	 * <b>see</b>: Bug 325120 - [Model Browser] don't freeze UI while loading
	 * model
	 *
	 * @param monitor
	 */
	protected boolean backgroundOpenModel(final IProgressMonitor monitor) {
		try {
			checkCancelled(monitor);
			initResourceSet();
			checkCancelled(monitor);
			checkResourceSet();

			if (this.model == null) {
				return false;
			}

			Display.getDefault().syncExec(new Runnable() {
				public void run() {
					getMetaclassViewer().setInput(
							getBrowserConfiguration().getInstancesForMetaclasses());
					/*
					 * Select the metaclass corresponding to the 'root' element
					 * (that is, the 'model' element). This in turn sets the
					 * input of the treeview.
					 */
					getMetaclassViewer().selectRootElement();
				}
			});

			loadDefaultFacetSets(this.model);

			IDialogSettings settingsForCurrentMetamodel = getSettingsPersistence()
					.loadLastSettingsForCurrentMetamodel();

			List<Facet> lastFacets = getSettingsPersistence().getLastFacets(
					settingsForCurrentMetamodel);

			LoadFacetsAction.loadFacets(lastFacets, this);
			// for (Facet facet : lastFacets) {
			// this.browserConfiguration.getAppearanceConfiguration().loadFacet(facet);
			// checkCancelled(monitor);
			// }

			checkCancelled(monitor);
			List<MetamodelView> lastCustomizations = getSettingsPersistence()
					.getLastCustomizations(settingsForCurrentMetamodel);
			if (lastCustomizations.size() > 0) {
				loadCustomizations(lastCustomizations);
			} else {
				loadDefaultCustomizations();
			}

			checkCancelled(monitor);

			// note: must be done after adding or removing facets too
			this.browserConfiguration.getInstancesForMetaclasses().buildDerivationTree();

			// add a listener to reload when Facets are modified
			reloadOnFacetChange();

			checkCancelled(monitor);
		} catch (CancellationException e) {
			// canceled : nothing more to do
			return false;
		} catch (ThreadDeath e) {
			// canceled : nothing more to do
			return false;
		}
		finishedLoading();
		return true;
	}

	private void checkResourceSet() {
		for (Resource resource : this.fResourceSet.getResources()) {
			if (resource.getURI() == null) {
				MoDiscoLogger.logError(
						"The ResourceSet opened in the browser contains a Resource with a null URI. " //$NON-NLS-1$
								+ "This can be the cause of NullPointerExceptions.", //$NON-NLS-1$
						MoDiscoBrowserPlugin.getPlugin());
			}
		}
	}

	private void finishedLoading() {
		for (Runnable runnable : this.doWhenLoaded) {
			try {
				Display.getDefault().syncExec(runnable);
			} catch (Exception e) {
				MoDiscoLogger.logError(e, Activator.getDefault());
			}
		}
		this.getSite().getShell().getDisplay().asyncExec(new Runnable() {
			public void run() {
				firePropertyChange(PROP_INPUT);
			}
		});
	}

	private void checkCancelled(final IProgressMonitor monitor) {
		if (monitor.isCanceled() || this.treeViewer.getTree().isDisposed()) {
			throw new CancellationException();
		}
	}

	public BrowserSettingsPersistence getSettingsPersistence() {
		if (this.settingsPersistence == null) {
			this.settingsPersistence = new BrowserSettingsPersistence(getMetamodelURI(), this,
					this.browserConfiguration);
		}
		return this.settingsPersistence;
	}

	/**
	 * @return the URI of the EPackage corresponding to the EClass of the main
	 *         resource's root element
	 */
	public String getMetamodelURI() {
		if (this.model == null) {
			return ""; //$NON-NLS-1$
		}
		try {
			EList<EObject> contents = this.model.getContents();
			if (contents.size() > 0) {
				EObject eObject = contents.get(0);
				EClass eClass = eObject.eClass();
				if (eClass != null) {
					return eClass.getEPackage().getNsURI();
				}
			}
		} catch (Exception e) {
			MoDiscoLogger.logError(e, MoDiscoBrowserPlugin.getPlugin());
		}
		return ""; //$NON-NLS-1$
	}

	/**
	 * @return {@link EPackage}s of {@link EClass}es from the model's main
	 *         {@link Resource}
	 */
	public Collection<EPackage> getReferencedEPackages() {
		if (this.referencedEPackages != null) {
			return this.referencedEPackages;
		}
		Set<EPackage> ePackages = new HashSet<EPackage>();
		try {
			if (this.model != null) {
				TreeIterator<EObject> allContents = this.model.getAllContents();
				while (allContents.hasNext()) {
					EObject eObject = allContents.next();
					EClass eClass = eObject.eClass();
					if (eClass != null) {
						EPackage ePackage = eClass.getEPackage();
						if (ePackage != null) {
							ePackages.add(ePackage);
						}
					}
				}
			}
		} catch (Exception e) {
			MoDiscoLogger.logError(e, MoDiscoBrowserPlugin.getPlugin());
		}
		this.referencedEPackages = ePackages;
		return ePackages;
	}

	protected void initResourceSet() {
		// create an empty resource set
		this.fResourceSet = createResourceSet();

		HashSet<Resource> browsedResources = new HashSet<Resource>();
		Resource mainResource;
		this.model = createModel();
		mainResource = this.model;
		if (mainResource != null) {
			browsedResources.add(mainResource);
		}
		this.browserConfiguration.setResourceSet(this.fResourceSet);

		addReferencedResources(mainResource, browsedResources);
		this.browserConfiguration.setBrowsedResources(browsedResources);
		this.browserConfiguration.getAppearanceConfiguration().getFacetContext()
				.setResources(browsedResources);

		final InstancesForMetaclasses instancesForMetaclasses = createInstancesForMetaclasses(browsedResources);
		this.browserConfiguration.setInstancesForMetaclasses(instancesForMetaclasses);

		instancesForMetaclasses.addListener(this);

		// see Bug 322985 - resources lazy loading and dynamic type panel
		// completion
		// watch ResourceSet to be notified when a Resource is lazy-loaded
		// when that happens, add its elements to the Types panel
		this.fResourceSet.eAdapters().add(new AdapterImpl() {
			@Override
			public void notifyChanged(final Notification notification) {
				if (notification.getFeatureID(ResourceSet.class) == ResourceSet.RESOURCE_SET__RESOURCES) {
					int eventType = notification.getEventType();
					if (eventType == Notification.ADD) {
						Object newValue = notification.getNewValue();
						if (newValue instanceof Resource) {
							Resource resource = (Resource) newValue;
							EcoreBrowser.this.browserConfiguration.addBrowsedResource(resource);
							instancesForMetaclasses.watchResource(resource);
							EcoreBrowser.this.browserConfiguration.getAppearanceConfiguration()
									.touch();
							refreshDelayed(true);
						}
					}
					if (eventType == Notification.REMOVE) {
						Object oldValue = notification.getOldValue();
						if (oldValue instanceof Resource) {
							Resource resource = (Resource) oldValue;
							EcoreBrowser.this.browserConfiguration.removeBrowsedResource(resource);
							instancesForMetaclasses.unwatchResource(resource);
							EcoreBrowser.this.browserConfiguration.getAppearanceConfiguration()
									.touch();
							refreshDelayed(true);
						}
					}
				}
			}
		});
	}

	protected InstancesForMetaclasses createInstancesForMetaclasses(
			final Set<Resource> browsedResources) {
		return new InstancesForMetaclasses(this.browserConfiguration, browsedResources);
	}

	/**
	 * Create the resourceSet. This method can be overridden by subclasses.
	 *
	 * @return The ResourceSet.
	 */
	protected ResourceSet createResourceSet() {
		return new ResourceSetImpl();
	}

	/**
	 * Load FacetSet defined as default for the root EPackage of root elements
	 * in the given resource
	 */
	private void loadDefaultFacetSets(final Resource resource) {
		synchronized (resource) {
			for (EObject root : resource.getContents()) {
				EPackage rootEPackage = root.eClass().getEPackage();
				Set<FacetSet> defaultFacetSets = FacetSetCatalog.getSingleton()
						.getDefaultFacetSets(rootEPackage);
				if (defaultFacetSets != null) {
					Set<Facet> facetsToLoad = new HashSet<Facet>();
					for (FacetSet facetSet : defaultFacetSets) {
						if (facetSet != null) {
							facetsToLoad.addAll(facetSet.getFacets());
						}
					}
				}
			}
		}
	}

	/**
	 * If proxies are found, ask the user whether to load resources referenced
	 * by proxies found in the given resource, and up to which depth.
	 *
	 * @param resource
	 *            the resource in which to look for proxies to resolve
	 * @param allResources
	 *            the set of resources to which to add resources referenced by
	 *            proxies
	 */
	private void addReferencedResources(final Resource resource, final Set<Resource> allResources) {
		IPreferenceStore preferenceStore = MoDiscoBrowserPlugin.getPlugin().getPreferenceStore();
		// only walk through the resource contents if necessary
		int registryLoadingDepth = LoadingDepthRegistry.getInstance().getLoadingDepth(
				getMetamodelURI());
		if (preferenceStore.getInt(PreferenceConstants.P_BROWSER_LOADING_DEPTH) != 0
				|| preferenceStore.getBoolean(PreferenceConstants.P_BROWSER_ASK_LOADING_DEPTH)
				|| (registryLoadingDepth != LoadingDepthRegistry.UNDEFINED && registryLoadingDepth != 0)) {
			addReferencedResourcesInternal(resource, allResources, 1);
		}
	}

	/**
	 * Adds resources referenced by proxies found in the given resources to the
	 * set <code>allResources</code>
	 *
	 * @param resource
	 *            the resource in which to look for proxies to resolve
	 * @param allResources
	 *            the set of resources to which to add resources referenced by
	 *            proxies
	 * @param currentDepth
	 *            the current depth
	 *
	 * @see EcoreBrowser#addReferencedResources(Resource, Set)
	 */
	private void addReferencedResourcesInternal(final Resource resource,
			final Set<Resource> allResources, final int currentDepth) {

		final Set<Resource> directReferencedResources = new HashSet<Resource>();

		synchronized (resource) {
			for (EObject root : resource.getContents()) {
				Map<EObject, Collection<EStructuralFeature.Setting>> externalReferences = EcoreUtil.ExternalCrossReferencer
						.find(root);
				if (!externalReferences.isEmpty()) {
					int loadingDepth = this.browserConfiguration
							.getReferencedResourcesLoadingDepth();
					if (loadingDepth == BrowserConfiguration.NOT_YET_ASKED) {
						int registryLoadingDepth = LoadingDepthRegistry.getInstance()
								.getLoadingDepth(getMetamodelURI());
						// whether user settings override registry settings
						boolean overridden = MoDiscoBrowserPlugin
								.getPlugin()
								.getPreferenceStore()
								.getBoolean(
										PreferenceConstants.P_BROWSER_OVERRIDE_METAMODEL_SPECIFIC_SETTINGS);

						if (registryLoadingDepth == LoadingDepthRegistry.UNDEFINED || overridden) {
							final int defaultLoadingDepth = MoDiscoBrowserPlugin.getPlugin()
									.getPreferenceStore()
									.getInt(PreferenceConstants.P_BROWSER_LOADING_DEPTH);
							if (MoDiscoBrowserPlugin.getPlugin().getPreferenceStore()
									.getBoolean(PreferenceConstants.P_BROWSER_ASK_LOADING_DEPTH)) {
								// get shell on UI thread
								final Shell[] shell = new Shell[1];
								Display.getDefault().syncExec(new Runnable() {
									public void run() {
										shell[0] = getSite().getShell();
									}
								});
								loadingDepth = BrowserUtils
										.askUserForDepthToLoadReferencedResources(
												defaultLoadingDepth, shell[0]);
							} else {
								loadingDepth = defaultLoadingDepth;
								if (loadingDepth < -1) {
									loadingDepth = 0;
								}
							}
						} else {
							loadingDepth = registryLoadingDepth;
						}
						this.browserConfiguration.setReferencedResourcesLoadingDepth(loadingDepth);
					}
					if (loadingDepth != -1 && loadingDepth < currentDepth) {
						return;
					}
					for (EObject external : externalReferences.keySet()) {
						Resource externalResource;
						if (external.eIsProxy()) {
							externalResource = EcoreUtil.resolve(external, root).eResource();
						} else {
							externalResource = external.eResource();
						}
						if (externalResource != null) {
							directReferencedResources.add(externalResource);
						} else {
							MoDiscoLogger
									.logError(
											"Failed to load an external element: " + external.eClass().getName() //$NON-NLS-1$
													+ " " + EcoreUtil.getURI(external), //$NON-NLS-1$
											MoDiscoBrowserPlugin.getPlugin());
						}
					}
				}
			}
		}

		int loadingDepth = this.browserConfiguration.getReferencedResourcesLoadingDepth();

		// recurse on sub-resources
		for (Resource directlyReferencedResource : directReferencedResources) {
			if (directlyReferencedResource == null) {
				continue;
			}
			// avoid infinite recursion in the case of mutually referencing
			// resources
			if (!allResources.contains(directlyReferencedResource)) {
				allResources.add(directlyReferencedResource);
				if (loadingDepth == -1 || currentDepth + 1 <= loadingDepth) {
					addReferencedResourcesInternal(directlyReferencedResource, allResources,
							currentDepth + 1);
				}
			}
		}
	}

	/**
	 * Create the left pane, containing the metaclass viewer.
	 *
	 * @param parent
	 *            the parent composite
	 */
	protected void createLeftPane(final Composite parent) {
		final Section section = this.fFormToolkit.createSection(parent,
				ExpandableComposite.TITLE_BAR | ExpandableComposite.EXPANDED);
		section.setText(Messages.EcoreBrowser_metaclasses);
		this.typesPaneComposite = this.fFormToolkit.createComposite(section);
		section.setClient(this.typesPaneComposite);
		this.leftPane = initLeftPane(section, this.fFormToolkit);
		final Composite toolBar = this.leftPane.getToolBarComposite();
		section.setTextClient(toolBar);
		this.typesPaneComposite.setLayout(new FillLayout());
		this.metaclassViewer = this.leftPane.getMetaclassViewer();
		this.metaclassViewer
				.addSelectionChangedListener(new MetaclassListViewerSelectionChangedListener());
	}

	protected LeftPane initLeftPane(final Section section, final FormToolkit formToolkit) {
		return new LeftPane(section, (Composite) section.getClient(), this.browserConfiguration,
				formToolkit, getSite());
	}

	/**
	 * Create the tree and its viewer
	 *
	 * @param parent
	 *            the parent composite of the tree
	 */
	protected void createTreePane(final Composite parent) {

		final Section section = this.fFormToolkit.createSection(parent,
				ExpandableComposite.TITLE_BAR | ExpandableComposite.EXPANDED);
		section.setText(Messages.EcoreBrowser_instances);
		this.instancesPaneComposite = this.fFormToolkit.createComposite(section, SWT.NONE);
		section.setClient(this.instancesPaneComposite);

		final GridLayout layout = new GridLayout();
		layout.marginHeight = 0;
		layout.marginWidth = 0;
		this.instancesPaneComposite.setLayout(layout);

		final Composite treeToolBar = createTreeToolBar(section);
		section.setTextClient(treeToolBar);

		this.errorsButton = new Button(this.instancesPaneComposite, SWT.PUSH);
		this.errorsButton.setText(Messages.EcoreBrowser_errorsAndWarnings);
		this.errorsButton.setToolTipText(Messages.EcoreBrowser_errorsAndWarnings);
		this.errorsButton.setImage(ImageProvider.getInstance().getErrorIcon());
		this.errorsButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(final SelectionEvent e) {
				final ErrorsDialog errorsDialog = new ErrorsDialog(getSite().getShell(),
						EcoreBrowser.this.fDiagnostic);
				errorsDialog.open();
			}
		});
		this.errorsButton.setVisible(false);

		final GridData errorsButtonGridData = new GridData();
		errorsButtonGridData.exclude = true;
		this.errorsButton.setLayoutData(errorsButtonGridData);

		createSearchPanel(this.instancesPaneComposite);

		this.fTree = this.fFormToolkit.createTree(this.instancesPaneComposite, SWT.MULTI
				| SWT.BORDER);
		final GridData treeGridData = new GridData();
		treeGridData.grabExcessHorizontalSpace = true;
		treeGridData.grabExcessVerticalSpace = true;
		treeGridData.horizontalAlignment = SWT.FILL;
		treeGridData.verticalAlignment = SWT.FILL;
		this.fTree.setLayoutData(treeGridData);

		this.fTree.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(final KeyEvent e) {
				if (e.keyCode == SWT.ESC) {
					// Escape on the tree: restore view (after search)
					EcoreBrowser.this.searchBox.setText(""); //$NON-NLS-1$
					search();
				} else if (e.keyCode == SWT.CR) {
					// Enter: browse selected item
					handleEnter();
				} else if (e.keyCode == 'c' && e.stateMask == SWT.CTRL) {
					// Ctrl+C : copy element text to clipboard
					BrowserUtils.handleCopyToClipboard(getEditorSelection());
				} else if (e.keyCode == SWT.DEL) {
					handleDel();
				}
			}
		});

		this.customTreePainter = new CustomTreePainter(this.fTree,
				this.browserConfiguration.getAppearanceConfiguration());
		// create a tooltip to show facet names
		FacetTooltip.create(this.fTree, this.customTreePainter);

		this.treeViewer = new TreeViewer(this.fTree);
		// speeds up all operations on a big model
		this.treeViewer.setUseHashlookup(true);

		hookViewerToSelection(this.treeViewer);

		this.fContentProvider = new BrowserContentProvider(this);
		this.treeViewer.setContentProvider(this.fContentProvider);
		this.fLabelProvider = new BrowserLabelProvider(this);
		this.treeViewer.setLabelProvider(this.fLabelProvider);

		registerShowPropertyViewOnDblClick(this.fTree);
	}

	/**
	 * The user pressed the "Enter" key : if selected element is a model
	 * element, then browse to it. If it is an attribute, then open properties
	 * view.
	 */
	protected void handleEnter() {
		final ISelection selection = getEditorSelection();
		if (selection instanceof ITreeSelection) {
			final ITreeSelection treeSelection = (ITreeSelection) selection;
			final Object selectedElement = treeSelection.getFirstElement();
			if (selectedElement instanceof ModelElementItem) {
				browse();
			} else if (selectedElement instanceof AttributeItem
					|| selectedElement instanceof LinkItem) {
				openPropertiesView();
			} else if (selectedElement instanceof QueryItem) {
				QueryItem queryItem = (QueryItem) selectedElement;
				SelectedQuery query = queryItem.getQuery();
				query.executeQuery();
			}
		}
	}

	/** The user pressed the "Delete" key */
	protected void handleDel() {
		final ISelection selection = getEditorSelection();
		if (selection instanceof ITreeSelection) {
			final ITreeSelection treeSelection = (ITreeSelection) selection;
			Iterator<?> iterator = treeSelection.iterator();
			while (iterator.hasNext()) {
				Object selectedElement = iterator.next();
				if (selectedElement instanceof QueryItem) {
					QueryItem queryItem = (QueryItem) selectedElement;
					this.browserConfiguration.getSelectedQueriesManager().remove(
							queryItem.getQuery());
				}
			}
		}
	}

	/**
	 * Set the initial font using saved user preferences, and add a listener to
	 * be notified of changes in the preferences
	 */
	private void setupInitialTreeFont() {
		setupPreferredFont();

		this.fontChangeListener = new IPropertyChangeListener() {
			public void propertyChange(final PropertyChangeEvent event) {
				if (event.getProperty().equals(JFaceResources.DIALOG_FONT)) {
					setupPreferredFont();
				}
			}
		};
		JFaceResources.getFontRegistry().addListener(this.fontChangeListener);
	}

	/** Set the user preferred font on the editor */
	private void setupPreferredFont() {
		FontDescriptor descriptor = FontDescriptor.createFrom(JFaceResources.getDialogFont());
		descriptor = descriptor.increaseHeight(this.browserConfiguration
				.getAppearanceConfiguration().getFontSizeDelta());
		final Font customFont = descriptor.createFont(Display.getDefault());
		descriptor = descriptor.setStyle(SWT.ITALIC);
		final Font customItalicFont = descriptor.createFont(Display.getDefault());
		this.browserConfiguration.getAppearanceConfiguration().setCustomFont(customFont);
		this.browserConfiguration.getAppearanceConfiguration()
				.setCustomItalicFont(customItalicFont);
		this.fTree.setFont(customFont);
		this.treeViewer.refresh();
		this.metaclassViewer.setFont(customFont);
		this.metaclassViewer.refresh();
	}

	protected Composite createTreeToolBar(final Composite parent) {
		final Composite treeToolBarComposite = new Composite(parent, SWT.WRAP);
		this.instancesToolBar = TreeToolBar.create(treeToolBarComposite, this);
		return treeToolBarComposite;
	}

	/**
	 * Register a listener to show the property view or execute a query when the
	 * tree is double-clicked
	 */
	private void registerShowPropertyViewOnDblClick(final Tree tree) {
		tree.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseDoubleClick(final MouseEvent event) {
				boolean handled = false;
				if (event.button == 1) {
					TreeItem[] selection = tree.getSelection();
					for (TreeItem treeItem : selection) {
						Object element = treeItem.getData();
						if (element instanceof QueryItem) {
							QueryItem queryItem = (QueryItem) element;
							SelectedQuery query = queryItem.getQuery();
							query.executeQuery();
							handled = true;
						}

						// If the user has activated the code synchronization
						if (EcoreBrowser.this.browserConfiguration.getAppearanceConfiguration()
								.isSynchronizeSourceCode()) {
							EObject eObject = (EObject) Platform.getAdapterManager().getAdapter(
									element, EObject.class);

							IStatusLineManager statusLineManager = getActionBars()
									.getStatusLineManager();

							if (eObject != null) {
								// Look for an extension declaring the
								// doubleClickListener extension point
								IExtensionRegistry registry = Platform.getExtensionRegistry();
								IExtensionPoint extPointDblClick = registry
										.getExtensionPoint("org.eclipse.modisco.infra.browser.doubleClickListener"); //$NON-NLS-1$

								if (extPointDblClick != null) {
									for (IExtension ext : extPointDblClick.getExtensions()) {
										for (IConfigurationElement configElt : ext
												.getConfigurationElements()) {
											String classAttribute = configElt.getAttribute("class"); //$NON-NLS-1$
											if (classAttribute != null) {
												try {
													DoubleClickListener listener = (DoubleClickListener) configElt
															.createExecutableExtension("class"); //$NON-NLS-1$
													// Synchronize this eObject
													// with its source code
													listener.synchronizeEObject(eObject,
															statusLineManager);
												} catch (CoreException e) {
													MoDiscoLogger.logError(e,
															MoDiscoBrowserPlugin.getPlugin());
												} finally {
													handled = true;
												}
											}
										}
									}
								} else {
									if (statusLineManager != null) {
										statusLineManager
												.setErrorMessage(Messages.EcoreBrowser_noSynchronisationExtensionFound);
									} else {
										MoDiscoLogger
												.logWarning(
														Messages.EcoreBrowser_noSynchronisationExtensionFound,
														MoDiscoBrowserPlugin.getPlugin());
									}

								}
							}
						}

					}
					if (!handled) {
						openPropertiesView();
					}
				}
			}
		});
	}

	public boolean isSynchronizeSourceCode() {
		return this.browserConfiguration.getAppearanceConfiguration().isSynchronizeSourceCode();
	}

	public void setSynchronizeSourceCode(final boolean value) {
		this.browserConfiguration.getAppearanceConfiguration().setSynchronizeSourceCode(value);
		internalRefreshTree();
	}

	/**
	 * Create the search panel, containing a label and search field.
	 *
	 * @param parent
	 *            the parent composite, which must have a GridLayout
	 */
	protected void createSearchPanel(final Composite parent) {
		final Composite searchPanel = new Composite(parent, SWT.NONE);
		searchPanel.setLayout(new GridLayout());

		searchPanel.setLayout(new FillLayout());
		final GridData searchPanelGridData = new GridData();
		searchPanelGridData.grabExcessHorizontalSpace = true;
		searchPanelGridData.horizontalAlignment = SWT.FILL;
		searchPanel.setLayoutData(searchPanelGridData);

		// Label searchLabel = new Label(searchPanel, SWT.NONE);
		// searchLabel.setText("&Search:");

		this.searchBox = new Text(searchPanel, SWT.SEARCH);
		this.searchBox.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(final KeyEvent e) {
				if (e.keyCode == SWT.CR || e.keyCode == SWT.KEYPAD_CR) {
					// ENTER: start a search
					search();
				} else if (e.keyCode == SWT.ESC) {
					// ESCAPE: restore the view after a search
					EcoreBrowser.this.searchBox.setText(""); //$NON-NLS-1$
					search();
				}
			}
		});

		this.searchBox.setMessage(Messages.EcoreBrowser_typeFilterText);
		this.searchBox.setData("org.eclipse.swtbot.widget.key", "EcoreBrowser.searchBox"); //$NON-NLS-1$//$NON-NLS-2$
		fixClipboardCommands(this.searchBox);
	}

	/**
	 * Called when the user initiates a search. Find the list of all the
	 * instances of the selected metaclass that have a name containing the
	 * search string (entered by the user in the search box), in a case
	 * insensitive way. Set this list as input of the tree viewer.
	 * <p>
	 * Do the search in a Job that can be canceled by the user.
	 * <p>
	 * If the search box is empty, then restore the previous tree viewer input.
	 */
	protected void search() {
		final String searchText = this.searchBox.getText().toLowerCase();

		if (searchText.trim().length() == 0) {
			if (this.savedInput != null && this.savedInput != this.treeViewer.getInput()) {
				this.treeViewer.setInput(this.savedInput);
			}
			return;
		}

		final List<EClass> selectedMetaclasses = findSelectedEClasses();
		if (selectedMetaclasses.isEmpty()) {
			return;
		}

		this.searchJob = new Job(Messages.EcoreBrowser_jobName_SearchInModelEditor) {
			@Override
			protected IStatus run(final IProgressMonitor monitor) {

				final ResourceSet resourceSet = EcoreBrowser.this.fResourceSet;
				final EList<Resource> resources = resourceSet.getResources();
				if (resources.size() < 1) {
					return Status.OK_STATUS;
				}

				// the search results : will become the input of the tree viewer
				final SearchResults searchResults = new SearchResults(
						EcoreBrowser.this.browserConfiguration);

				InstancesForMetaclasses instancesForMetaclasses = EcoreBrowser.this.browserConfiguration
						.getInstancesForMetaclasses();
				for (EClass eClass : selectedMetaclasses) {
					ArrayList<EObject> elements = instancesForMetaclasses.getInstancesForMetaclass(
							eClass).getElements();
					for (EObject eObject : elements) {
						final ModelElementItem modelElementItem = new ModelElementItemEx(eObject,
								null, EcoreBrowser.this.browserConfiguration);
						final String objectText = modelElementItem.getName().toLowerCase();
						if (objectText.contains(searchText)) {
							searchResults.add(eObject);
						}
						// if the user canceled the search
						if (monitor.isCanceled()) {
							return Status.CANCEL_STATUS;
						}
					}
				}

				// do only the minimum amount of work in the UI thread
				Display.getDefault().syncExec(new Runnable() {
					public void run() {
						// do not try to restore selection
						EcoreBrowser.this.treeViewer.setSelection(null);
						EcoreBrowser.this.treeViewer.setInput(searchResults);
					}
				});
				return Status.OK_STATUS;
			}
		};
		this.searchJob.setUser(true);
		this.searchJob.setPriority(Job.LONG);
		this.searchJob.schedule();
	}

	/**
	 * @return the {@link EClass}es corresponding to the metaclasses selected in
	 *         the metaclass list (empty list if none)
	 */
	private List<EClass> findSelectedEClasses() {

		final ArrayList<EClass> selectedMetaclasses = new ArrayList<EClass>();

		final ISelection selection = this.metaclassViewer.getSelection();
		if (selection instanceof IStructuredSelection) {
			final IStructuredSelection structuredSelection = (IStructuredSelection) selection;

			final Iterator<?> iterator = structuredSelection.iterator();
			while (iterator.hasNext()) {
				final Object element = iterator.next();
				if (element instanceof EClass) {
					final EClass eClass = (EClass) element;
					addMetaclassToSelection(eClass, selectedMetaclasses, this.browserConfiguration
							.getAppearanceConfiguration().isDisplayInstancesOfSubclasses());
				}
			}
		}
		return selectedMetaclasses;
	}

	/**
	 * Adds the given metaclass to the given selection.
	 *
	 * @param addSubclasses
	 *            also adds subclasses
	 */
	private void addMetaclassToSelection(final EClass eClass,
			final ArrayList<EClass> selectedMetaclasses, final boolean addSubclasses) {
		selectedMetaclasses.add(eClass);
		// add subclasses recursively
		if (addSubclasses) {
			InstancesForMetaclasses instancesForMetaclasses = this.browserConfiguration
					.getInstancesForMetaclasses();
			InstancesForMetaclass instancesForMetaclass = instancesForMetaclasses
					.getInstancesForMetaclass(eClass);
			if (instancesForMetaclass != null) {
				InstancesForMetaclass[] subclasses = instancesForMetaclass.getSubclasses();
				for (InstancesForMetaclass subclass : subclasses) {
					addMetaclassToSelection(subclass.getEClass(), selectedMetaclasses,
							addSubclasses);
				}
			} else {
				MoDiscoLogger.logError("Could not find subclasses of '" + eClass.getName() + "'", //$NON-NLS-1$ //$NON-NLS-2$
						MoDiscoBrowserPlugin.getPlugin());
			}

		}
	}

	/**
	 * Listen to selection changes in the metaclass list viewer, and update the
	 * tree viewer accordingly.
	 */
	private final class MetaclassListViewerSelectionChangedListener implements
			ISelectionChangedListener {

		/** Memorize the tree selection for each metaclass */
		private final HashMap<EClass, ITreeSelection> selections = new HashMap<EClass, ITreeSelection>();
		/** The metaclass that was selected before the selection changed */
		private EClass lastSelectedMetaclass = null;

		/**
		 * Get the selected entries corresponding to the given selection in the
		 * metaclass viewer (may be empty)
		 */
		private InstancesForMetaclass[] getEntriesForSelection(final ISelection selection) {
			final ArrayList<InstancesForMetaclass> instancesForMetaclasses = new ArrayList<InstancesForMetaclass>();

			if (selection instanceof IStructuredSelection) {
				final IStructuredSelection structuredSelection = (IStructuredSelection) selection;

				for (final Iterator<?> iterator = structuredSelection.iterator(); iterator
						.hasNext();) {
					final Object element = iterator.next();
					if (element instanceof InstancesForMetaclass) {
						final InstancesForMetaclass instancesForMetaclass = (InstancesForMetaclass) element;
						instancesForMetaclasses.add(instancesForMetaclass);
					}
				}
			}

			return instancesForMetaclasses
					.toArray(new InstancesForMetaclass[instancesForMetaclasses.size()]);
		}

		/**
		 * Updates the tree viewer when the selection changes in the metaclass
		 * viewer. Keeps track of the tree selection for each metaclass, and
		 * restores it when possible.
		 */
		public void selectionChanged(final SelectionChangedEvent event) {

			// save the selection
			if (this.lastSelectedMetaclass != null) {
				this.selections.put(this.lastSelectedMetaclass,
						(ITreeSelection) EcoreBrowser.this.treeViewer.getSelection());
			}

			final ISelection metaclassSelection = event.getSelection();
			final InstancesForMetaclass[] entries = getEntriesForSelection(metaclassSelection);

			ITreeSelection savedSelection = null;
			Object input = null;
			if (entries.length > 0) {
				savedSelection = this.selections.get(entries[0].getEClass());

				final EClass[] selectedMetaclasses = new EClass[entries.length];
				int i = 0;
				for (final InstancesForMetaclass entry : entries) {
					selectedMetaclasses[i++] = entry.getEClass();
				}

				input = new MetaclassList(EcoreBrowser.this.browserConfiguration,
						selectedMetaclasses);
				this.lastSelectedMetaclass = entries[0].getEClass();
			} else {
				this.lastSelectedMetaclass = null;
			}

			try {
				// speedup and avoid flickering
				EcoreBrowser.this.treeViewer.getTree().setRedraw(false);

				if (EcoreBrowser.this.searchBox != null) {
					EcoreBrowser.this.searchBox.setText(""); //$NON-NLS-1$
				}

				// do not restore selection twice
				EcoreBrowser.this.treeViewer.setSelection(null);

				// set the list of model elements as the input of the treeview
				EcoreBrowser.this.treeViewer.setInput(input);
				EcoreBrowser.this.savedInput = input;
				EcoreBrowser.this.treeViewer.setSelection(savedSelection, true);
			} finally {
				EcoreBrowser.this.treeViewer.getTree().setRedraw(true);
			}

			markNavigationLocation();
		}
	}

	public void setShowEmptyLinks(final boolean value) {
		this.browserConfiguration.getAppearanceConfiguration().setShowEmptyLinks(value);
		internalRefreshTree();
	}

	public boolean isShowEmptyLinks() {
		return this.browserConfiguration.getAppearanceConfiguration().isShowEmptyLinks();
	}

	public void setSortInstances(final boolean value) {
		this.browserConfiguration.getAppearanceConfiguration().setSortInstances(value);
		internalRefreshTree();
	}

	public boolean isSortInstances() {
		return this.browserConfiguration.getAppearanceConfiguration().isSortInstances();
	}

	public void setShowDerivedLinks(final boolean value) {
		this.browserConfiguration.getAppearanceConfiguration().setShowDerivedLinks(value);
		internalRefreshTree();
	}

	public boolean isShowDerivedLinks() {
		return this.browserConfiguration.getAppearanceConfiguration().isShowDerivedLinks();
	}

	public void setShowFullQualifiedNames(final boolean value) {
		this.browserConfiguration.getAppearanceConfiguration().setShowFullQualifiedNames(value);
		internalRefreshTree();
		this.metaclassViewer.refresh();
	}

	public boolean isShowFullQualifiedNames() {
		return this.browserConfiguration.getAppearanceConfiguration().isShowFullQualifiedNames();
	}

	public void setShowMultiplicity(final boolean value) {
		this.browserConfiguration.getAppearanceConfiguration().setShowMultiplicity(value);
		internalRefreshTree();
	}

	public boolean isShowMultiplicity() {
		return this.browserConfiguration.getAppearanceConfiguration().isShowMultiplicity();
	}

	public void setShowOppositeLinks(final boolean value) {
		this.browserConfiguration.getAppearanceConfiguration().setShowOppositeLinks(value);
		internalRefreshTree();
	}

	public boolean isShowOppositeLinks() {
		return this.browserConfiguration.getAppearanceConfiguration().isShowOppositeLinks();
	}

	public void setShowContainer(final boolean value) {
		this.browserConfiguration.getAppearanceConfiguration().setShowContainer(value);
		internalRefreshTree();
	}

	public boolean isShowContainer() {
		return this.browserConfiguration.getAppearanceConfiguration().isShowContainer();
	}

	public void setSortLinks(final boolean value) {
		this.browserConfiguration.getAppearanceConfiguration().setSortLinks(value);
		internalRefreshTree();
	}

	public boolean isSortLinks() {
		return this.browserConfiguration.getAppearanceConfiguration().isSortLinks();
	}

	public void setSortLinksByType(final boolean value) {
		this.browserConfiguration.getAppearanceConfiguration().setSortLinksByType(value);
		internalRefreshTree();
	}

	public boolean isSortLinksByType() {
		return this.browserConfiguration.getAppearanceConfiguration().isSortLinksByType();
	}

	public void setShowAttributes(final boolean value) {
		this.browserConfiguration.getAppearanceConfiguration().setShowAttributes(value);
		internalRefreshTree();
	}

	public boolean isShowAttributes() {
		return this.browserConfiguration.getAppearanceConfiguration().isShowAttributes();
	}

	public void setShowEmptyAttributes(final boolean value) {
		this.browserConfiguration.getAppearanceConfiguration().setShowEmptyAttributes(value);
		internalRefreshTree();
	}

	public boolean isShowEmptyAttributes() {
		return this.browserConfiguration.getAppearanceConfiguration().isShowEmptyAttributes();
	}

	public void setFontSizeDelta(final int value) {
		this.browserConfiguration.getAppearanceConfiguration().setFontSizeDelta(value);
		setupPreferredFont();
	}

	public int getFontSizeDelta() {
		return this.browserConfiguration.getAppearanceConfiguration().getFontSizeDelta();
	}

	public void setShowOrdering(final boolean value) {
		this.browserConfiguration.getAppearanceConfiguration().setShowOrdering(value);
		internalRefreshTree();
	}

	public boolean isShowOrdering() {
		return this.browserConfiguration.getAppearanceConfiguration().isShowOrdering();
	}

	public void setShowTypeOfLinks(final boolean value) {
		this.browserConfiguration.getAppearanceConfiguration().setShowTypeOfLinks(value);
		internalRefreshTree();
	}

	public boolean isShowTypeOfLinks() {
		return this.browserConfiguration.getAppearanceConfiguration().isShowTypeOfLinks();
	}

	public void setShowElementIDs(final boolean value) {
		this.browserConfiguration.getAppearanceConfiguration().setShowElementIDs(value);
		internalRefreshTree();
	}

	public boolean isShowElementIDs() {
		return this.browserConfiguration.getAppearanceConfiguration().isShowElementIDs();
	}

	public void setShowURI(final boolean value) {
		this.browserConfiguration.getAppearanceConfiguration().setShowURI(value);
		internalRefreshTree();
	}

	public boolean isShowURI() {
		return this.browserConfiguration.getAppearanceConfiguration().isShowURI();
	}

	public void showOnlyInstancesPanel() {
		this.sashForm.setSashWidth(0);
		this.sashForm.setWeights(new int[] { 0, 1 });
	}

	public void showOnlyTypesPanel() {
		this.sashForm.setSashWidth(0);
		this.sashForm.setWeights(new int[] { 1, 0 });
	}

	public void showBothPanels() {
		this.sashForm.setSashWidth(EcoreBrowser.SASH_WIDTH);
		this.sashForm.setWeights(new int[] { EcoreBrowser.LEFT_PANE_SASH_WEIGHT,
				EcoreBrowser.RIGHT_PANE_SASH_WEIGHT });
	}

	/** This is how the framework determines which interfaces we implement. */
	@SuppressWarnings("unchecked")
	@Override
	public Object getAdapter(final Class key) {
		if (key.equals(IPropertySheetPage.class)) {
			// Store the propertySheetPage to be able to call dispose() on it.
			if (this.propertySheetPage == null) {
				this.propertySheetPage = getPropertySheetPage();
			}
			return getPropertySheetPage();
		}
		return super.getAdapter(key);
	}

	/** This accesses a cached version of the property sheet page. */
	public IPropertySheetPage getPropertySheetPage() {
		if (this.propertySheetPage == null) {
			this.propertySheetPage = new ExtendedPropertySheetPage(this.editingDomain) {
				@Override
				public void setSelectionToViewer(final List<?> selection) {
					EcoreBrowser.this.setSelectionToViewer(selection);
					EcoreBrowser.this.setFocus();
				}

				@Override
				public void setActionBars(final IActionBars actionBars) {
					super.setActionBars(actionBars);
					getActionBarContributor().shareGlobalActions(this, actionBars);
				}

				@Override
				public void selectionChanged(final IWorkbenchPart part, final ISelection selection0) {
					ISelection selection = EcoreBrowser.this.getEditorSelection();

					boolean selectionNotified = false;
					if (selection instanceof IStructuredSelection) {
						if (((IStructuredSelection) selection).toArray().length == 1) {
							Object objSelected = ((IStructuredSelection) selection)
									.getFirstElement();
							if (objSelected instanceof ModelElementItem) {
								ModelElementItem modelElementItem = (ModelElementItem) objSelected;
								super.selectionChanged(part, new StructuredSelection(
										modelElementItem.getEObject()));
								selectionNotified = true;
							} else if (objSelected instanceof AttributeItem) {
								super.selectionChanged(part, new StructuredSelection(
										((AttributeItem) objSelected).getAttribute()));
								selectionNotified = true;
							} else if (objSelected instanceof LinkItem) {
								super.selectionChanged(part, new StructuredSelection(
										((LinkItem) objSelected).getReference()));
								selectionNotified = true;
							}
						}
					}
					if (!selectionNotified) {
						super.selectionChanged(part, StructuredSelection.EMPTY);
					}
				}
			};
			if (this.propertySheetPage instanceof PropertySheetPage) {
				((PropertySheetPage) this.propertySheetPage)
						.setPropertySourceProvider(new AdapterFactoryContentProvider(
								this.adapterFactoryWithRegistry) {
							@Override
							protected IPropertySource createPropertySource(final Object object,
									final IItemPropertySource itemPropertySource) {
								return new PropertySource(object, itemPropertySource) {
									@Override
									protected IPropertyDescriptor createPropertyDescriptor(
											final IItemPropertyDescriptor itemPropertyDescriptor) {
										return new PropertyDescriptor(this.object,
												itemPropertyDescriptor);
									}
								};
							}
						});
			}
		}
		return this.propertySheetPage;
	}

	@Override
	public boolean isDirty() {
		if (isReadOnly()) {
			return false;
		}
		return ((BasicCommandStack) this.editingDomain.getCommandStack()).isSaveNeeded();
	}

	/**
	 * This is for implementing {@link org.eclipse.ui.IEditorPart} : saves the
	 * model file.
	 */
	@Override
	public void doSave(final IProgressMonitor progressMonitor) {
		if (isReadOnly()) {
			return;
		}

		// Save only resources that have actually changed.
		final Map<Object, Object> saveOptions = new HashMap<Object, Object>();
		saveOptions.put(Resource.OPTION_SAVE_ONLY_IF_CHANGED,
				Resource.OPTION_SAVE_ONLY_IF_CHANGED_MEMORY_BUFFER);

		// Do the work within an operation because this is a long running
		// activity that modifies the workbench.
		WorkspaceModifyOperation operation = new WorkspaceModifyOperation() {
			// This is the method that gets invoked when the operation runs.
			@Override
			public void execute(final IProgressMonitor monitor) {
				// Save the resources to the file system.
				boolean first = true;
				for (Resource resource : EcoreBrowser.this.editingDomain.getResourceSet()
						.getResources()) {
					// see Bug 311005 - UnknownServiceException when trying to
					// save a UML model
					synchronized (resource) {
						URI uri = resource.getURI();
						if ((first || !resource.getContents().isEmpty() || isPersisted(resource))
								&& !EcoreBrowser.this.editingDomain.isReadOnly(resource)
								&& uri != null && (uri.isPlatformResource() || uri.isFile())) {
							try {
								long timeStamp = resource.getTimeStamp();
								resource.save(saveOptions);
								if (resource.getTimeStamp() != timeStamp) {
									EcoreBrowser.this.savedResources.add(resource);
								}
							} catch (final Exception e) {
								MoDiscoLogger.logError(e, MoDiscoBrowserPlugin.getPlugin());
								DialogUtils.openErrorDialog(getSite().getShell(), e,
										Messages.EcoreBrowser_errorSavingResource);
								EcoreBrowser.this.resourceToDiagnosticMap.put(resource,
										analyzeResourceProblems(resource, e));
							}
							first = false;
						}
					}
				}
			}
		};

		this.updateProblemIndication = false;
		try {
			// This runs the options, and shows progress.
			new ProgressMonitorDialog(getSite().getShell()).run(true, false, operation);

			// Refresh the necessary state.
			((BasicCommandStack) this.editingDomain.getCommandStack()).saveIsDone();
			firePropertyChange(IEditorPart.PROP_DIRTY);
		} catch (Exception exception) {
			// Something went wrong that shouldn't.
			MoDiscoBrowserPlugin.getPlugin().log(exception);
		}
		this.updateProblemIndication = true;
		updateProblemIndication();
	}

	@Override
	public void doSaveAs() {
		SaveAsDialog saveAsDialog = new SaveAsDialog(getSite().getShell());
		saveAsDialog.open();
		IPath path = saveAsDialog.getResult();
		if (path != null) {
			IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
			if (file != null) {
				doSaveAs(URI.createPlatformResourceURI(file.getFullPath().toString(), true),
						new FileEditorInput(file));
			}
		}
	}

	protected void doSaveAs(final URI uri, final IEditorInput editorInput) {
		this.editingDomain.getResourceSet().getResources().get(0).setURI(uri);
		setInputWithNotify(editorInput);
		setPartName(editorInput.getName());
		IProgressMonitor progressMonitor;
		IStatusLineManager statusLineManager = getActionBars().getStatusLineManager();
		if (statusLineManager != null) {
			progressMonitor = statusLineManager.getProgressMonitor();
		} else {
			progressMonitor = new NullProgressMonitor();
		}
		doSave(progressMonitor);
	}

	@Override
	public boolean isSaveAsAllowed() {
		return !isReadOnly();
	}

	/**
	 * This returns whether something has been persisted to the URI of the
	 * specified resource. The implementation uses the URI converter from the
	 * editor's resource set to try to open an input stream.
	 */
	protected boolean isPersisted(final Resource resource) {
		boolean result = false;
		try {
			InputStream stream = this.editingDomain.getResourceSet().getURIConverter()
					.createInputStream(resource.getURI());
			if (stream != null) {
				result = true;
				stream.close();
			}
		} catch (IOException e) {
			result = false;
		}
		return result;
	}

	/**
	 * This is called during startup to initialize the editor with its site and
	 * input.
	 */
	@Override
	public void init(final IEditorSite site, final IEditorInput editorInput) {
		// TODO: check input is of expected type
		try {
			setSite(site);
			setInputWithNotify(editorInput);
			setPartName(editorInput.getName());
			site.setSelectionProvider(this);
			site.getPage().addPartListener(this.partListener);
			ResourcesPlugin.getWorkspace().addResourceChangeListener(this.resourceChangeListener,
					IResourceChangeEvent.POST_CHANGE);
		} catch (final Exception e) {
			MoDiscoLogger.logError(e, MoDiscoBrowserPlugin.getPlugin());
		}
	}

	/** Focus the tree viewer when the editor is focused */
	@Override
	public void setFocus() {
		// Done in setFocus because we don't want the job to start until the
		// editor is visible. Otherwise it still hangs the UI.
		if (this.openModelJob == null) {
			this.openModelJob = new Job(Messages.EcoreBrowser_jobOpeningModelInMoDiscoBrowser) {
				@Override
				protected IStatus run(final IProgressMonitor monitor) {
					boolean result = backgroundOpenModel(monitor);
					EcoreBrowser.this.loaded = result;
					if (result) {
						return Status.OK_STATUS;
					}
					return Status.CANCEL_STATUS;
				}
			};
			this.openModelJob.setPriority(Job.LONG);
			getProgressService().schedule(this.openModelJob);
		} else if (this.treeViewer != null) {
			this.treeViewer.getTree().setFocus();
		}
	}

	/** This implements {@link org.eclipse.jface.viewers.ISelectionProvider}. */
	public void addSelectionChangedListener(final ISelectionChangedListener listener) {
		this.selectionChangedListeners.add(listener);
	}

	/** This implements {@link org.eclipse.jface.viewers.ISelectionProvider}. */
	public void removeSelectionChangedListener(final ISelectionChangedListener listener) {
		this.selectionChangedListeners.remove(listener);
	}

	/**
	 * Returns the "unwrapped" selection of the editor, with Ecore elements
	 * instead of the proxies used internally
	 */
	public ISelection getSelection() {
		return BrowserUtils.unwrapSelection(this.editorSelection);
	}

	/** @return the "real" selection, with proxy objects (ModelElementItem, etc.) */
	public ISelection getEditorSelection() {
		return this.editorSelection;
	}

	/**
	 * This implements {@link org.eclipse.jface.viewers.ISelectionProvider} to
	 * set this editor's overall selection. Calling this result will notify the
	 * listeners.
	 */
	public void setSelection(final ISelection selection) {
		this.editorSelection = selection;

		for (final ISelectionChangedListener listener : this.selectionChangedListeners) {
			// depending on the listener type, unwrap the selection
			if (listener instanceof IBrowserSelectionChangedListener) {
				// expose the proxy objects
				listener.selectionChanged(new SelectionChangedEvent(this, selection));
			} else {
				// expose the underlying Ecore elements
				listener.selectionChanged(new SelectionChangedEvent(this, BrowserUtils
						.unwrapSelection(selection)));
			}
		}
		setStatusLineMessage(selection);
	}

	/** Connect the given viewer to the editor's selection */
	private void hookViewerToSelection(final Viewer viewer) {
		if (viewer == null) {
			return;
		}

		if (this.selectionChangedListener == null) {
			// Create the listener on demand
			this.selectionChangedListener = new ISelectionChangedListener() {
				// This just notifies those things that are affected by the
				// selection
				public void selectionChanged(final SelectionChangedEvent selectionChangedEvent) {
					setSelection(selectionChangedEvent.getSelection());
				}
			};
		}

		viewer.addSelectionChangedListener(this.selectionChangedListener);

		// Set the editor's selection based on the viewer's selection
		setSelection(viewer.getSelection());
	}

	/** Set the status line message depending on the given selection */
	public void setStatusLineMessage(final ISelection selection) {
		// TODO: maybe display more useful information?
		final IStatusLineManager statusLineManager = getActionBars().getStatusLineManager();

		if (statusLineManager != null) {
			if (selection instanceof IStructuredSelection) {
				final Collection<?> collection = ((IStructuredSelection) selection).toList();
				switch (collection.size()) {
				case 0:
					statusLineManager.setMessage(Messages.EcoreBrowser_noObjectSelected);
					break;
				case 1:
					final Object object = collection.iterator().next();
					if (object instanceof ITreeElement) {
						final ITreeElement treeElement = (ITreeElement) object;
						statusLineManager.setMessage(NLS.bind(
								Messages.EcoreBrowser_singleObjectSelected, treeElement.getText()));
					}
					break;
				default:
					statusLineManager.setMessage(NLS.bind(
							Messages.EcoreBrowser_multiObjectSelected,
							Integer.toString(collection.size())));
					break;
				}
			} else {
				statusLineManager.setMessage(""); //$NON-NLS-1$
			}
		}
	}

	/**
	 * This implements {@link org.eclipse.jface.action.IMenuListener} to help
	 * fill the context menus with contributions from the Edit menu.
	 */
	public void menuAboutToShow(final IMenuManager menuManager) {
		((IMenuListener) getEditorSite().getActionBarContributor()).menuAboutToShow(menuManager);
	}

	public BrowserActionBarContributor getActionBarContributor() {
		return (BrowserActionBarContributor) getEditorSite().getActionBarContributor();
	}

	public IActionBars getActionBars() {
		return getActionBarContributor().getActionBars();
	}

	/** Clean up */
	@Override
	public void dispose() {
		stopOpeningModel();

		this.disposing = true;
		ResourcesPlugin.getWorkspace().removeResourceChangeListener(this.resourceChangeListener);
		getSite().getPage().removePartListener(this.partListener);

		this.adapterFactoryWithRegistry.dispose();
		this.sashForm.dispose();

		if (getActionBarContributor().getActiveEditor() == this) {
			getActionBarContributor().setActiveEditor(null);
		}

		if (this.propertySheetPage != null) {
			this.propertySheetPage.dispose();
		}

		if (this.treeViewer != null && this.selectionChangedListener != null) {
			this.treeViewer.removeSelectionChangedListener(this.selectionChangedListener);
			this.selectionChangedListener = null;
		}

		// dispose fonts
		this.browserConfiguration.getAppearanceConfiguration().setCustomFont(null);
		this.browserConfiguration.getAppearanceConfiguration().setCustomItalicFont(null);

		// avoid leaking editor
		this.browserConfiguration.dispose();

		JFaceResources.getFontRegistry().removeListener(this.fontChangeListener);

		this.customTreePainter.dispose();
		// dispose the customization engine, which removes listeners too
		this.browserConfiguration.getAppearanceConfiguration().getCustomizationEngine().dispose();
		this.fCustomizationEngineChangeListener = null;

		FacetSetCatalog.getSingleton().removeChangeListener(this.fFacetsChangeListener);

		this.fFormToolkit.dispose();

		// avoid memory leak for EMF registry resources since a new
		// adapter is created each time the same resource is opened
		// in a different editor
		Set<Resource> browsedResources = this.browserConfiguration.getBrowsedResources();
		if (browsedResources != null) {
			for (Resource resource : browsedResources) {
				ListIterator<Adapter> listIterator = resource.eAdapters().listIterator();
				while (listIterator.hasNext()) {
					Adapter adapter = listIterator.next();
					if (adapter instanceof MetaclassInstancesAdapterWithFacet) {
						MetaclassInstancesAdapterWithFacet adapterWithFacet = (MetaclassInstancesAdapterWithFacet) adapter;
						if (adapterWithFacet.getFacetContext() == getBrowserConfiguration()
								.getAppearanceConfiguration().getFacetContext()) {
							listIterator.remove();
						}
					}
				}
			}
		}
		// let the FacetContext be GCed
		MetaclassInstancesAdapterFactoryWithFacet.getInstance().setFacetContext(null);

		// if (!isReadOnly()) {
		// // unload all resources
		// final EList<Resource> resources = this.fResourceSet.getResources();
		// final Job cleanupJob = new
		// Job(Messages.EcoreBrowser_jobName_UnloadResources) {
		// @Override
		// protected IStatus run(final IProgressMonitor monitor) {
		// for (final Resource resource : resources) {
		// resource.unload();
		// }
		// return Status.OK_STATUS;
		// }
		// };
		// cleanupJob.setPriority(Job.DECORATE);
		// cleanupJob.setSystem(true);
		// cleanupJob.schedule();
		// }

		super.dispose();
	}

	@SuppressWarnings("deprecation")
	private void stopOpeningModel() {
		if (this.openModelJob != null && this.openModelJob.getState() == Job.RUNNING) {
			this.openModelJob.cancel();
			Thread thread = this.openModelJob.getThread();
			if (thread != null) {
				thread.stop();
			}
		}
	}

	/** Open the selected element in the list of elements of the same metaclass */
	public void browse() {
		final ISelection selection = getEditorSelection();
		if (selection instanceof ITreeSelection) {
			final ITreeSelection treeSelection = (ITreeSelection) selection;
			final Object selectedElement = treeSelection.getFirstElement();
			if (selectedElement instanceof ModelElementItem) {
				final ModelElementItem modelElementItem = (ModelElementItem) selectedElement;
				browseTo(modelElementItem);
			}
		}
	}

	/** Open the given element in the list of elements of the same metaclass */
	public void browseTo(final ModelElementItem modelElementItem) {
		final EObject modelElement = modelElementItem.getEObject();
		browseTo(modelElement);
	}

	/** Open the given element in the list of elements of the same metaclass */
	public void browseTo(final EObject modelElement) {
		browseTo(modelElement, modelElement.eClass());
	}

	/**
	 * Open the given element in the list of elements of the given metaclass
	 * (which can be a Facet).
	 */
	public void browseTo(final EObject modelElement, final EClass eClass) {
		markNavigationLocation();
		// Select the metaclass in the metaclass list viewer
		this.metaclassViewer.selectMetaclass(eClass);

		TreePath treePath = findTreePathForElement(modelElement);
		if (treePath != null) {
			// deselect any previously selected elements
			this.treeViewer.setSelection(null);
			this.treeViewer.setSelection(new TreeSelection(treePath), true);
			if (this.treeViewer.getSelection().isEmpty()) {
				delayedBrowseTo(modelElement);
			} else {
				markNavigationLocation();
			}
		} else {
			delayedBrowseTo(modelElement);
		}
	}

	/**
	 * delayed because the browser doesn't always update synchronously
	 * (temporary "loading..." nodes)
	 */
	private void delayedBrowseTo(final EObject modelElement) {
		Listener refreshListener = new Listener() {
			public void handleEvent(final Event event) {
				removeRefreshListener(this);
				Display.getDefault().asyncExec(new Runnable() {
					public void run() {
						TreePath treePath2 = findTreePathForElement(modelElement);
						EcoreBrowser.this.treeViewer.setSelection(null);
						EcoreBrowser.this.treeViewer.setSelection(new TreeSelection(treePath2),
								true);
						markNavigationLocation();
					}
				});
			}
		};
		addRefreshListener(refreshListener);
	}

	public boolean browseToByURI(final String uriFragment) {
		EObject eObject = EMFUtil.findElementByURI(uriFragment, this.fResourceSet);
		if (eObject != null) {
			browseTo(eObject);
			return true;
		}
		return false;
	}

	/**
	 * Finds the path of the given element in the tree viewer. The element is
	 * looked for at the root and under BigListItemProviders in the case the
	 * elements are split.
	 *
	 * @return the path or <code>null</code> if the element was not found
	 */
	private TreePath findTreePathForElement(final EObject eObject) {
		final Object input = this.treeViewer.getInput();
		if (input instanceof MetaclassList) {
			final MetaclassList metaclassListItemProvider = (MetaclassList) input;
			final Collection<?> elements = metaclassListItemProvider.getElements();
			for (final Object element : elements) {
				// if the elements are split
				if (element instanceof BigListItem) {
					final BigListItem bigListItemProvider = (BigListItem) element;
					final Collection<?> subElements = bigListItemProvider.getChildren();
					for (final Object subElement : subElements) {
						if (subElement instanceof ModelElementItem) {
							final ModelElementItem other = (ModelElementItem) subElement;
							if (other.getEObject().equals(eObject)) {
								return new TreePath(new Object[] { subElement });
							}
						}
					}
				}

				if (element instanceof ModelElementItem) {
					final ModelElementItem other = (ModelElementItem) element;
					if (other.getEObject().equals(eObject)) {
						return new TreePath(new Object[] { element });
					}
				}
			}
		}
		return null;
	}

	/** Implements {@link INavigationLocationProvider} */
	public INavigationLocation createEmptyNavigationLocation() {
		return new BrowserNavigationLocation(this);
	}

	/**
	 * Implements {@link INavigationLocationProvider}. Create a location that
	 * can be navigated back to, using the "back" button
	 */
	public INavigationLocation createNavigationLocation() {
		// navigation to the first element of the selection
		final EClass firstSelectedMetaclass = this.metaclassViewer.getFirstSelectedMetaclass();
		return new BrowserNavigationLocation(this, firstSelectedMetaclass,
				(ITreeSelection) this.treeViewer.getSelection());
	}

	/** Mark a location that can be navigated back to, using the "back" button */
	protected void markNavigationLocation() {
		getSite().getPage().getNavigationHistory().markLocation(this);
	}

	/**
	 * Restore a location (used for implementing history).
	 *
	 * @param eClass
	 *            the metaclass viewer's selection
	 * @param selection
	 *            the tree viewer's selection
	 */
	public void restoreLocation(final EClass eClass, final ITreeSelection selection) {
		this.metaclassViewer.selectMetaclass(eClass);
		this.treeViewer.setSelection(selection);
	}

	private final List<Listener> refreshListeners = new ArrayList<Listener>();

	public void addRefreshListener(final Listener refreshListener) {
		if (!this.refreshListeners.contains(refreshListener)) {
			this.refreshListeners.add(refreshListener);
		}
	}

	public void removeRefreshListener(final Listener refreshListener) {
		this.refreshListeners.remove(refreshListener);
	}

	public void notifyRefresh() {
		for (Listener listener : new ArrayList<Listener>(this.refreshListeners)) {
			listener.handleEvent(new Event());
		}
	}

	/**
	 * Refresh the editor
	 *
	 * @param metaclassViewerToo
	 *            whether the metaclass view must be refreshed too, or only the
	 *            tree viewer
	 */
	public void refreshDelayed(final boolean metaclassViewerToo) {
		if (this.disposing) {
			return;
		}
		if (this.refreshJob == null) {
			this.refreshJob = new Job(Messages.EcoreBrowser_refreshingModelViewers) {
				@Override
				protected IStatus run(final IProgressMonitor monitor) {
					Display.getDefault().syncExec(new Runnable() {
						public void run() {
							internalRefreshTree();
							if (metaclassViewerToo) {
								getMetaclassViewer().refresh();
							}
							notifyRefresh();
						}
					});
					return Status.OK_STATUS;
				}
			};
		} else {
			/*
			 * If refreshTreeDelayed is called again before the job delay
			 * passed, then cancel the job and re-schedule a new one.
			 */
			this.refreshJob.cancel();
		}
		// we don't want to keep refreshing while computing children,
		// because it slows down the computation
		if (this.fContentProvider.isComputing()) {
			final int delay = 100;
			this.refreshJob.setPriority(Job.DECORATE);
			this.refreshJob.schedule(delay);
		} else {
			this.refreshJob.setPriority(Job.INTERACTIVE);
			this.refreshJob.schedule();
		}
	}

	public void clearInstancesCache() {
		AppearanceConfiguration appearanceConfiguration = this.browserConfiguration
				.getAppearanceConfiguration();
		MetaclassInstancesAdapterFactoryWithFacet.getInstance().setFacetContext(
				appearanceConfiguration.getFacetContext());
		Set<Resource> browsedResources = this.browserConfiguration.getBrowsedResources();
		if (browsedResources != null) {
			for (Resource resource : browsedResources) {
				MetaclassInstances instances = (MetaclassInstances) MetaclassInstancesAdapterFactoryWithFacet
						.getInstance().adapt(resource, MetaclassInstances.class);
				instances.clearCache();
			}
		}
	}

	private void internalRefreshTree() {
		if (!this.treeViewer.getTree().isDisposed()) {
			try {
				this.treeViewer.getTree().setRedraw(false);
				this.treeViewer.refresh();
			} finally {
				this.treeViewer.getTree().setRedraw(true);
			}
		}
	}

	public BrowserConfiguration getBrowserConfiguration() {
		return this.browserConfiguration;
	}

	private void openPropertiesView() {
		try {
			getEditorSite().getPage().showView(EcoreBrowser.PROPERTY_VIEW_ID);
		} catch (final PartInitException e) {
			MoDiscoBrowserPlugin.logException(e);
		}
	}

	public ResourceSet getResourceSet() {
		return this.fResourceSet;
		// return getEditingDomain().getResourceSet();
	}

	public void loadCustomizations(final Collection<MetamodelView> customizationsToLoad) {
		final CustomizationEngine customizationEngine = this.browserConfiguration
				.getAppearanceConfiguration().getCustomizationEngine();

		if (this.fCustomizationEngineChangeListener == null) {
			this.fCustomizationEngineChangeListener = new ChangeListener() {
				public void changed() {
					Display.getDefault().asyncExec(new Runnable() {
						public void run() {
							refreshDelayed(true);
						}
					});
				}
			};
			customizationEngine.addChangeListener(this.fCustomizationEngineChangeListener);
		}

		customizationEngine.clear();
		for (final MetamodelView customizationToLoad : customizationsToLoad) {
			customizationEngine.registerCustomization(customizationToLoad);
		}
		customizationEngine.loadCustomizations();
	}

	private void loadDefaultCustomizations() {
		Collection<MetamodelView> customizations = CustomizationsCatalog.filterForMetamodel(
				CustomizationsCatalog.getInstance().getRegistryDefaultCustomizations(),
				getReferencedEPackages());
		if (customizations.size() > 0) {
			loadCustomizations(customizations);
		}
	}

	/** used by unit tests */
	protected TreeToolBar getInstancesToolBar() {
		return this.instancesToolBar;
	}

	protected void reloadOnFacetChange() {
		if (this.fFacetsChangeListener == null) {
			this.fFacetsChangeListener = new ModiscoCatalogChangeListener() {
				private void changed() {
					if (!EcoreBrowser.this.loaded) {
						return;
					}
					Job reloadFacetsJob = new Job(Messages.EcoreBrowser_ReloadingFacets) {
						@Override
						protected IStatus run(final IProgressMonitor monitor) {
							// reloading Facets by name, since the elements are
							// different after a FacetSet model reload
							List<String> facetsToReload = new ArrayList<String>();
							Collection<Facet> loadedFacets = getBrowserConfiguration()
									.getAppearanceConfiguration().getLoadedFacets();
							for (Facet facet : loadedFacets) {
								FacetSet facetSet = facet.getFacetSet();
								facetsToReload.add(facetSet.getName() + "#" + facet.getName()); //$NON-NLS-1$
							}
							getBrowserConfiguration().getAppearanceConfiguration().clearFacets();

							Collection<FacetSet> allFacetSets = FacetSetCatalog.getSingleton()
									.getAllFacetSets();

							for (FacetSet facetSet : allFacetSets) {
								EList<Facet> facets = facetSet.getFacets();
								for (Facet facet : facets) {
									for (String fullname : facetsToReload) {
										if (fullname.equals(facetSet.getName() + "#" //$NON-NLS-1$
												+ facet.getName())) {
											getBrowserConfiguration().getAppearanceConfiguration()
													.loadFacet(facet);
											break;
										}
									}
								}
							}
							// for modified facets
							getBrowserConfiguration().getInstancesForMetaclasses()
									.buildDerivationTree();
							return Status.OK_STATUS;
						}
					};
					reloadFacetsJob.setPriority(Job.DECORATE);
					reloadFacetsJob.schedule();
				}

				public void removed(final IFile file) {
					changed();
				}

				public void changed(final EObject eObject, final IFile file) {
					changed();
				}

				public void added(final EObject eObject, final IFile file) {
					changed();
				}
			};
			FacetSetCatalog.getSingleton().addChangeListener(this.fFacetsChangeListener);
		}
	}

	public void modelChanged() {
		getBrowserConfiguration().getAppearanceConfiguration().touch();
		refreshDelayed(true);
	}

	/**
	 * Handles activation of the editor or it's associated views.
	 */
	protected void handleActivate() {
		// Recompute the read only state.
		if (this.editingDomain.getResourceToReadOnlyMap() != null) {
			this.editingDomain.getResourceToReadOnlyMap().clear();

			// Refresh any actions that may become enabled or disabled.
			setSelection(getEditorSelection());
		}

		if (!this.removedResources.isEmpty()) {
			if (handleDirtyConflict()) {
				getSite().getPage().closeEditor(EcoreBrowser.this, false);
			} else {
				this.removedResources.clear();
				this.changedResources.clear();
				this.savedResources.clear();
			}
		} else if (!this.changedResources.isEmpty()) {
			this.changedResources.removeAll(this.savedResources);
			handleChangedResources();
			this.changedResources.clear();
			this.savedResources.clear();
		}
	}

	/**
	 * Shows a dialog that asks if conflicting changes should be discarded.
	 */
	protected boolean handleDirtyConflict() {
		return MessageDialog.openQuestion(getSite().getShell(), Messages.UI_FileConflict_label,
				Messages.WARN_FileConflict);
	}

	/**
	 * Handles what to do with changed resources on activation.
	 */
	protected void handleChangedResources() {
		if (!this.changedResources.isEmpty() && (!isDirty() || handleDirtyConflict())) {
			if (isDirty()) {
				this.changedResources.addAll(this.editingDomain.getResourceSet().getResources());
			}
			this.editingDomain.getCommandStack().flush();

			this.updateProblemIndication = false;
			for (Resource resource : this.changedResources) {
				if (resource.isLoaded()) {
					resource.unload();
					try {
						resource.load(Collections.EMPTY_MAP);
					} catch (IOException e) {
						final URI uri = resource.getURI();
						final String uristr = uri.toString();
						final String logMsg = String.format(
								"The MoDisco browser failed to reload the resource %s.", //$NON-NLS-1$
								uristr);
						Logger.logError(
								e, logMsg , MoDiscoBrowserPlugin.getPlugin());
						final String userMsg = String.format(
								"%s, cf. %s", //$NON-NLS-1$
								Messages.EcoreBrowser_errorLoadingResource,
								uristr);
						DialogUtils.openErrorDialog(getSite().getShell(), e,
								userMsg);
						if (!this.resourceToDiagnosticMap.containsKey(resource)) {
							this.resourceToDiagnosticMap.put(resource,
									analyzeResourceProblems(resource, e));
						}
					}
				}
			}

			if (AdapterFactoryEditingDomain.isStale(this.editorSelection)) {
				setSelection(StructuredSelection.EMPTY);
			}

			this.updateProblemIndication = true;
			updateProblemIndication();
		}
	}

	/**
	 * Updates the problems indication with the information described in the
	 * specified diagnostic.
	 */
	protected void updateProblemIndication() {
		if (this.updateProblemIndication) {
			BasicDiagnostic diagnostic = new BasicDiagnostic(Diagnostic.OK,
					MoDiscoBrowserPlugin.PLUGIN_ID, 0, null,
					new Object[] { this.editingDomain.getResourceSet() });
			int nWarnings = 0;
			int nErrors = 0;
			int nInfo = 0;

			for (Diagnostic childDiagnostic : this.resourceToDiagnosticMap.values()) {
				if (childDiagnostic.getSeverity() != Diagnostic.OK) {
					diagnostic.add(childDiagnostic);
					if (childDiagnostic.getSeverity() == Diagnostic.WARNING) {
						nWarnings++;
					} else if (childDiagnostic.getSeverity() == Diagnostic.ERROR) {
						nErrors++;
					} else if (childDiagnostic.getSeverity() == Diagnostic.INFO) {
						nInfo++;
					}
				}
			}

			StringBuilder builder = new StringBuilder();

			if (nErrors == 1) {
				builder.append(NLS.bind(Messages.EcoreBrowser_error, nErrors));
			} else if (nErrors > 1) {
				builder.append(NLS.bind(Messages.EcoreBrowser_errors, nErrors));
			}

			if (nWarnings == 1) {
				if (builder.length() > 0) {
					builder.append(Messages.EcoreBrowser_separator);
				}
				builder.append(NLS.bind(Messages.EcoreBrowser_warning, nWarnings));
			} else if (nWarnings > 1) {
				if (builder.length() > 0) {
					builder.append(Messages.EcoreBrowser_separator);
				}
				builder.append(NLS.bind(Messages.EcoreBrowser_warnings, nWarnings));
			}

			if (nInfo == 1) {
				if (builder.length() > 0) {
					builder.append(Messages.EcoreBrowser_separator);
				}
				builder.append(NLS.bind(Messages.EcoreBrowser_info, nInfo));
			} else if (nInfo > 1) {
				if (builder.length() > 0) {
					builder.append(Messages.EcoreBrowser_separator);
				}
				builder.append(NLS.bind(Messages.EcoreBrowser_infos, nInfo));
			}

			if (!this.errorsButton.isDisposed()) {
				if (builder.length() > 0) {
					this.errorsButton.setText(builder.toString());
					this.errorsButton.setVisible(true);
				} else {
					this.errorsButton.setVisible(false);
				}

				final GridData errorsButtonGridData = new GridData();
				if (this.errorsButton.isVisible()) {
					this.errorsButton.setSize(this.errorsButton.computeSize(SWT.DEFAULT,
							SWT.DEFAULT));
					errorsButtonGridData.exclude = false;
				} else {
					errorsButtonGridData.exclude = true;
				}
				this.errorsButton.setLayoutData(errorsButtonGridData);
				this.errorsButton.getParent().layout();
			}

			this.fDiagnostic = diagnostic;

			if (this.markerHelper.hasMarkers(this.editingDomain.getResourceSet())) {
				this.markerHelper.deleteMarkers(this.editingDomain.getResourceSet());
				if (diagnostic.getSeverity() != Diagnostic.OK) {
					try {
						this.markerHelper.createMarkers(diagnostic);
					} catch (CoreException exception) {
						MoDiscoBrowserPlugin.getPlugin().log(exception);
					}
				}
			}
		}
	}

	/**
	 * Returns a diagnostic describing the errors and warnings listed in the
	 * resource and the specified exception (if any).
	 */
	public Diagnostic analyzeResourceProblems(final Resource resource, final Exception exception) {
		if (!resource.getErrors().isEmpty() || !resource.getWarnings().isEmpty()) {
			Object errorData;
			if (exception == null) {
				errorData = resource;
			} else {
				errorData = exception;
			}
			BasicDiagnostic basicDiagnostic = new BasicDiagnostic(Diagnostic.ERROR,
					MoDiscoBrowserPlugin.PLUGIN_ID, 0, NLS.bind(Messages.UI_ErrorFile_message,
							resource.getURI()), new Object[] { errorData });
			basicDiagnostic.merge(EcoreUtil.computeDiagnostic(resource, true));
			return basicDiagnostic;
		} else if (exception != null) {
			return new BasicDiagnostic(Diagnostic.ERROR, MoDiscoBrowserPlugin.PLUGIN_ID, 0,
					NLS.bind(Messages.UI_ErrorFile_message, resource.getURI()),
					new Object[] { exception });
		} else {
			return Diagnostic.OK_INSTANCE;
		}
	}

	class BrowserAdapterFactory extends ComposedAdapterFactory implements IEditingDomainProvider {
		public BrowserAdapterFactory(final ComposedAdapterFactory.Descriptor.Registry registry) {
			super(registry);
		}

		public EditingDomain getEditingDomain() {
			return EcoreBrowser.this.getEditingDomain();
		}
	}

	/**
	 * This sets up the editing domain for the model editor
	 */
	protected void initializeEditingDomain() {
		if (this.fResourceSet == null) {
			initializeEditingDomain(new ResourceSetImpl());
		}
	}

	protected void initializeEditingDomain(final ResourceSet resourceSet) {
			// Create an adapter factory that yields item providers.
			this.adapterFactoryWithRegistry = new BrowserAdapterFactory(
					ComposedAdapterFactory.Descriptor.Registry.INSTANCE);
			this.adapterFactoryWithRegistry
					.addAdapterFactory(new ResourceItemProviderAdapterFactory());
			this.adapterFactoryWithRegistry
					.addAdapterFactory(new ReflectiveItemProviderAdapterFactory());
			final CommandStack commandStack = createCommandStack();
			// Create the editing domain with a special command stack.
			final BrowserEditingDomain newEditingDomain = new BrowserEditingDomain(
					this.adapterFactoryWithRegistry, commandStack, resourceSet, this);
			setEditingDomain(newEditingDomain);
	}

	private CommandStack createCommandStack() {
		// Create the command stack that will notify this editor as commands
		// are executed.
		CommandStack commandStack;
		if (isReadOnly()) {
			commandStack = new ReadOnlyCommandStack();
		} else {
			commandStack = new BasicCommandStack();
		}
		commandStack.addCommandStackListener(new CommandStackListener() {
			public void commandStackChanged(final EventObject event) {
				getParentComposite().getDisplay().asyncExec(new Runnable() {
					public void run() {
						firePropertyChange(IEditorPart.PROP_DIRTY);
						// Try to select the affected objects.
						final Command mostRecentCommand = ((CommandStack) event.getSource())
								.getMostRecentCommand();
						if (mostRecentCommand != null) {
							// asyncExec is to make it happen after the
							// refresh
							Display.getDefault().asyncExec(new Runnable() {
								public void run() {
									try {
										// avoid the view jumping around as
										// the selection changes
										// several times
										EcoreBrowser.this.treeViewer.getTree().setRedraw(false);
										selectAffectedElements(mostRecentCommand);
									} finally {
										EcoreBrowser.this.treeViewer.getTree().setRedraw(true);
									}
								}
							});
						}
						IPropertySheetPage page = EcoreBrowser.this.getPropertySheetPage();
						if (page != null && page.getControl() != null
								&& !page.getControl().isDisposed()) {
							if (page instanceof PropertySheetPage) {
								PropertySheetPage propertyPage = (PropertySheetPage) page;
								propertyPage.refresh();
							} else if (page instanceof TabbedPropertySheetPage) {
								TabbedPropertySheetPage tabbedPropertyPage = (TabbedPropertySheetPage) page;
								if (tabbedPropertyPage.getCurrentTab() != null) {
									tabbedPropertyPage.refresh();
								}
							}
						}
					}
				});
			}
		});
		return commandStack;
	}

	/** added for integration into Papyrus */
	protected void setEditingDomain(final AdapterFactoryEditingDomain editingDomain) {
		this.editingDomain = editingDomain;
	}

	/** This is here for the listener to be able to call it. */
	@Override
	protected void firePropertyChange(final int action) {
		super.firePropertyChange(action);
	}

	/**
	 * Implements {@link IGotoMarker}. Select the EObject corresponding to the
	 * given marker
	 */
	public void gotoMarker(final IMarker marker) {
		try {
			if (marker.getType().equals(EValidator.MARKER)) {
				String uriAttribute = marker.getAttribute(EValidator.URI_ATTRIBUTE, null);
				if (uriAttribute != null) {
					URI uri = URI.createURI(uriAttribute);
					EObject eObject = this.fResourceSet.getEObject(uri, true);
					if (eObject != null) {
						browseTo(eObject);
					}
				}
			}
		} catch (Exception e) {
			MoDiscoLogger.logError(e, MoDiscoBrowserPlugin.getPlugin());
		}
	}

	public Composite getParentComposite() {
		return this.parentComposite;
	}

	public EditingDomain getEditingDomain() {
		return this.editingDomain;
	}

	public Collection<Resource> getSavedResources() {
		return this.savedResources;
	}

	public Collection<Resource> getChangedResources() {
		return this.changedResources;
	}

	public Collection<Resource> getRemovedResources() {
		return this.removedResources;
	}

	/**
	 * If <code>true</code>, prevent modification or save. For example, if the
	 * resource being viewed comes from the package registry, it must not be
	 * saved.
	 */
	public boolean isReadOnly() {
		return !(getEditorInput() instanceof FileEditorInput);
	}

	public TreeViewer getTreeViewer() {
		return this.treeViewer;
	}

	public void setStyleSashForm(final int styleSashForm) {
		this.styleSashForm = styleSashForm;
	}

	protected void selectAffectedElements(final Command command) {
		if (command instanceof DragAndDropOnLinkCommand) {
			DragAndDropOnLinkCommand dragAndDropOnLinkCommand = (DragAndDropOnLinkCommand) command;
			Command dropCommand = dragAndDropOnLinkCommand.getDropCommand();
			selectAffectedElements(dropCommand, null, dragAndDropOnLinkCommand.getLinkItem());
		} else if (command instanceof DragAndDropOnModelElementCommand) {
			DragAndDropOnModelElementCommand dragAndDropOnModelElementCommand = (DragAndDropOnModelElementCommand) command;
			Command dropCommand = dragAndDropOnModelElementCommand.getDropCommand();
			selectAffectedElements(dropCommand,
					dragAndDropOnModelElementCommand.getModelElementItem(), null);
		} else if (this.editingDomain instanceof BrowserEditingDomain) {
			BrowserEditingDomain browserEditingDomain = (BrowserEditingDomain) this.editingDomain;
			Object selectedElementForCommand = browserEditingDomain
					.getEditorSelectionForCommand(command);
			if (selectedElementForCommand instanceof ModelElementItem) {
				ModelElementItem selectedModelElementItem = (ModelElementItem) selectedElementForCommand;
				selectAffectedElements(command, selectedModelElementItem, null);
			} else if (selectedElementForCommand instanceof LinkItem) {
				LinkItem linkItem = (LinkItem) selectedElementForCommand;
				selectAffectedElements(command, (ModelElementItem) linkItem.getTreeParent(),
						linkItem);
			}
		}
	}

	private void selectAffectedElements(final Command command,
			final ModelElementItem contextModelElementItem, final LinkItem contextLinkItem) {
		if (command instanceof AddCommand) {
			AddCommand addCommand = (AddCommand) command;
			if (contextLinkItem != null) {
				boolean result = selectElements(contextLinkItem, addCommand.getCollection());
				if (!result) {
					setSelection(Collections.singletonList(contextLinkItem), true);
					this.treeViewer.expandToLevel(contextLinkItem, 1);
				}
			} else if (contextModelElementItem != null) {
				selectElements(contextModelElementItem, addCommand.getFeature(),
						addCommand.getCollection());
			} else {
				selectElements(addCommand.getOwner(), addCommand.getFeature(),
						addCommand.getCollection());
			}
		} else if (command instanceof SetCommand) {
			SetCommand setCommand = (SetCommand) command;
			if (contextModelElementItem != null) {
				boolean result = selectElements(contextModelElementItem, setCommand.getFeature(),
						Collections.singleton(setCommand.getValue()));
				if (!result) {
					ITreeElement treeParent = contextModelElementItem.getTreeParent();
					setSelection(Collections.singletonList(treeParent), true);
					this.treeViewer.expandToLevel(treeParent, 1);
				}
			} else {
				selectElements(setCommand.getOwner(), setCommand.getFeature(),
						Collections.singleton(setCommand.getValue()));
			}
		} else if (command instanceof CreateChildCommand) {
			CreateChildCommand createChildCommand = (CreateChildCommand) command;
			Command command2 = createChildCommand.getCommand();
			selectAffectedElements(command2, contextModelElementItem, contextLinkItem);
		} else if (command instanceof DeleteCommand) {
			DeleteCommand deleteCommand = (DeleteCommand) command;
			List<Command> commandList = deleteCommand.getCommandList();
			if (commandList.size() > 0) {
				selectAffectedElements(commandList.get(0), contextModelElementItem, contextLinkItem);
			}
		} else if (command instanceof RemoveCommand) {
			RemoveCommand removeCommand = (RemoveCommand) command;
			LinkItem linkItem = null;
			if (contextModelElementItem != null) {
				ITreeElement parent = contextModelElementItem.getTreeParent();
				if (parent instanceof LinkItem) {
					linkItem = (LinkItem) parent;
				} else if (parent instanceof ModelElementItem) {
					// ↑ possible with "collapse" customization
					ModelElementItem modelElementItem = (ModelElementItem) parent;
					setSelection(Collections.singletonList(modelElementItem), true);
					return;
				}
			}
			if (linkItem == null) {
				browseTo(removeCommand.getOwner());
				ModelElementItem modelElementItem = getSelectedModelElementItem();
				linkItem = getLink(modelElementItem, removeCommand.getFeature());
			}
			if (linkItem != null) {
				this.treeViewer.expandToLevel(linkItem, 1);
				setSelection(Collections.singletonList(linkItem), true);
			}
		} else if (command instanceof CompoundCommand) {
			CompoundCommand compoundCommand = (CompoundCommand) command;
			List<Command> commandList = compoundCommand.getCommandList();
			if (commandList.size() > 0) {
				selectAffectedElements(commandList.get(commandList.size() - 1),
						contextModelElementItem, contextLinkItem);
			}
		} else if (command instanceof CommandWrapper) {
			CommandWrapper commandWrapper = (CommandWrapper) command;
			selectAffectedElements(commandWrapper.getCommand(), contextModelElementItem,
					contextLinkItem);
		}

		// PasteFromClipboardCommand : deliberately not handled, to let the user
		// paste multiple times, without having to reselect the parent element
		// each time
	}

	protected void selectElements(final EObject owner, final EStructuralFeature feature,
			final Collection<?> collection) {
		// TreePath treePath = findTreePathForElement(owner);
		// Object lastSegment = treePath.getLastSegment();
		browseTo(owner);
		ModelElementItem modelElementItem = getSelectedModelElementItem();
		selectElements(modelElementItem, feature, collection);
	}

	protected boolean selectElements(final ModelElementItem modelElementItem,
			final EStructuralFeature feature, final Collection<?> collection) {
		if (modelElementItem != null) {
			LinkItem linkItem = getLink(modelElementItem, feature);
			if (linkItem != null) {
				boolean result = selectElements(linkItem, collection);
				if (!result) {
					setSelection(Collections.singletonList(linkItem), true);
					this.treeViewer.expandToLevel(linkItem, 1);
				}
				return true;
			}
		}
		return false;
	}

	protected boolean selectElements(final LinkItem linkItem, final Collection<?> collection) {
		List<ModelElementItem> elementItems = new ArrayList<ModelElementItem>();
		for (Object object : collection) {
			if (object instanceof EObject) {
				EObject eObject = (EObject) object;
				ModelElementItem elementItem = getElement(linkItem, eObject);
				if (elementItem != null) {
					elementItems.add(elementItem);
				}
			}
		}
		if (!elementItems.isEmpty()) {
			setSelection(elementItems, true);
			return true;
		}
		return false;
	}

	protected void setSelection(final List<? extends ITreeElement> treeElements,
			final boolean reveal) {
		List<TreePath> treePaths = new ArrayList<TreePath>();
		for (ITreeElement treeElement : treeElements) {
			List<ITreeElement> segments = new ArrayList<ITreeElement>();
			ITreeElement current = treeElement;
			while (current != null) {
				segments.add(current);
				current = current.getTreeParent();
			}

			if (segments.size() > 0) {
				ITreeElement[] segmentsArray = new ITreeElement[segments.size()];
				for (int i = 0; i < segments.size(); i++) {
					segmentsArray[i] = segments.get(segments.size() - i - 1);
				}
				treePaths.add(new TreePath(segmentsArray));
			}
		}

		if (!treePaths.isEmpty()) {
			this.treeViewer.setSelection(
					new TreeSelection(treePaths.toArray(new TreePath[treePaths.size()])), reveal);
		}
	}

	protected LinkItem getLink(final ModelElementItem selectedModelElementItem,
			final EStructuralFeature feature) {
		ITreeContentProvider contentProvider = (ITreeContentProvider) this.treeViewer
				.getContentProvider();
		Object[] children = contentProvider.getChildren(selectedModelElementItem);
		for (Object child : children) {
			if (child instanceof LinkItem) {
				LinkItem linkItem = (LinkItem) child;
				if (linkItem.getReference() == feature) {
					return linkItem;
				}
			}
		}
		return null;
	}

	protected ModelElementItem getElement(final LinkItem linkItem, final EObject eObject) {
		ITreeContentProvider contentProvider = (ITreeContentProvider) this.treeViewer
				.getContentProvider();
		Object[] children = contentProvider.getChildren(linkItem);
		for (Object child : children) {
			if (child instanceof ModelElementItem) {
				ModelElementItem modelElementItem = (ModelElementItem) child;
				if (EcoreUtil.getURI(modelElementItem.getEObject()).equals(
						EcoreUtil.getURI(eObject))) {
					return modelElementItem;
				}
			}
		}
		return null;
	}

	protected ModelElementItem getSelectedModelElementItem() {
		ITreeSelection selection = (ITreeSelection) this.treeViewer.getSelection();
		Object firstElement = selection.getFirstElement();
		if (firstElement instanceof ModelElementItemEx) {
			ModelElementItemEx modelElementItem = (ModelElementItemEx) firstElement;
			return modelElementItem;
		}
		return null;
	}

	public void doWhenLoaded(final Runnable runnable) {
		if (this.loaded) {
			Display.getDefault().syncExec(runnable);
		} else {
			this.doWhenLoaded.add(runnable);
		}
	}

	/**
	 * Replace the default context by a dummy one when the given widget is
	 * focused. The dummy context is used to redefine the "Ctrl+X", "Ctrl+C" and
	 * "Ctrl+V" key bindings to a command which does nothing. This is useful to
	 * prevent these commands associated to the existing context from being
	 * executed when this widget is focused.
	 */
	private void fixClipboardCommands(final Control control) {
		final IWorkbench workbench = PlatformUI.getWorkbench();
		final IContextService contextService = (IContextService) workbench
				.getService(IContextService.class);

		control.addFocusListener(new FocusListener() {
			private IContextActivation contextActivation = null;

			public void focusGained(final FocusEvent event) {
				this.contextActivation = contextService
						.activateContext("org.eclipse.modisco.infra.browser.dummyContext"); //$NON-NLS-1$
			}

			public void focusLost(final FocusEvent event) {
				if (this.contextActivation != null) {
					contextService.deactivateContext(this.contextActivation);
				}
			}
		});
	}

	/**
	 * * Adapter used to update the problem indication when resources are
	 * demanded loaded.
	 */
	private final EContentAdapter problemIndicationAdapter = new EContentAdapter() {
		@Override
		public void notifyChanged(final Notification notification) {
			if (notification.getNotifier() instanceof Resource) {
				switch (notification.getFeatureID(Resource.class)) {
				case Resource.RESOURCE__IS_LOADED:
				case Resource.RESOURCE__ERRORS:
				case Resource.RESOURCE__WARNINGS:
					Resource resource = (Resource) notification.getNotifier();
					Diagnostic diagnostic = analyzeResourceProblems(resource, null);
					if (diagnostic.getSeverity() != Diagnostic.OK) {
						EcoreBrowser.this.resourceToDiagnosticMap.put(resource, diagnostic);
					} else {
						EcoreBrowser.this.resourceToDiagnosticMap.remove(resource);
					}

					if (EcoreBrowser.this.updateProblemIndication) {
						getSite().getShell().getDisplay().asyncExec(new Runnable() {
							public void run() {
								updateProblemIndication();
							}
						});
					}
					break;
				default:
				}
			} else {
				super.notifyChanged(notification);
			}
		}

		@Override
		protected void setTarget(final Resource theTarget) {
			basicSetTarget(theTarget);
		}

		@Override
		protected void unsetTarget(final Resource theTarget) {
			basicUnsetTarget(theTarget);
		}
	};

	/**
	 * Refreshes the selection (checked) state of actions in the Browser's
	 * toolbar.
	 */
	public void refreshToolbar() {
		this.instancesToolBar.refresh();
	}

	protected Text getSearchBox() {
		return this.searchBox;
	}

	protected void setSearchBox(final Text searchBox) {
		this.searchBox = searchBox;
	}

	public IWorkbenchSiteProgressService getProgressService() {
		IWorkbenchSiteProgressService service = null;
		Object siteService = getSite().getAdapter(IWorkbenchSiteProgressService.class);
		if (siteService != null) {
			service = (IWorkbenchSiteProgressService) siteService;
		}
		return service;
	}

	public boolean isRefreshing() {
		return this.refreshJob != null && this.refreshJob.getState() != Job.NONE;
	}
}
