/*******************************************************************************
 *  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.ODataArtifactSelectionUtil;
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);
				}
				//below code is enable the artifact selection extention
			    PictogramElement[] selectedPictogramElements = getSelectedPictogramElements();
			    EObject businessObject = (EObject) getDiagramTypeProvider().getFeatureProvider().getBusinessObjectForPictogramElement(selectedPictogramElements[0]);
			    ODataArtifactSelectionUtil.notifyRegisteredSubscribers(selectedPictogramElements[0], businessObject , ODataArtifactSelectionUtil.SelectionStatus.SELECTED);
			}
		}
	}

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