/*******************************************************************************
 *  Copyright (c) 2012-2014 SAP SE.
 *  All rights reserved. This program and the accompanying materials
 *  are made available under the terms of the Eclipse Public License v1.0
 *  which accompanies this distribution, and is available at
 *  http://www.eclipse.org/legal/epl-v10.html
 *
 *  Contributors:
 *  SAP SE - initial API and implementation and/or initial documentation
 *
 *******************************************************************************/
package org.eclipse.ogee.designer;

import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.transaction.RecordingCommand;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.gef.GraphicalViewer;
import org.eclipse.gef.ui.actions.ActionRegistry;
import org.eclipse.graphiti.features.context.impl.CustomContext;
import org.eclipse.graphiti.mm.pictograms.ContainerShape;
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
import org.eclipse.graphiti.mm.pictograms.Shape;
import org.eclipse.graphiti.services.Graphiti;
import org.eclipse.graphiti.ui.editor.DiagramBehavior;
import org.eclipse.graphiti.ui.editor.DiagramEditor;
import org.eclipse.graphiti.ui.editor.DiagramEditorInput;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.ogee.designer.actions.ODataArtifactsCollapseAllAction;
import org.eclipse.ogee.designer.actions.ODataArtifactsExpandAllAction;
import org.eclipse.ogee.designer.actions.ODataShowUsageAction;
import org.eclipse.ogee.designer.features.ODataCollapsibleFeature;
import org.eclipse.ogee.designer.messages.Messages;
import org.eclipse.ogee.designer.utils.ArtifactUtil;
import org.eclipse.ogee.designer.utils.IODataEditorConstants;
import org.eclipse.ogee.designer.utils.ODataLayoutUtil;
import org.eclipse.ogee.designer.utils.PropertyUtil;
import org.eclipse.ogee.designer.visualizer.ODataModelVisualizer;
import org.eclipse.ogee.model.api.IModelContext;
import org.eclipse.ogee.model.api.IValidator;
import org.eclipse.ogee.model.api.ModelAPIException;
import org.eclipse.ogee.model.odata.EDMXSet;
import org.eclipse.ogee.utils.logger.Logger;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchListener;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.contexts.IContextService;
import org.eclipse.ui.dialogs.SaveAsDialog;
import org.eclipse.ui.ide.IGotoMarker;
import org.eclipse.ui.ide.ResourceUtil;
import org.eclipse.ui.navigator.CommonNavigator;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.part.MultiPageEditorPart;

/**
 * OData Model Graphical Editor.
 */
public class ODataEditor extends DiagramEditor implements IGotoMarker {

	private IFile modelFile;
	private boolean isReadOnly = false;
	private IWorkbenchListener workbenchListener;
	private ODataDomainModelChangeListener odataModelChangeListener;
	private IAction expandAllAction;
	private IAction collapseAllAction;
	private IAction showUsageAction;
	private GraphicalViewer graphicalViewer;

	/**
	 * OData Editor ID
	 */
	public static final String EDITOR_ID = "org.eclipse.ogee.designer.ODataEditor"; //$NON-NLS-1$

	@Override
	public void init(IEditorSite site, final IEditorInput input)
			throws PartInitException {

		boolean isBlankModel = false;

		try {
			// Editor is invoked from Project Explorer.
			if (input instanceof IFileEditorInput) {
				this.setModelFile(((IFileEditorInput) input).getFile());

				// OData file is read only
				this.isReadOnly = ((IFileEditorInput) input).getFile()
						.isReadOnly();
			}
			// Editor is invoked from IODataDiagramCreator#createDiagram() API.
			else if (input instanceof ODataEditorInput) {
				final URI uri = ((ODataEditorInput) input).getUri();
				final String uriString = uri.trimFragment().toPlatformString(
						true);
				this.setModelFile(getModelFile(new Path(uriString)));
				isBlankModel = ((ODataEditorInput) input).isBlankModel();
				this.isReadOnly = ((ODataEditorInput) input).getDiagramInput()
						.isReadOnlyMode();
			}
			// Editor is invoked when eclipse IDE is launched.
			else if (input instanceof DiagramEditorInput) {
				final URI uri = ((DiagramEditorInput) input).getUri();
				final String uriString = uri.trimFragment().toPlatformString(
						true);
				this.setModelFile(getModelFile(new Path(uriString)));
				// OData file is read only
				this.isReadOnly = getModelFile(new Path(uriString))
						.isReadOnly();
			}
			// invoke super's init(). Do not change the invocation position.
			super.init(site, input);
			// obtain the global context support instance from the workbench.
			final IContextService contextService = (IContextService) PlatformUI
					.getWorkbench().getService(IContextService.class);
			if (contextService != null) {
				// enable the context defined for OData Editor.
				contextService
						.activateContext(IODataEditorConstants.ODATA_EDITOR_CONTEXT_ID);
			}
			// for non-empty model input, visualize the model.
			if (input instanceof ODataEditorInput && !isBlankModel) {
				final ODataEditorInput editorInput = (ODataEditorInput) input;
				final IProgressMonitor monitor = editorInput.getDiagramInput()
						.getProgressMonitor();
				final TransactionalEditingDomain editingDomain = this
						.getEditingDomain();
				editingDomain.getCommandStack().execute(
						new RecordingCommand(editingDomain) {
							@Override
							protected void doExecute() {
								/*
								 * ODataEditorService.updateProgressMonitor(
								 * Messages.PROGRESS_TASK_NAME7, 5, monitor); //
								 * completed 15%
								 */
								monitor.setTaskName(Messages.PROGRESS_TASK_NAME7);
								monitor.worked(5);

								final ODataModelVisualizer visualizer = new ODataModelVisualizer(
										getDiagramTypeProvider());
								visualizer.visualizeModel(editorInput);

								/*
								 * ODataEditorService.updateProgressMonitor(null,
								 * 5, monitor); // completed 70%
								 */
								monitor.worked(5);

								// Do not validate read only models.
								if (!editorInput.getDiagramInput()
										.isReadOnlyMode()) {

									/*
									 * ODataEditorService.updateProgressMonitor(
									 * Messages.PROGRESS_TASK_NAME8, 0,
									 * monitor);
									 */

									monitor.setTaskName(Messages.PROGRESS_TASK_NAME8);
									monitor.worked(0);

									final EDMXSet edmxSet = editorInput
											.getDiagramInput().getEDMXSet();
									// Validate the edmxSet according to the
									// OData 3.0 specification.
									// For each constraint violation a
									// corresponding problem marker is
									// created.
									if (edmxSet != null) {
										final IValidator validator = IModelContext.INSTANCE
												.createValidator();
										validator.validate(edmxSet);
									}
								}

							}
						});
				/*
				 * ODataEditorService.updateProgressMonitor(
				 * Messages.PROGRESS_TASK_NAME10, 0, monitor);
				 */

				monitor.setTaskName(Messages.PROGRESS_TASK_NAME10);
				monitor.worked(0);
				try {
					final IFile file = getModelFile();
					if (file != null) {
						IModelContext.INSTANCE.saveModelFile(file);
					}
				} catch (ModelAPIException e) {
					Logger.getLogger(Activator.PLUGIN_ID).logError(e);
				}
				/*
				 * ODataEditorService.updateProgressMonitor(
				 * Messages.PROGRESS_TASK_NAME6, 10, monitor); // completed //
				 * 80%
				 */
				monitor.setTaskName(Messages.PROGRESS_TASK_NAME6);
				monitor.worked(10);
			}
			// add a listener so we get notified if the workbench is shutting
			// down.
			// in this case dispose the temporary model files.
			addWorkbenchListener();
		} catch (PartInitException e) {
			Logger.getLogger(Activator.PLUGIN_ID).logError(e);
			throw new PartInitException(new Status(IStatus.ERROR,
					Activator.PLUGIN_ID, e.getMessage(), e));
		} catch (Exception t) {
			Logger.getLogger(Activator.PLUGIN_ID).logError(t);
			throw new PartInitException(new Status(IStatus.ERROR,
					Activator.PLUGIN_ID, t.getMessage(), t));
		}
	}

	/**
	 * Creates DiagramBehavior Instance.
	 */
	@Override
	protected DiagramBehavior createDiagramBehavior() {

		return new ODataDiagramBehavior(this);
	}

	@Override
	public String getContributorId() {

		return super.getContributorId();
	}

	@SuppressWarnings("rawtypes")
	@Override
	public Object getAdapter(Class required) {

		if (required == IGotoMarker.class) {
			return this;
		}

		return super.getAdapter(required);
	}

	@Override
	public void gotoMarker(IMarker marker) {

		EObject bo = null;

		try {
			if (IODataEditorConstants.PROBLEM_MARKER_ID
					.equals(marker.getType())) {
				final String uriAttribute = marker.getAttribute(
						IMarker.LOCATION, null);
				if (uriAttribute != null) {
					final URI uri = URI.createURI(uriAttribute);
					EObject eObject = getDiagramBehavior().getResourceSet()
							.getEObject(uri, true);
					eObject = ArtifactUtil.getSelectableObject(eObject);
					if (eObject != null) {
						// peList -> list of selectable PictogramElement's.
						final List<PictogramElement> peList = new ArrayList<PictogramElement>();
						final List<PictogramElement> referencingPes = Graphiti
								.getLinkService().getPictogramElements(
										getDiagramTypeProvider().getDiagram(),
										eObject);
						// for selected object with the Top Container set, only
						// add the PictogramElement with the Top Container
						for (PictogramElement pe : referencingPes) {
							bo = Graphiti
									.getLinkService()
									.getBusinessObjectForLinkedPictogramElement(
											pe);
							if (eObject.equals(bo)
									&& PropertyUtil.isTopContainer(pe)) {
								// add selectable Top Container Pictogram
								// Element into one list -> peList
								peList.add(pe);
								break;
							}
						}
						if (!referencingPes.isEmpty() && peList.isEmpty()) {
							for (PictogramElement pe : referencingPes) {
								bo = Graphiti
										.getLinkService()
										.getBusinessObjectForLinkedPictogramElement(
												pe);
								if (eObject.equals(bo)) {
									// add selectable Pictogram Element into one
									// list -> peList
									peList.add(pe);
								}
							}
						}
						// Do the selection in the diagram (in case there is
						// something to select)
						PictogramElement[] pes = null;
						if (peList.size() > 0) {
							pes = peList.toArray(new PictogramElement[peList
									.size()]);
						}
						if (pes != null && pes.length > 0) {
							for (PictogramElement pe : pes) {
								// expand the group corresponding to selected
								// pictogram element.
								this.expandGroup(pe);
							}
							// Do the selection in the diagram
							selectPictogramElements(pes);
						}
					}
				}
			}
		} catch (CoreException exception) {
			Logger.getLogger(Activator.PLUGIN_ID).logError(exception);
		}
	}

	@Override
	public boolean isSaveAsAllowed() {

		if (this.isReadOnly) {
			return false;
		}

		return true;

	}

	@Override
	public void doSave(IProgressMonitor monitor) {

		super.doSave(monitor);

		final EDMXSet edmxSet = getEDMXSet();
		// Validate the edmxSet according to the OData 3.0 specification.
		// For each constraint violation a corresponding problem marker is
		// created.
		if (edmxSet != null) {
			final IValidator validator = IModelContext.INSTANCE
					.createValidator();
			validator.validate(edmxSet);
			getDiagramBehavior().refresh();
			// bug fix for Artifact name still in edit mode after save
			// programatically call Escape key so as to lose focus of editor
			if (getDiagramBehavior().isDirectEditingActive()) {
				Robot robot;
				try {
					robot = new Robot();
					robot.keyPress(KeyEvent.VK_ESCAPE);
				} catch (AWTException e) {
					Logger.getLogger(Activator.PLUGIN_ID).logError(e);
				}
			}

		}
	}

	@Override
	public void doSaveAs() {

		handleSaveAs();

		final EDMXSet edmxSet = getEDMXSet();
		// Validate the edmxSet according to the OData 3.0 specification.
		// For each constraint violation a corresponding problem marker is
		// created.
		if (edmxSet != null) {
			final IValidator validator = IModelContext.INSTANCE
					.createValidator();
			validator.validate(edmxSet);
			getDiagramBehavior().refresh();
		}
	}

	@Override
	public void selectionChanged(IWorkbenchPart part, ISelection selection) {

		// As GEF doesn't understands multi-page editors,
		// invoke updateActions() in case the active editor is an
		// instance of MultiPageEditorPart.
		final IEditorPart editor = getSite().getPage().getActiveEditor();
		if (editor instanceof MultiPageEditorPart) {
			// Update the selectionActions list when the editor is selected
			// as a page of a MultiPageEditorPart.
			updateActions(getSelectionActions());
		}
		this.handleSelectionChanged(part, selection);
	}

	@Override
	public boolean isDirty() {
		if (this.isReadOnly) {
			return false;
		}
		return super.isDirty();
	}

	/**
	 * registered listener has to be removed before dispose of editor.
	 */
	@Override
	public void dispose() {

		super.dispose();

		if (this.modelFile != null
				&& IODataEditorConstants.TEMPFILE_EXTENSION
						.equals(this.modelFile.getFileExtension())) {
			disposeTempFile(this.modelFile);
		} else {
			final TransactionalEditingDomain editingDomain = this
					.getEditingDomain();
			if (editingDomain != null) {
				editingDomain
						.removeResourceSetListener(this.odataModelChangeListener);
				this.odataModelChangeListener = null;
			}
		}
		// Remove the added actions from action registry & dispose.
		if (this.expandAllAction != null) {
			getActionRegistry().removeAction(this.expandAllAction);
			this.expandAllAction = null;
		}
		if (this.collapseAllAction != null) {
			getActionRegistry().removeAction(this.collapseAllAction);
			this.collapseAllAction = null;
		}
		if (this.showUsageAction != null) {
			getActionRegistry().removeAction(this.showUsageAction);
			this.showUsageAction = null;
		}
		getActionRegistry().dispose();

		this.modelFile = null;
		this.graphicalViewer = null;

		this.removeWorkbenchListener();
		this.odataModelChangeListener = null;
	}

	/**
	 * @return IFile - model file
	 */
	public IFile getModelFile() {

		return this.modelFile;
	}

	/**
	 * @param file
	 *            - instance of IFile
	 */
	public void setModelFile(final IFile file) {

		this.modelFile = file;
	}

	/**
	 * @return boolean - true, if read only.
	 */
	public boolean isReadOnly() {

		return this.isReadOnly;
	}

	/**
	 * @param readOnlyFlag
	 *            - set true, if read only.
	 */
	public void setReadOnly(final boolean readOnlyFlag) {

		this.isReadOnly = readOnlyFlag;
	}

	@Override
	protected void setInput(IEditorInput input) {

		super.setInput(input);
	}

	private static IFile getModelFile(IPath fullPath) {

		return ResourcesPlugin.getWorkspace().getRoot()
				.getFile(fullPath.makeAbsolute());
	}

	// The following method is redefined as the configuration provider is not
	// yet part of the Graphiti API in 0.9.
	// TODO Fix it as we switch to Graphiti 0.10.
	/*
	 * The following method is redefined in order to disable all external
	 * droppings into the diagram. (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.graphiti.ui.editor.DiagramEditor#createGraphicalViewer(org
	 * .eclipse.swt.widgets.Composite)
	 */
	@Override
	protected void createGraphicalViewer(Composite parent) {

		// In order to disable all external droppings into the diagram, the
		// customized viewer "ODataScrollingGraphicalViewer" is implemented
		// in which the object transfer drop listener is filtered out on adding.
		this.graphicalViewer = new ODataScrollingGraphicalViewer(this);
		this.graphicalViewer.createControl(parent);
		setGraphicalViewer(this.graphicalViewer);
		configureGraphicalViewer();
		hookGraphicalViewer();
		initializeGraphicalViewer();
	}

	@Override
	public ActionRegistry getActionRegistry() {

		return super.getActionRegistry();
	}

	@Override
	protected void initializeActionRegistry() {

		super.initializeActionRegistry();

		// Register an "expand all" action to expand all OData artifacts from
		// graphical editor tool bar.
		this.expandAllAction = new ODataArtifactsExpandAllAction(this);
		this.expandAllAction.setEnabled(true);
		getActionRegistry().registerAction(this.expandAllAction);

		// Register a "collapse all" action to collapse all OData artifacts from
		// graphical editor tool bar.
		this.collapseAllAction = new ODataArtifactsCollapseAllAction(this);
		this.collapseAllAction.setEnabled(true);
		getActionRegistry().registerAction(this.collapseAllAction);

		// Register a "show/hide all usages" action to show/hide usages of all
		// types from graphical editor tool bar.
		this.showUsageAction = new ODataShowUsageAction(this);
		this.showUsageAction.setEnabled(true);
		if (PropertyUtil.isShowAllUsage(this.getDiagramTypeProvider()
				.getDiagram())) {
			this.showUsageAction.setChecked(true);
		} else {
			this.showUsageAction.setChecked(false);
		}
		getActionRegistry().registerAction(this.showUsageAction);
	}

	/**
	 * Delete the temporary model file & the project.
	 * 
	 * @param file
	 *            - the temporary diagram file.
	 */
	protected static void disposeTempFile(final IFile tempFile) {

		try {
			if (tempFile != null && tempFile.exists()) {
				final IProject project = tempFile.getProject();
				tempFile.delete(true, null);
				if (project != null && project.exists()) {
					project.delete(true, null);
				}
			}
		} catch (CoreException e) {
			Logger.getLogger(Activator.PLUGIN_ID).logError(e);
		}
	}

	/**
	 * Handles a selection changed event that is triggered by any selection
	 * source, e.g. a browser with "Link to Editor" enabled.<br>
	 * Checks if the currently active editor is a {@link MultiPageEditorPart}
	 * with an opened diagram editor inside, tries to find any
	 * {@link PictogramElement} for the objects in the selection and selects
	 * them in the diagram.<br>
	 * Note that in case of the {@link CommonNavigator} as event source, its
	 * editor linking mechanism must be enabled.
	 * 
	 * @param part
	 *            the source {@link IWorkbenchPart} that triggered the event
	 * @param selection
	 *            the new selection (mostly a {@link IStructuredSelection}
	 *            instance.
	 */
	private void handleSelectionChanged(final IWorkbenchPart part,
			final ISelection selection) {

		EObject bo = null;
		EObject selectableObj = null;

		// If not the active editor, ignore selection changed.
		boolean editorIsActive = getSite().getPage().isPartVisible(this);
		if (!editorIsActive) {
			// Check if we are a page of the active multi page editor
			final IEditorPart activeEditor = getSite().getPage()
					.getActiveEditor();
			if (activeEditor != null) {
				if (activeEditor instanceof MultiPageEditorPart) {
					final Object selectedPage = ((MultiPageEditorPart) activeEditor)
							.getAdapter(DiagramEditor.class);
					if (selectedPage instanceof DiagramEditor) {
						// Editor is active and diagram sub-editor is its active
						// page
						editorIsActive = true;
					}
				}
			}
		}
		if (editorIsActive) {
			// this is where we should check the selection source (part)
			// for CNF view the link flag must be obeyed
			// this would however require a dependency to
			// org.eclipse.ui.navigator
			if (part instanceof CommonNavigator) {
				if (!((CommonNavigator) part).isLinkingEnabled()) {
					return;
				}
			}
			if (selection instanceof IStructuredSelection) {
				final IStructuredSelection structuredSelection = (IStructuredSelection) selection;
				// Collect all Pictogram Elements for all selected domain
				// objects into one list -> peList
				final List<PictogramElement> peList = new ArrayList<PictogramElement>();
				for (Iterator<?> iterator = structuredSelection.iterator(); iterator
						.hasNext();) {
					final Object object = iterator.next();
					if (object instanceof EObject) {
						selectableObj = ArtifactUtil
								.getSelectableObject((EObject) object);
						if (selectableObj != null) {
							// Find the Pictogram Elements for the given domain
							// object via the standard link service
							final List<PictogramElement> referencingPes = Graphiti
									.getLinkService().getPictogramElements(
											getDiagramTypeProvider()
													.getDiagram(),
											selectableObj);
							// for selected object with the Top Container set,
							// add only the PictogramElement with the Top
							// Container.
							for (PictogramElement pe : referencingPes) {
								bo = Graphiti
										.getLinkService()
										.getBusinessObjectForLinkedPictogramElement(
												pe);
								if (selectableObj.equals(bo)
										&& PropertyUtil.isTopContainer(pe)) {
									// add selectable Top Container Pictogram
									// Element into one list -> peList
									peList.add(pe);
									break;
								}
							}
							if (!referencingPes.isEmpty() && peList.isEmpty()) {
								for (PictogramElement pe : referencingPes) {
									bo = Graphiti
											.getLinkService()
											.getBusinessObjectForLinkedPictogramElement(
													pe);
									if (selectableObj.equals(bo)) {
										// add selectable Pictogram Element into
										// one list -> peList
										peList.add(pe);
									}
								}
							}
						}
					} else {
						// For non-EMF domain objects use the registered
						// notification service for finding
						PictogramElement[] relatedPictogramElements = getDiagramTypeProvider()
								.getNotificationService()
								.calculateRelatedPictogramElements(
										new Object[] { object });
						for (int i = 0; i < relatedPictogramElements.length; i++) {
							peList.add(relatedPictogramElements[i]);
						}
					}
				}
				// Do the selection in the diagram (in case there is something
				// to select)
				PictogramElement[] pes = null;
				if (peList.size() > 0) {
					pes = peList.toArray(new PictogramElement[peList.size()]);
				}
				if (pes != null && pes.length > 0) {
					for (PictogramElement pe : pes) {
						// expand the group corresponding to selected
						// pictogram element.
						this.expandGroup(pe);
					}
					// Do the selection in the diagram.
					selectPictogramElements(pes);
				}
			}
		}
	}

	/*
	 * Get EDMXSet from OData service model file.
	 */
	private EDMXSet getEDMXSet() {

		EDMXSet edmxSet = null;

		if (this.getModelFile() != null) {
			final URI uri = URI.createPlatformResourceURI(this.getModelFile()
					.getFullPath().toString(), true);
			final EList<EObject> resourceContents = getDiagramBehavior()
					.getResourceSet().getResource(uri, true).getContents();
			for (EObject resourceContent : resourceContents) {
				if (resourceContent instanceof EDMXSet) {
					edmxSet = (EDMXSet) resourceContent;
					break;
				}
			}
		}

		return edmxSet;
	}

	/*
	 * The following method will expand the collapsed group for the selected
	 * pictogram element.
	 */
	private void expandGroup(final PictogramElement pe) {

		if (pe != null && pe instanceof ContainerShape) {
			final Shape expandSection = ODataLayoutUtil
					.getSectionTitle((ContainerShape) pe);
			if (expandSection != null) {
				final TransactionalEditingDomain editingDomain = this
						.getEditingDomain();
				editingDomain.getCommandStack().execute(
						new RecordingCommand(editingDomain) {
							@Override
							public void doExecute() {
								final ODataCollapsibleFeature collapsableFeature = new ODataCollapsibleFeature(
										getDiagramTypeProvider()
												.getFeatureProvider());
								final CustomContext context = new CustomContext();
								context.setPictogramElements(new PictogramElement[] { expandSection });
								collapsableFeature.execute(context);
							}
						});
			}
		}
	}

	/*
	 * The following method disposes the temporary model files on eclipse
	 * shutdown.
	 */
	private void addWorkbenchListener() {

		if (this.workbenchListener == null) {
			this.workbenchListener = new IWorkbenchListener() {
				@Override
				public boolean preShutdown(IWorkbench workbench, boolean forced) {

					if (getModelFile() != null
							&& getModelFile().exists()
							&& IODataEditorConstants.TEMPFILE_EXTENSION
									.equals(getModelFile().getFileExtension())) {
						final IWorkbenchPage page = getSite().getPage();
						final IEditorPart editorPart = ResourceUtil.findEditor(
								page, getModelFile());
						if (editorPart != null) {
							page.closeEditor(editorPart, false);
						}
						disposeTempFile(getModelFile());
					}
					return true;
				}

				@Override
				public void postShutdown(IWorkbench workbench) {
					// do nothing
				}
			};
			PlatformUI.getWorkbench().addWorkbenchListener(
					this.workbenchListener);
		}
	}

	private void removeWorkbenchListener() {

		if (this.workbenchListener != null) {
			PlatformUI.getWorkbench().removeWorkbenchListener(
					this.workbenchListener);
			this.workbenchListener = null;
		}
	}

	private void handleSaveAs() {

		IFile oldFile = getModelFile();
		SaveAsDialog saveAsDialog = new SaveAsDialog(getSite().getShell());
		saveAsDialog.setOriginalFile(oldFile);
		saveAsDialog.create();
		if (saveAsDialog.open() == Window.CANCEL) {
			return;
		}
		IPath newFilePath = saveAsDialog.getResult();
		if (newFilePath == null) {
			return;
		}
		IFile newFile = ResourcesPlugin.getWorkspace().getRoot()
				.getFile(newFilePath);
		IWorkbenchPage page = getSite().getPage();
		try {
			// Save the current(old) file
			doSave(null);
			// if new file exists, close its editor (if open) and delete the
			// existing file
			if (newFile.exists()) {
				IEditorPart editorPart = ResourceUtil.findEditor(page, newFile);
				if (editorPart != null) {
					page.closeEditor(editorPart, false);
				}
				newFile.delete(true, null);
			}
			// make a copy
			oldFile.copy(newFilePath, true, null);
		} catch (CoreException e) {
			Logger.getLogger(Activator.PLUGIN_ID).logError(e);
			return;
		}
		// open new editor
		try {
			page.openEditor(new FileEditorInput(newFile), ODataEditor.EDITOR_ID);
		} catch (PartInitException e) {
			Logger.getLogger(Activator.PLUGIN_ID).logError(e);
			return;
		}
		// and close the old editor
		IEditorPart editorPart = ResourceUtil.findEditor(page, oldFile);
		if (editorPart != null) {
			page.closeEditor(editorPart, false);
		}
		try {
			newFile.refreshLocal(IResource.DEPTH_ZERO, null);
		} catch (CoreException e) {
			Logger.getLogger(Activator.PLUGIN_ID).logError(e);
			return;
		}
	}
}
