package org.eclipse.jpt.jpadiagrameditor.swtbot.tests.ui.editor;

import static org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable.asyncExec;
import static org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable.syncExec;
import static org.eclipse.swtbot.swt.finder.waits.Conditions.shellIsActive;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.awt.AWTException;
import java.awt.Robot;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.draw2d.FigureCanvas;
import org.eclipse.draw2d.IFigure;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.GraphicalViewer;
import org.eclipse.gef.LayerConstants;
import org.eclipse.gef.editparts.ScalableFreeformRootEditPart;
import org.eclipse.graphiti.features.IFeatureProvider;
import org.eclipse.graphiti.internal.ExternalPictogramLink;
import org.eclipse.graphiti.mm.Property;
import org.eclipse.graphiti.mm.pictograms.FreeFormConnection;
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
import org.eclipse.graphiti.services.Graphiti;
import org.eclipse.graphiti.ui.internal.contextbuttons.ContextButton;
import org.eclipse.graphiti.ui.internal.contextbuttons.ContextButtonPad;
import org.eclipse.graphiti.ui.internal.parts.DiagramEditPart;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jpt.jpa.core.context.java.JavaPersistentAttribute;
import org.eclipse.jpt.jpa.core.context.java.JavaPersistentType;
import org.eclipse.jpt.jpa.core.jpa2.MappingKeys2_0;
import org.eclipse.jpt.jpa.ui.internal.details.JptUiDetailsMessages;
import org.eclipse.jpt.jpadiagrameditor.swtbot.tests.internal.Utils;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.i18n.JPAEditorMessages;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.provider.IJPAEditorFeatureProvider;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.relations.HasReferanceRelation;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.relations.IRelation;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.relations.IRelation.RelType;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.relations.IsARelation;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.util.JPAEditorConstants;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.util.JPAEditorUtil;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView;
import org.eclipse.swtbot.eclipse.gef.finder.SWTGefBot;
import org.eclipse.swtbot.eclipse.gef.finder.widgets.SWTBotGefConnectionEditPart;
import org.eclipse.swtbot.eclipse.gef.finder.widgets.SWTBotGefEditPart;
import org.eclipse.swtbot.eclipse.gef.finder.widgets.SWTBotGefEditor;
import org.eclipse.swtbot.swt.finder.SWTBot;
import org.eclipse.swtbot.swt.finder.results.VoidResult;
import org.eclipse.swtbot.swt.finder.utils.Position;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotButton;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotStyledText;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotText;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
import org.eclipse.swtbot.swt.finder.widgets.TimeoutException;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;

@SuppressWarnings("restriction")
public class EditorProxy {

	private final SWTWorkbenchBot workbenchBot;
	protected SWTGefBot bot;

	private SWTBotGefEditor jpaDiagramEditor;

	/**
	 * Create proxy object.
	 * 
	 * @param bot
	 */
	public EditorProxy(SWTWorkbenchBot workbenchBot, SWTGefBot bot) {
		this.workbenchBot = workbenchBot;
		this.bot = bot;
	}

	public SWTBotGefEditor openDiagramOnJPAContentNode(String name) {
		SWTBotTree projectTree = workbenchBot.viewByTitle("Project Explorer")
				.bot().tree();
		SWTBotTreeItem item = projectTree.expandNode(name)
				.expandNode("JPA Content").select();
		assertTrue("The JPA Content node is disabled.", item.isEnabled());
		ContextMenuHelper.clickContextMenu(projectTree, "Open Diagram");

		workbenchBot
				.waitUntil(
						shellIsActive(JPAEditorMessages.OpenJpaDiagramActionDelegate_jpaSupportWarningTitle),
						10000);
		SWTBotShell jpaSupportWarningDialog = workbenchBot
				.shell(JPAEditorMessages.OpenJpaDiagramActionDelegate_jpaSupportWarningTitle);
		getOkButton(jpaSupportWarningDialog).click();

		SWTBotGefEditor jpaDiagramEditor = bot.gefEditor(name);
		assertFalse("Editor must not be dirty!", jpaDiagramEditor.isDirty());

		List<SWTBotGefEditPart> entities = jpaDiagramEditor.mainEditPart()
				.children();
		assertTrue("Editor must not contains any entities!", entities.isEmpty());

		return jpaDiagramEditor;
	}

	public SWTBotGefEditor openDiagramOnJPAProjectNode(String name,
			boolean isJPA20) {
		SWTBotTree projectTree = workbenchBot.viewByTitle("Project Explorer")
				.bot().tree();
		projectTree.expandNode(name).select();
		ContextMenuHelper.clickContextMenu(projectTree, "JPA Tools",
				"Open Diagram");

		if (isJPA20) {
			workbenchBot
					.waitUntil(
							shellIsActive(JPAEditorMessages.OpenJpaDiagramActionDelegate_jpaSupportWarningTitle),
							10000);
			SWTBotShell jpaSupportWarningDialog = workbenchBot
					.shell(JPAEditorMessages.OpenJpaDiagramActionDelegate_jpaSupportWarningTitle);
			getOkButton(jpaSupportWarningDialog).click();
		}

		SWTBotGefEditor jpaDiagramEditor = bot.gefEditor(name);
		assertFalse("Editor must not be dirty!", jpaDiagramEditor.isDirty());
		return jpaDiagramEditor;
	}

	/**
	 * Gets the "Select Type" dialog that appears when the attribute's context
	 * menu "Refactor Attribute Type..." is selected
	 * 
	 * @param attribute
	 * @return the "Select Type" dialog
	 */
	public SWTBotShell getSelectNewAttributeTypeDialog(
			SWTBotGefEditPart attribute) {
		attribute.click();
		jpaDiagramEditor
				.clickContextMenu(JPAEditorMessages.JPAEditorToolBehaviorProvider_refactorAttributeType);

		workbenchBot
				.waitUntil(
						shellIsActive(JPAEditorMessages.SelectTypeDialog_chooseAttributeTypeDialogWindowTitle),
						10000);
		SWTBotShell changeTypeDialog = workbenchBot
				.shell(JPAEditorMessages.SelectTypeDialog_chooseAttributeTypeDialogWindowTitle);
		getNewTypeInputField(changeTypeDialog);
		return changeTypeDialog;
	}

	/**
	 * Gets the text input field of the "Select Type" dialog, which appears when
	 * the attribute's context menu "Refcator Attribute Type..." is selected
	 * 
	 * @param changeTypeDialog
	 *            - the "Select Type" dialog
	 * @return the text input field
	 */
	public SWTBotText getNewTypeInputField(SWTBotShell changeTypeDialog) {
		SWTBotText attributeType = changeTypeDialog.bot().textWithLabel(
				JPAEditorMessages.SelectTypeDialog_typeLabel);
		assertEquals("java.lang.String", attributeType.getText());
		assertTrue(getOkButton(changeTypeDialog).isEnabled());
		assertTrue(getCancelButton(changeTypeDialog).isEnabled());
		return attributeType;
	}

	/**
	 * Gets the current attribute type value
	 * 
	 * @param attributeName
	 * @param fp
	 * @return the value of the attribute's type
	 */
	public String getAttributeType(String attributeName,
			final IFeatureProvider fp) {
		SWTBotGefEditPart attribute = jpaDiagramEditor
				.getEditPart(attributeName);
		PictogramElement el = (PictogramElement) attribute.part().getModel();
		Object bo = fp.getBusinessObjectForPictogramElement(el);
		assertTrue("The selected element is not an attribute!",
				(bo instanceof JavaPersistentAttribute));
		String currentAttributeType = JPAEditorUtil
				.getAttributeTypeName((JavaPersistentAttribute) bo);
		return currentAttributeType;
	}

	/**
	 * Adds a new attribute to the entity and checks that: 1. The newly created
	 * attribute is selected 2. The "Other Attributes" section is visible
	 * 
	 * @param attributeName
	 *            - the name of the attribute
	 * @return the newly added attribute
	 */
	public SWTBotGefEditPart addAttributeToJPT(SWTBotGefEditPart jptType,
			String attributeName) {

		JavaPersistentType jpt = getJPTObjectForGefElement(jptType);

		System.out.println(">>>>>> Attribute is trying to be added in "
				+ jpt.getName());

		pressEntityContextButton(
				jptType,
				JPAEditorMessages.JPAEditorToolBehaviorProvider_createAttributeButtonlabel);

		bot.waitUntil(new ElementIsShown(jpaDiagramEditor, attributeName),
				10000);
		List<SWTBotGefEditPart> editParts = new ArrayList<SWTBotGefEditPart>();
		editParts.add(jptType);
		SWTBotGefEditPart attribute = jpaDiagramEditor.getEditpart(
				attributeName, editParts);
		assertNotNull("Atrribute is not added.", attribute);

		System.out.println(">>>>>> Attribute is successfully added in "
				+ jpt.getName());

		assertTrue("The newly added attribute must be selected.",
				jpaDiagramEditor.selectedEditParts().size() == 1);
		// assertTrue("The newly added attribute must be selected.",
		// jpaDiagramEditor.selectedEditParts().contains(attribute));

		assertTrue(
				"\"Other Attributes\" section must be visible!",
				isSectionVisible(
						JPAEditorMessages.AddJPAEntityFeature_basicAttributesShapes,
						jptType));

		return attribute;
	}

	public SWTBotGefEditPart addElementCollectionAttributeToJPT(
			SWTBotGefEditPart jptType, String attributeName) {
		pressEntityContextButton(
				jptType,
				JPAEditorMessages.JPAEditorToolBehaviorProvider_CreateElementCollectionAttributeButtonLabel);

		bot.waitUntil(new ElementIsShown(jpaDiagramEditor, attributeName),
				10000);
		List<SWTBotGefEditPart> editParts = new ArrayList<SWTBotGefEditPart>();
		editParts.add(jptType);
		SWTBotGefEditPart attribute = jpaDiagramEditor.getEditpart(
				attributeName, editParts);
		assertNotNull("Atrribute is not added.", attribute);

		assertTrue("The newly added attribute must be selected.",
				jpaDiagramEditor.selectedEditParts().size() == 1);
		assertTrue("The newly added attribute must be selected.",
				jpaDiagramEditor.selectedEditParts().contains(attribute));

		assertTrue(
				"\"Other Attributes\" section must be visible!",
				isSectionVisible(
						JPAEditorMessages.AddJPAEntityFeature_basicAttributesShapes,
						jptType));

		JavaPersistentAttribute jpa = getJPAObjectForGefElement(attribute);
		assertEquals(
				"The newly added attribute must be mapped as element-collection.",
				MappingKeys2_0.ELEMENT_COLLECTION_ATTRIBUTE_MAPPING_KEY,
				jpa.getMappingKey());

		return attribute;
	}

	/**
	 * Checks whether a section with the specified name is visible
	 * 
	 * @param sectionTitle
	 *            - the name of the section
	 * @return true, if the section with the specified name is visible, false
	 *         otherwise
	 */
	public boolean isSectionVisible(String sectionTitle,
			SWTBotGefEditPart editPart) {
		List<SWTBotGefEditPart> editParts = new ArrayList<SWTBotGefEditPart>();
		editParts.add(editPart);
		SWTBotGefEditPart section = jpaDiagramEditor.getEditpart(sectionTitle,
				editParts);
		((PictogramElement) section.part().getModel()).isVisible();
		IFigure figure = ((GraphicalEditPart) section.part()).getFigure();
		return figure.isVisible();
	}

	/**
	 * Adds an entity to the diagram
	 * 
	 * @param entityName
	 *            - the name of the entity to be added
	 * @return the added entity
	 */
	public SWTBotGefEditPart addEntityToDiagram(int x, int y, String entityName) {
		jpaDiagramEditor
				.activateTool(JPAEditorMessages.CreateJPAEntityFeature_jpaEntityFeatureName);
		jpaDiagramEditor.doubleClick(x, y);

		try {
			bot.waitUntil(new ElementIsShown(jpaDiagramEditor, entityName),
					30000);
		} catch (TimeoutException e) {
			jpaDiagramEditor.activateDefaultTool();

			jpaDiagramEditor
					.activateTool(JPAEditorMessages.CreateJPAEntityFeature_jpaEntityFeatureName);
			jpaDiagramEditor.doubleClick(x, y);

			bot.waitUntil(new ElementIsShown(jpaDiagramEditor, entityName),
					30000);
		}

		List<SWTBotGefEditPart> entities = jpaDiagramEditor.mainEditPart()
				.children();
		assertFalse("Editor must contains at least one entity!",
				entities.isEmpty());

		SWTBotGefEditPart entity = jpaDiagramEditor.getEditPart(entityName);
		assertNotNull("Entity is not added!", entity);

		SWTBotGefEditPart idAttribute = jpaDiagramEditor.getEditPart("id");
		assertNotNull("Entity must have a primary key attribute!", idAttribute);

		assertTrue(
				"\"Primary Key\" section must be visible!",
				isSectionVisible(
						JPAEditorMessages.AddJPAEntityFeature_primaryKeysShape,
						entity));
		assertFalse(
				"\"Relation Attributes\" section must not be visible!",
				isSectionVisible(
						JPAEditorMessages.AddJPAEntityFeature_relationAttributesShapes,
						entity));
		assertFalse(
				"\"Other Attributes\" section must not be visible!",
				isSectionVisible(
						JPAEditorMessages.AddJPAEntityFeature_basicAttributesShapes,
						entity));

		return entity;
	}

	/**
	 * Adds mapped superclass to the diagram
	 * 
	 * @param entityName
	 *            - the name of the mapped superclass to be added
	 * @return the added mapped superclass
	 */
	public SWTBotGefEditPart addMappedSuperclassToDiagram(int x, int y,
			String entityName) {
		jpaDiagramEditor
				.activateTool(JPAEditorMessages.CreateMappedSuperclassFeature_createMappedSuperclassFeatureName);
		jpaDiagramEditor.doubleClick(x, y);

		try {
			bot.waitUntil(new ElementIsShown(jpaDiagramEditor, entityName),
					30000);
		} catch (TimeoutException e) {
			jpaDiagramEditor.activateDefaultTool();

			jpaDiagramEditor
					.activateTool(JPAEditorMessages.CreateMappedSuperclassFeature_createMappedSuperclassFeatureName);
			jpaDiagramEditor.doubleClick(x, y);

			bot.waitUntil(new ElementIsShown(jpaDiagramEditor, entityName),
					30000);
		}

		List<SWTBotGefEditPart> entities = jpaDiagramEditor.mainEditPart()
				.children();
		assertFalse("Editor must contains at least one mapped superclass!",
				entities.isEmpty());

		SWTBotGefEditPart mappedSuperclass = jpaDiagramEditor
				.getEditPart(entityName);
		assertNotNull("Mapped superclass is not added!", mappedSuperclass);

		List<SWTBotGefEditPart> parts = new ArrayList<SWTBotGefEditPart>();
		parts.add(mappedSuperclass);

		SWTBotGefEditPart idAttribute = jpaDiagramEditor.getEditpart("id",
				parts);
		assertNull("Mapped superclass must not have a primary key attribute!",
				idAttribute);

		assertFalse(
				"\"Primary Key\" section must not be visible!",
				isSectionVisible(
						JPAEditorMessages.AddJPAEntityFeature_primaryKeysShape,
						mappedSuperclass));
		assertFalse(
				"\"Relation Attributes\" section must not be visible!",
				isSectionVisible(
						JPAEditorMessages.AddJPAEntityFeature_relationAttributesShapes,
						mappedSuperclass));
		assertFalse(
				"\"Other Attributes\" section must not be visible!",
				isSectionVisible(
						JPAEditorMessages.AddJPAEntityFeature_basicAttributesShapes,
						mappedSuperclass));

		return mappedSuperclass;
	}

	/**
	 * Adds mapped superclass to the diagram
	 * 
	 * @param entityName
	 *            - the name of the mapped superclass to be added
	 * @return the added mapped superclass
	 */
	public SWTBotGefEditPart addEmbeddableToDiagram(int x, int y,
			String entityName) {
		jpaDiagramEditor
				.activateTool(JPAEditorMessages.CreateEmbeddableFeature_EmbeddableFeatureName);
		jpaDiagramEditor.doubleClick(x, y);

		try {
			bot.waitUntil(new ElementIsShown(jpaDiagramEditor, entityName),
					30000);
		} catch (TimeoutException e) {
			jpaDiagramEditor.activateDefaultTool();

			jpaDiagramEditor
					.activateTool(JPAEditorMessages.CreateEmbeddableFeature_EmbeddableFeatureName);
			jpaDiagramEditor.doubleClick(x, y);

			bot.waitUntil(new ElementIsShown(jpaDiagramEditor, entityName),
					30000);
		}

		List<SWTBotGefEditPart> entities = jpaDiagramEditor.mainEditPart()
				.children();
		assertFalse("Editor must contains at least one embeddable!",
				entities.isEmpty());

		SWTBotGefEditPart embeddable = jpaDiagramEditor.getEditPart(entityName);
		assertNotNull("Embeddable is not added!", embeddable);

		List<SWTBotGefEditPart> editParts = new ArrayList<SWTBotGefEditPart>();
		editParts.add(embeddable);
		SWTBotGefEditPart idAttribute = jpaDiagramEditor.getEditpart("id",
				editParts);
		assertNull("Embeddablemust not have a primary key attribute!",
				idAttribute);

		assertFalse(
				"\"Primary Key\" section must not be visible!",
				isSectionVisible(
						JPAEditorMessages.AddJPAEntityFeature_primaryKeysShape,
						embeddable));
		assertFalse(
				"\"Relation Attributes\" section must not be visible!",
				isSectionVisible(
						JPAEditorMessages.AddJPAEntityFeature_relationAttributesShapes,
						embeddable));
		assertFalse(
				"\"Other Attributes\" section must not be visible!",
				isSectionVisible(
						JPAEditorMessages.AddJPAEntityFeature_basicAttributesShapes,
						embeddable));

		return embeddable;
	}

	/**
	 * Pressing the "Yes" button of the "Confirm Delete" question dialog.
	 */
	public void confirmDelete() {
		SWTBotShell shell = getDeleteEntityDialog();
		shell.bot().button("Yes").click();
	}

	/**
	 * Pressing the "No" button of the "Confirm Delete" question dialog.
	 */
	public void denyDelete() {
		SWTBotShell shell = getDeleteEntityDialog();
		shell.bot().button("No").click();
	}

	/**
	 * Gets the dialog that appears after the "Delete" context button/menu is
	 * pressed.
	 * 
	 * @return the question dialog, asking whether to the delete the selected
	 *         entity
	 */
	public SWTBotShell getDeleteEntityDialog() {
		workbenchBot.waitUntil(
				shellIsActive(JPAEditorMessages.DeleteFeature_deleteConfirm),
				10000);
		SWTBotShell shell = workbenchBot
				.shell(JPAEditorMessages.DeleteFeature_deleteConfirm);
		return shell;
	}

	/**
	 * Gets the dialog that appears after the
	 * "Refactor Entity Class -> Rename..." context menu is pressed.
	 * 
	 * @return the "Rename Compilation Unit" dialog
	 */
	public SWTBotShell getRenameEntityDialog() {
		workbenchBot.waitUntil(shellIsActive("Rename Compilation Unit"), 10000);
		SWTBotShell shell = workbenchBot.shell("Rename Compilation Unit");
		assertFalse(getFinishButton(shell).isEnabled());
		assertTrue(getCancelButton(shell).isEnabled());
		return shell;
	}

	/**
	 * Gets the dialog that appears after the "Refactor Entity Class -> Move..."
	 * context menu is pressed.
	 * 
	 * @return the "Move" dialog
	 */
	public SWTBotShell getMoveEntityDialog() {
		workbenchBot.waitUntil(shellIsActive("Move"), 10000);
		SWTBotShell shell = workbenchBot.shell("Move");
		assertFalse(getOkButton(shell).isEnabled());
		assertTrue(getCancelButton(shell).isEnabled());
		return shell;
	}

	/**
	 * Gets the dialog that appears after the
	 * "Remove All Entities from Diagram -> ...and Save/Discard Changes" context
	 * menu is pressed. Press the OK button.
	 */
	public void confirmRemoveEntitiesFromDiagramDialog() {
		workbenchBot
				.waitUntil(
						shellIsActive(JPAEditorMessages.JPAEditorToolBehaviorProvider_removeAllEntitiesMenu),
						10000);
		SWTBotShell shell = workbenchBot
				.shell(JPAEditorMessages.JPAEditorToolBehaviorProvider_removeAllEntitiesMenu);
		assertTrue("Ok button is disabled", getOkButton(shell).isEnabled());
		assertTrue(getCancelButton(shell).isEnabled());
		getOkButton(shell).click();
	}

	/**
	 * Deletes an entity with the specified name using the context button.
	 * 
	 * @param entityName
	 *            - the name of the entity to be deleted
	 */
	public void deleteDiagramElements() {

		jpaDiagramEditor.save();

		List<SWTBotGefEditPart> entitiesInDiagram = jpaDiagramEditor
				.mainEditPart().children();
		// assertFalse("Diagram must contain at least one entity!",
		// entitiesInDiagram.isEmpty());

		for (int i = 0; i < entitiesInDiagram.size(); i++) {
			SWTBotGefEditPart editPart = entitiesInDiagram.get(i);
			assertNotNull(editPart);
			JavaPersistentType type = getJPTObjectForGefElement(editPart);
			if (type != null) {
				editPart.select();
				jpaDiagramEditor.clickContextMenu("Delete");
				confirmDelete();
			}
		}

		waitASecond();
		entitiesInDiagram = jpaDiagramEditor.mainEditPart().children();
		assertTrue("Diagram must be empty!", entitiesInDiagram.isEmpty());
		// assertTrue("Editor must be dirty!", jpaDiagramEditor.isDirty());
	}

	public void deleteAttributeInJPT(SWTBotGefEditPart jpt, String attributeName) {

		waitASecond();
		jpaDiagramEditor.activateDefaultTool();

		List<SWTBotGefEditPart> jptParts = new ArrayList<SWTBotGefEditPart>();
		jptParts.add(jpt);
		SWTBotGefEditPart attribute = jpaDiagramEditor.getEditpart(
				attributeName, jptParts);
		attribute.select();
		attribute.click();
		jpaDiagramEditor.clickContextMenu("Delete");
		confirmDelete();
		bot.waitUntil(new ElementDisappears(jpaDiagramEditor, jpt,
				attributeName), 10000);
	}

	/**
	 * Press some of the entity's context buttons
	 * 
	 * @param jpaDiagramEditor
	 * @param contextButtonName
	 *            - the name of the button to be pressed
	 */
	public void pressEntityContextButton(SWTBotGefEditPart part,
			String contextButtonName) {
		pressContextButton(part, contextButtonName);
	}

	/**
	 * Press the "Delete Attribute" attribute's context button
	 * 
	 */
	public void pressAttributeDeleteContextButton(SWTBotGefEditPart part) {
		pressContextButton(
				part,
				JPAEditorMessages.JPAEditorToolBehaviorProvider_deleteAttributeButtonlabel);
	}

	/**
	 * Assert that the context button pad is shown, when the mouse is placed
	 * over the entity and press the the desired button
	 * 
	 * @param contextButtonName
	 *            - the name of the button to be pressed.
	 */
	private void pressContextButton(SWTBotGefEditPart part,
			String contextButtonName) {
		jpaDiagramEditor.click(0, 0);
		jpaDiagramEditor.click(part);

		ContextButtonPad pad = findContextButtonPad();
		assertNotNull(pad);
		for (final Object button : pad.getChildren()) {
			if (((ContextButton) button).getEntry().getText()
					.equals(contextButtonName)) {
				asyncExec(new VoidResult() {
					public void run() {
						((ContextButton) button).doClick();

					}
				});
			}
		}
	}

	/**
	 * Place the mouse over the entity to show the context button pad.
	 * 
	 */
	public void moveMouse(final int x, final int y) {
		syncExec(new VoidResult() {
			public void run() {
				Robot r;
				try {
					r = new Robot();
					Point p = getOrigin();
					r.mouseMove(p.x + x, p.y + y);
				} catch (AWTException e) {
					fail(e.getMessage());
				}
			}
		});
	}

	/**
	 * Gets the context button pad, after placing the mouse over the entity
	 * 
	 * @return the entity's context button pad
	 */
	@SuppressWarnings("restriction")
	private ContextButtonPad findContextButtonPad() {
		SWTBotGefEditPart rootEditPart = jpaDiagramEditor.rootEditPart();
		IFigure feedbackLayer = ((ScalableFreeformRootEditPart) rootEditPart
				.part()).getLayer(LayerConstants.HANDLE_LAYER);
		ContextButtonPad cbp = null;
		for (Object obj : feedbackLayer.getChildren()) {
			if (obj instanceof ContextButtonPad) {
				cbp = (ContextButtonPad) obj;
				break;
			}
		}
		return cbp;
	}

	private FigureCanvas getCanvas() {
		IEditorReference reference = jpaDiagramEditor.getReference();
		final IEditorPart editor = reference.getEditor(true);
		GraphicalViewer graphicalViewer = (GraphicalViewer) editor
				.getAdapter(GraphicalViewer.class);
		final Control control = graphicalViewer.getControl();
		if (control instanceof FigureCanvas) {
			FigureCanvas c = (FigureCanvas) control;
			return c;
		}
		return null;
	}

	private Point getOrigin() {
		Canvas c = getCanvas();
		Point p = c.toDisplay(0, 0);
		return p;
	}

	/**
	 * Get the error message that appears in the "Select Type" dialog
	 * 
	 * @param dialog
	 * @return the error message
	 */
	public SWTBotText getDialogErroMessage(SWTBotShell dialog) {
		return dialog.bot().text(1);
	}

	/**
	 * Gets the "OK" button of a dialog
	 * 
	 * @param dialog
	 * @return the "OK" button
	 */
	public SWTBotButton getOkButton(SWTBotShell dialog) {
		return dialog.bot().button(IDialogConstants.OK_LABEL);
	}

	/**
	 * Gets the "Cancel" button of a dialog
	 * 
	 * @param dialog
	 * @return the "Cancel" button
	 */
	public SWTBotButton getCancelButton(SWTBotShell dialog) {
		return dialog.bot().button(IDialogConstants.CANCEL_LABEL);
	}

	/**
	 * Gets the "Finish" button of a dialog
	 * 
	 * @param dialog
	 * @return the "Finish" button
	 */
	public SWTBotButton getFinishButton(SWTBotShell dialog) {
		return dialog.bot().button("Finish");
	}

	/**
	 * Find the IRelation object for the given GEF Connection
	 * 
	 * @param gefConn
	 * @return the IRelation object for the given GEF Connection
	 */
	@SuppressWarnings("restriction")
	public IRelation getConnection(SWTBotGefConnectionEditPart gefConn) {
		IFeatureProvider fp = ((DiagramEditPart) jpaDiagramEditor
				.mainEditPart().part()).getFeatureProvider();
		FreeFormConnection conn = (FreeFormConnection) gefConn.part()
				.getModel();
		Object ob = fp.getBusinessObjectForPictogramElement(conn);
		if (ob instanceof IRelation) {
			return (IRelation) ob;
		}

		return null;
	}

	/**
	 * Find the IRelation object for the given GEF Connection
	 * 
	 * @param gefConn
	 * @return the IRelation object for the given GEF Connection
	 */
	@SuppressWarnings("restriction")
	public HasReferanceRelation getHasReferenceConnection(
			SWTBotGefConnectionEditPart gefConn) {
		IFeatureProvider fp = ((DiagramEditPart) jpaDiagramEditor
				.mainEditPart().part()).getFeatureProvider();
		FreeFormConnection conn = (FreeFormConnection) gefConn.part()
				.getModel();
		assertNotNull("Relation is not created.", conn);

		Object ob = fp.getBusinessObjectForPictogramElement(conn);

		assertNotNull("Such a relation must exists.", ob);
		if (ob instanceof HasReferanceRelation) {
			return (HasReferanceRelation) ob;
		}

		return null;
	}

	/**
	 * Gets the business object (JavaPersistentType) for the given GEF element
	 * 
	 * @param element
	 * @return the java persistent type for the given element, null if the
	 *         selected element is not an entity
	 */
	public JavaPersistentType getJPTObjectForGefElement(
			SWTBotGefEditPart element) {
		final IFeatureProvider fp = ((DiagramEditPart) jpaDiagramEditor
				.mainEditPart().part()).getFeatureProvider();
		PictogramElement el = (PictogramElement) element.part().getModel();
		Object bo = fp.getBusinessObjectForPictogramElement(el);
		if (bo instanceof JavaPersistentType) {
			return (JavaPersistentType) bo;
		}
		return null;
	}

	public JavaPersistentAttribute getJPAObjectForGefElement(
			SWTBotGefEditPart element) {
		final IFeatureProvider fp = ((DiagramEditPart) jpaDiagramEditor
				.mainEditPart().part()).getFeatureProvider();
		PictogramElement el = (PictogramElement) element.part().getModel();
		Object bo = fp.getBusinessObjectForPictogramElement(el);
		if (bo instanceof JavaPersistentAttribute) {
			return (JavaPersistentAttribute) bo;
		}
		return null;
	}

	/**
	 * Gets the existing isARelation
	 * 
	 * @return the existing isArelation if exists, null otherwise
	 */
	@SuppressWarnings("restriction")
	public IsARelation getIsARelationship() {
		IJPAEditorFeatureProvider fp = (IJPAEditorFeatureProvider) ((DiagramEditPart) jpaDiagramEditor
				.mainEditPart().part()).getFeatureProvider();
		Set<IsARelation> isARelationships = fp.getAllExistingIsARelations();
		assertFalse(isARelationships.isEmpty());
		assertEquals(1, isARelationships.size());
		IsARelation relation = isARelationships.iterator().next();
		return relation;
	}

	/**
	 * CHecks whether the Entity contains unsaved changes.
	 * 
	 * @param element
	 * @return true if the entity contains unsaved changes, false otherwise
	 */
	@SuppressWarnings("restriction")
	public boolean isJPTDirty(SWTBotGefEditPart element) {
		final IFeatureProvider fp = ((DiagramEditPart) jpaDiagramEditor
				.mainEditPart().part()).getFeatureProvider();
		PictogramElement el = (PictogramElement) element.part().getModel();
		Object bo = fp.getBusinessObjectForPictogramElement(el);
		IResource res = null;
		if (bo instanceof JavaPersistentAttribute) {
			res = ((JavaPersistentAttribute) bo).getResource();
		} else if (bo instanceof JavaPersistentType) {
			res = ((JavaPersistentType) bo).getResource();
		}

		if (res != null) {
			ICompilationUnit unit = JPAEditorUtil
					.getCompilationUnit((IFile) res);
			try {
				return unit.hasUnsavedChanges();
			} catch (JavaModelException e) {
				e.printStackTrace();
			}
		}

		return false;
	}

	/**
	 * Select the bidirectional relation and call its "Delete" context menu. On
	 * the confirmation dialog press "No" and assert that the connection and the
	 * relative relation attributes still exist and the "Relation Attributes"
	 * sections of the entities' are visible.
	 * 
	 * @param entity1
	 * @param entity2
	 * @param connection
	 * @param ownerAttributeName
	 * @param inverseAttributeName
	 */
	public void assertBiDirRelationIsNotDeleted(SWTBotGefEditPart entity1,
			SWTBotGefEditPart entity2, SWTBotGefConnectionEditPart connection,
			String ownerAttributeName, String inverseAttributeName) {
		connection.select();
		jpaDiagramEditor.clickContextMenu("Delete");
		denyDelete();
		assertFalse(entity1.sourceConnections().isEmpty());
		assertFalse(entity2.targetConnections().isEmpty());
		connection = entity1.sourceConnections().get(0);
		assertNotNull("Attribute must not be deleted!", connection);
		assertNotNull(jpaDiagramEditor.getEditPart(ownerAttributeName));
		assertNotNull(jpaDiagramEditor.getEditPart(inverseAttributeName));
		assertTrue(
				"\"Relation Attributes\" section of the owner entity must be visible!",
				isSectionVisible(
						entity1,
						JPAEditorMessages.AddJPAEntityFeature_relationAttributesShapes));
		assertTrue(
				"\"Relation Attributes\" section of the inverse entity must be visible!",
				isSectionVisible(
						entity2,
						JPAEditorMessages.AddJPAEntityFeature_relationAttributesShapes));
	}

	/**
	 * Select the bidirectional self relation and call its "Delete" context
	 * menu. On the confirmation dialog press "No" and assert that the
	 * connection and the relative relation attributes still exist and the
	 * "Relation Attributes" sections of the entities' are visible.
	 * 
	 * @param entity1
	 * @param connection
	 * @param ownerAttributeName
	 * @param inverseAttributeName
	 */
	public void assertSelfBiDirRelationIsNotDeleted(SWTBotGefEditPart entity1,
			SWTBotGefConnectionEditPart connection, String ownerAttributeName,
			String inverseAttributeName) {
		connection.select();
		jpaDiagramEditor.clickContextMenu("Delete");
		denyDelete();
		assertFalse(entity1.sourceConnections().isEmpty());
		assertFalse(entity1.targetConnections().isEmpty());
		connection = entity1.sourceConnections().get(0);
		assertNotNull("Attribute must not be deleted!", connection);
		assertNotNull(jpaDiagramEditor.getEditPart(ownerAttributeName));
		assertNotNull(jpaDiagramEditor.getEditPart(inverseAttributeName));
		assertTrue(
				"\"Relation Attributes\" section of the owner entity must be visible!",
				isSectionVisible(
						entity1,
						JPAEditorMessages.AddJPAEntityFeature_relationAttributesShapes));
	}

	/**
	 * Select the unidirectional relation and call its "Delete" context menu. On
	 * the confirmation dialog press "No" and assert that the connection and the
	 * relative relation attributes still exist and the "Relation Attributes"
	 * sections of the entities' are visible.
	 * 
	 * @param entity1
	 * @param entity2
	 * @param connection
	 * @param ownerAttributeName
	 * @param inverseAttributeName
	 */
	public void assertUniDirRelationIsNotDeleted(SWTBotGefEditPart entity1,
			SWTBotGefEditPart entity2, SWTBotGefConnectionEditPart connection,
			String attributeName) {
		connection.select();
		jpaDiagramEditor.clickContextMenu("Delete");
		denyDelete();
		assertFalse(entity1.sourceConnections().isEmpty());
		assertFalse(entity2.targetConnections().isEmpty());
		connection = entity1.sourceConnections().get(0);
		assertNotNull("Attribute must not be deleted!", connection);
		assertNotNull(jpaDiagramEditor.getEditPart(attributeName));
		assertTrue(
				"\"Relation Attributes\" section of the owner entity must be visible!",
				isSectionVisible(
						entity1,
						JPAEditorMessages.AddJPAEntityFeature_relationAttributesShapes));
		assertFalse(
				"\"Relation Attributes\" section of the inverse entity must not be visible!",
				isSectionVisible(
						entity2,
						JPAEditorMessages.AddJPAEntityFeature_relationAttributesShapes));
	}

	/**
	 * Select the unidirectional self relation and call its "Delete" context
	 * menu. On the confirmation dialog press "No" and assert that the
	 * connection and the relative relation attributes still exist and the
	 * "Relation Attributes" sections of the entities' are visible.
	 * 
	 * @param entity1
	 * @param connection
	 * @param ownerAttributeName
	 * @param inverseAttributeName
	 */
	public void assertSelfUniDirRelationIsNotDeleted(SWTBotGefEditPart entity1,
			SWTBotGefConnectionEditPart connection, String attributeName) {
		connection.select();
		jpaDiagramEditor.clickContextMenu("Delete");
		denyDelete();
		assertFalse(entity1.sourceConnections().isEmpty());
		assertFalse(entity1.targetConnections().isEmpty());
		connection = entity1.sourceConnections().get(0);
		assertNotNull("Attribute must not be deleted!", connection);
		assertNotNull(jpaDiagramEditor.getEditPart(attributeName));
		assertTrue(
				"\"Relation Attributes\" section of the owner entity must be visible!",
				isSectionVisible(
						entity1,
						JPAEditorMessages.AddJPAEntityFeature_relationAttributesShapes));
	}

	/**
	 * Select the bidirectional relation and call its "Delete" context menu. On
	 * the confirmation dialog press "Yes" and assert that the connection and
	 * the relative relation attributes do not exist anymore and the
	 * "Relation Attributes" sections of the entities' are not visible.
	 * 
	 * @param entity1
	 * @param entity2
	 * @param connection
	 * @param ownerAttributeName
	 * @param inverseAttributeName
	 */
	public void assertBiDirRelationIsDeleted(SWTBotGefEditPart entity1,
			SWTBotGefEditPart entity2, SWTBotGefConnectionEditPart connection,
			String ownerAttributeName, String inverseAttributeName) {
		connection.select();
		jpaDiagramEditor.clickContextMenu("Delete");
		confirmDelete();
		bot.waitUntil(new ElementDisappears(jpaDiagramEditor,
				ownerAttributeName), 10000);
		assertTrue(entity1.sourceConnections().isEmpty());
		assertTrue(entity2.targetConnections().isEmpty());
		assertNull(jpaDiagramEditor.getEditPart(ownerAttributeName));
		assertNull(jpaDiagramEditor.getEditPart(inverseAttributeName));

		assertFalse(
				"\"Relation Attributes\" section of the owner entity must not be visible!",
				isSectionVisible(
						entity1,
						JPAEditorMessages.AddJPAEntityFeature_relationAttributesShapes));
		assertFalse(
				"\"Relation Attributes\" section of the inverse entity must not be visible!",
				isSectionVisible(
						entity2,
						JPAEditorMessages.AddJPAEntityFeature_relationAttributesShapes));
	}

	/**
	 * Select the bidirectional self relation and call its "Delete" context
	 * menu. On the confirmation dialog press "Yes" and assert that the
	 * connection and the relative relation attributes do not exist anymore and
	 * the "Relation Attributes" sections of the entities' are not visible.
	 * 
	 * @param entity1
	 * @param connection
	 * @param ownerAttributeName
	 * @param inverseAttributeName
	 */
	public void assertSelfBiDirRelationIsDeleted(SWTBotGefEditPart entity1,
			SWTBotGefConnectionEditPart connection, String ownerAttributeName,
			String inverseAttributeName) {
		connection.select();
		jpaDiagramEditor.clickContextMenu("Delete");
		confirmDelete();
		bot.waitUntil(new ElementDisappears(jpaDiagramEditor,
				ownerAttributeName), 10000);
		assertTrue(entity1.sourceConnections().isEmpty());
		assertTrue(entity1.targetConnections().isEmpty());
		assertNull(jpaDiagramEditor.getEditPart(ownerAttributeName));
		assertNull(jpaDiagramEditor.getEditPart(inverseAttributeName));
		assertFalse(
				"\"Relation Attributes\" section of the owner entity must not be visible!",
				isSectionVisible(
						entity1,
						JPAEditorMessages.AddJPAEntityFeature_relationAttributesShapes));
	}

	/**
	 * Select the unidirectional relation and call its "Delete" context menu. On
	 * the confirmation dialog press "Yes" and assert that the connection and
	 * the relative relation attributes do not exist anymore and the
	 * "Relation Attributes" sections of the entities' are not visible.
	 * 
	 * @param entity1
	 * @param entity2
	 * @param connection
	 * @param ownerAttributeName
	 * @param inverseAttributeName
	 */
	public void assertUniDirRelationIsDeleted(SWTBotGefEditPart entity1,
			SWTBotGefEditPart entity2, SWTBotGefConnectionEditPart connection,
			String attributeName) {
		connection.select();
		jpaDiagramEditor.clickContextMenu("Delete");
		confirmDelete();
		bot.waitUntil(new ElementDisappears(jpaDiagramEditor, attributeName),
				10000);
		assertTrue(entity1.sourceConnections().isEmpty());
		assertTrue(entity2.targetConnections().isEmpty());
		assertNull(jpaDiagramEditor.getEditPart(attributeName));
		assertFalse(
				"\"Relation Attributes\" section of the owner entity must not be visible!",
				isSectionVisible(
						entity1,
						JPAEditorMessages.AddJPAEntityFeature_relationAttributesShapes));
		assertFalse(
				"\"Relation Attributes\" section of the inverse entity must not be visible!",
				isSectionVisible(
						entity2,
						JPAEditorMessages.AddJPAEntityFeature_relationAttributesShapes));
	}

	/**
	 * Select the unidirectional self relation and call its "Delete" context
	 * menu. On the confirmation dialog press "Yes" and assert that the
	 * connection and the relative relation attributes do not exist anymore and
	 * the "Relation Attributes" sections of the entities' are not visible.
	 * 
	 * @param entity1
	 * @param connection
	 * @param ownerAttributeName
	 * @param inverseAttributeName
	 */
	public void assertSelfUniDirRelationIsDeleted(SWTBotGefEditPart entity1,
			SWTBotGefConnectionEditPart connection, String attributeName) {
		connection.select();
		jpaDiagramEditor.clickContextMenu("Delete");
		confirmDelete();
		bot.waitUntil(new ElementDisappears(jpaDiagramEditor, attributeName),
				10000);
		assertTrue(entity1.sourceConnections().isEmpty());
		assertTrue(entity1.targetConnections().isEmpty());
		assertNull(jpaDiagramEditor.getEditPart(attributeName));
		assertFalse(
				"\"Relation Attributes\" section of the owner entity must not be visible!",
				isSectionVisible(
						entity1,
						JPAEditorMessages.AddJPAEntityFeature_relationAttributesShapes));
	}

	/**
	 * Assert that there is exactly one GEF element representing the
	 * relationship
	 * 
	 * @param entity1
	 * @param entity2
	 */
	public void assertConnectionIsCreated(SWTBotGefEditPart entity1,
			SWTBotGefEditPart entity2, boolean isBiDIr) {
		// assert that there is exactly one relationship, which start from
		// entity1
		// and that there is no relationship which starts from entity2
		assertFalse(entity1.sourceConnections().isEmpty());
		assertEquals(1, entity1.sourceConnections().size());
		assertTrue(entity2.sourceConnections().isEmpty());

		// assert that there is exactly one relationship which ends in entity2
		// and that there is no relationship which end in entity1.
		assertFalse(entity2.targetConnections().isEmpty());
		assertEquals(1, entity2.targetConnections().size());
		// assertTrue(entity1.targetConnections().isEmpty());

		assertTrue(
				"\"Relation Attributes\" section of the owner entity must be visible!",
				isSectionVisible(
						entity1,
						JPAEditorMessages.AddJPAEntityFeature_relationAttributesShapes));
		if (isBiDIr) {
			assertTrue(
					"\"Relation Attributes\" section of the inverse entity must be visible!",
					isSectionVisible(
							entity2,
							JPAEditorMessages.AddJPAEntityFeature_relationAttributesShapes));
		} else {
			assertFalse(
					"\"Relation Attributes\" section of the inverse entity must not be visible!",
					isSectionVisible(
							entity2,
							JPAEditorMessages.AddJPAEntityFeature_relationAttributesShapes));
		}
	}

	public void assertIsARelationExists(SWTBotGefEditPart entity1,
			SWTBotGefEditPart entity2) {
		// assert that there is exactly one relationship, which start from
		// entity2 and that there is no relationship which starts from entity2
		assertFalse(entity2.sourceConnections().isEmpty());
		assertEquals(1, entity2.sourceConnections().size());
		assertTrue(entity1.sourceConnections().isEmpty());

		// assert that there is exactly one relationship which ends in entity1
		// and that there is no relationship which end in entity2.
		assertFalse(entity1.targetConnections().isEmpty());
		assertEquals(1, entity1.targetConnections().size());
		assertTrue(entity2.targetConnections().isEmpty());
	}

	/**
	 * Assert that there is exactly one GEF element representing the self
	 * relationship
	 * 
	 * @param entity1
	 */
	public void assertSelfConnectionIsCreated(SWTBotGefEditPart entity1) {
		// assert that there is exactly one relationship, which start from
		// entity1
		// and ends in entity2
		assertFalse(entity1.sourceConnections().isEmpty());
		assertEquals(1, entity1.sourceConnections().size());

		assertFalse(entity1.targetConnections().isEmpty());
		assertEquals(1, entity1.targetConnections().size());

		assertTrue(isSectionVisible(entity1,
				JPAEditorMessages.AddJPAEntityFeature_relationAttributesShapes));
	}

	/**
	 * Assert that the owner relationship attribute exists
	 * 
	 * @param rel
	 * @return the name of the owner relationship attribute
	 */
	public String testOwnerRelationAttributeProperties(IRelation rel) {
		JavaPersistentAttribute ownerAttr = rel.getOwnerAnnotatedAttribute();
		String attributeName = rel.getOwnerAttributeName();
		assertNotNull(ownerAttr);
		assertNotNull(jpaDiagramEditor.getEditPart(attributeName));

		return attributeName;
	}

	/**
	 * Assert that the embedded attribute exists
	 * 
	 * @param rel
	 * @return the name of the embedding attribute
	 */
	public String testEmbeddedAttributeProperties(HasReferanceRelation rel,
			String attributeMapping) {
		JavaPersistentAttribute embeddedAttr = rel
				.getEmbeddedAnnotatedAttribute();
		String attributeName = embeddedAttr.getName();
		assertNotNull(embeddedAttr);
		assertNotNull(jpaDiagramEditor.getEditPart(attributeName));
		assertEquals("The attribute must be embedded attribute.",
				embeddedAttr.getMappingKey(), attributeMapping);

		return attributeName;
	}

	/**
	 * Assert that the inverse relationship attribute exists.
	 * 
	 * @param rel
	 * @return the name of the inverse relationship attribute
	 */
	public String testInverseRelationAttributeProperties(IRelation rel) {
		JavaPersistentAttribute inverseAttr = rel
				.getInverseAnnotatedAttribute();
		String inverseAttributeName = rel.getInverseAttributeName();
		assertNotNull(inverseAttr);
		assertNotNull(jpaDiagramEditor.getEditPart(inverseAttributeName));
		return inverseAttributeName;
	}

	/**
	 * Checks whether a section of a particular entity is visible
	 * 
	 * @param editPart
	 *            - the particular entity
	 * @param sectionTitle
	 *            - the title of the section to be checked
	 * @return true, if the sections is visible, false otherwise
	 */
	@SuppressWarnings("deprecation")
	public boolean isSectionVisible(SWTBotGefEditPart editPart,
			String sectionTitle) {
		List<SWTBotGefEditPart> children = editPart.children();
		SWTBotGefEditPart section = jpaDiagramEditor.getEditpart(sectionTitle,
				children);
		((PictogramElement) section.part().getModel()).isVisible();
		IFigure figure = ((GraphicalEditPart) section.part()).getFigure();
		return figure.isVisible() || figure.isShowing();
	}

	public SWTBotGefEditPart getSectionInJPT(SWTBotGefEditPart editPart,
			String sectionTitle) {
		List<SWTBotGefEditPart> children = editPart.children();
		SWTBotGefEditPart section = jpaDiagramEditor.getEditpart(sectionTitle,
				children);
		return section;
	}

	/**
	 * Change the mapping of the type or attribute.
	 * 
	 * @param newMappingType
	 */
	public void changeMappingtype(String newMappingType) {
		workbenchBot.waitUntil(shellIsActive("Mapping Type Selection"), 10000);
		SWTBotShell mappingTypeShell = workbenchBot
				.shell("Mapping Type Selection");
		mappingTypeShell.bot().table().getTableItem(newMappingType).select();
		getOkButton(mappingTypeShell).click();
	}

	/**
	 * Click on the mapping type link in the JPA Details view
	 * 
	 * @param styledText
	 * @param position
	 */
	public void clickOnStyledText(final SWTBotStyledText styledText,
			int position) {
		styledText.navigateTo(new Position(0, position));
		asyncExec(new VoidResult() {
			public void run() {
				styledText.widget.notifyListeners(SWT.MouseDown, new Event());
				styledText.widget.notifyListeners(SWT.MouseUp, new Event());
			}
		});
	}

	public void waitASecond() {
		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Assert that the relation attribute is correctly mapped in the JPA Details
	 * view
	 * 
	 * @param attributeName
	 * @param relationAttributeMapping
	 *            - the expected attribute mapping
	 */
	public void assertAttributeIsCorretlyMapped(String attributeName,
			String relationAttributeMapping) {

		// assert that the JPA Details view is opened
		SWTBotView jpaDetailsView = workbenchBot.viewByTitle("JPA Details");
		jpaDetailsView.setFocus();
		assertTrue("JPA Details view must be opened!",
				jpaDetailsView.isActive());

		SWTBotGefEditPart attribute = jpaDiagramEditor
				.getEditPart(attributeName);
		attribute.select();
		attribute.click();

		// assert that the default entity's attribute is mapped as primary key
		SWTBot jpaDetailsBot = jpaDetailsView.bot();
		SWTBotStyledText styledText = jpaDetailsBot.styledText();
		assertEquals("Attribute '" + attributeName + "' is mapped as "
				+ relationAttributeMapping + ".", styledText.getText());
	}

	/**
	 * Assert that the type is correctly mapped in the JPA Details view
	 * 
	 * @param typeName
	 * @param typeMapping
	 *            - the expected type mapping
	 */
	public void assertTypeIsCorretlyMapped(SWTBotGefEditPart type,
			String typeMapping) {
		// workbenchBot.viewByTitle("JPA Details").close();

		// SWTBotGefEditPart type = jpaDiagramEditor.getEditPart(typeName);

		// JavaPersistentType jpt = getJPTObjectForGefElement(type);
		// assertEquals("Type is not mapped correctly.", jpt.getMappingKey(),
		// typeMapping);

		// type.click();
		//
		// jpaDiagramEditor
		// .clickContextMenu(JPAEditorMessages.JPAEditorToolBehaviorProvider_openJPADetailsView);
		// // assert that the JPA Details view is opened
		// SWTBotView jpaDetailsView = workbenchBot.viewByTitle("JPA Details");
		// assertTrue("JPA Details view must be opened!",
		// jpaDetailsView.isActive());
		//
		// // assert that the default entity's attribute is mapped as the given
		// // mapping key
		// SWTBot jpaDetailsBot = jpaDetailsView.bot();
		// SWTBotStyledText styledText = jpaDetailsBot.styledText();
		// assertEquals("Type '" + typeName + "' is mapped as " + typeMapping
		// + ".", styledText.getText());

		// assert that the JPA Details view is opened
		SWTBotView jpaDetailsView = workbenchBot.viewByTitle("JPA Details");
		jpaDetailsView.setFocus();
		assertTrue("JPA Details view must be opened!",
				jpaDetailsView.isActive());

		// SWTBotGefEditPart type = jpaDiagramEditor.getEditPart(typeName);

		type.select();
		type.click();

		String typeName = getJPTObjectForGefElement(type).getSimpleName();

		// assert that the default entity's attribute is mapped as primary key
		SWTBot jpaDetailsBot = jpaDetailsView.bot();
		SWTBotStyledText styledText = jpaDetailsBot.styledText();
		assertEquals("Type '" + typeName + "' is mapped as " + typeMapping
				+ ".", styledText.getText());
	}

	public void deleteJPTViaButton(SWTBotGefEditPart jptType) {

		String jptName = getJPTObjectForGefElement(jptType).getSimpleName();

		pressEntityContextButton(
				jptType,
				JPAEditorMessages.JPAEditorToolBehaviorProvider_deleteEntityFromModelButtonLabel);
		denyDelete();

		jptType = jpaDiagramEditor.getEditPart(jptName);
		assertNotNull("Entity is deleted!", jptType);

		pressEntityContextButton(
				jptType,
				JPAEditorMessages.JPAEditorToolBehaviorProvider_deleteEntityFromModelButtonLabel);
		confirmDelete();
		bot.waitUntil(new ElementDisappears(jpaDiagramEditor, jptName), 10000);
		jptType = jpaDiagramEditor.getEditPart(jptName);
		assertNull("Entity is not deleted!", jptType);
	}

	public void deleteJPTViaMenu(SWTBotGefEditPart jptType) {

		String jptName = getJPTObjectForGefElement(jptType).getSimpleName();

		jpaDiagramEditor
				.clickContextMenu(JPAEditorMessages.JPAEditorToolBehaviorProvider_deleteEntityFromModelButtonLabel);
		denyDelete();

		jptType = jpaDiagramEditor.getEditPart(jptName);
		assertNotNull("Entity is deleted!", jptType);

		jpaDiagramEditor
				.clickContextMenu(JPAEditorMessages.JPAEditorToolBehaviorProvider_deleteEntityFromModelButtonLabel);
		confirmDelete();
		bot.waitUntil(new ElementDisappears(jpaDiagramEditor, jptName), 10000);
		jptType = jpaDiagramEditor.getEditPart(jptName);
		assertNull("Entity is not deleted!", jptType);
	}

	public void removeAttributeViaButton(SWTBotGefEditPart jptType,
			String attributeName) {

		assertFalse(
				"\"Other Attributes\" section must not be visible!",

				isSectionVisible(
						JPAEditorMessages.AddJPAEntityFeature_basicAttributesShapes,
						jptType));

		SWTBotGefEditPart attribute = addAttributeToJPT(jptType, attributeName);
		assertTrue("Editor must be dirty", jpaDiagramEditor.isDirty());
		jpaDiagramEditor.save();

		pressAttributeDeleteContextButton(attribute);
		denyDelete();
		attribute = jpaDiagramEditor.getEditPart(attributeName);
		assertNotNull("Attribute must not be deleted!", attribute);

		pressAttributeDeleteContextButton(attribute);
		confirmDelete();
		bot.waitUntil(new ElementDisappears(jpaDiagramEditor, attributeName),
				20000);
		attribute = jpaDiagramEditor.getEditPart(attributeName);
		assertNull("Attribute must be deleted!", attribute);

		jpaDiagramEditor.save();
		assertFalse(
				"\"Other Attributes\" section must not be visible!",
				isSectionVisible(
						JPAEditorMessages.AddJPAEntityFeature_basicAttributesShapes,
						jptType));

	}

	public void removeAttributeViaMenu(SWTBotGefEditPart jptType,
			String attributeName) {
		assertFalse(
				"\"Other Attributes\" section must not be visible!",
				isSectionVisible(
						JPAEditorMessages.AddJPAEntityFeature_basicAttributesShapes,
						jptType));

		SWTBotGefEditPart attribute = addAttributeToJPT(jptType, attributeName);
		assertTrue("Editor must be dirty", jpaDiagramEditor.isDirty());
		jpaDiagramEditor.save();

		attribute.click();
		jpaDiagramEditor.clickContextMenu("Delete");
		denyDelete();
		attribute = jpaDiagramEditor.getEditPart(attributeName);
		assertNotNull("Attribute must not be deleted!", attribute);

		attribute.click();
		jpaDiagramEditor.clickContextMenu("Delete");
		confirmDelete();
		bot.waitUntil(new ElementDisappears(jpaDiagramEditor, attributeName),
				20000);
		attribute = jpaDiagramEditor.getEditPart(attributeName);
		assertNull("Attribute must be deleted!", attribute);

		assertFalse(
				"\"Other Attributes\" section must not be visible!",
				isSectionVisible(
						JPAEditorMessages.AddJPAEntityFeature_basicAttributesShapes,
						jptType));
	}

	public void directEditAttribute(SWTBotGefEditPart jptType,
			String attributeName) {

		assertFalse(
				"\"Other Attributes\" section must not be visible!",
				isSectionVisible(
						JPAEditorMessages.AddJPAEntityFeature_basicAttributesShapes,
						jptType));

		SWTBotGefEditPart attribute = addAttributeToJPT(jptType, attributeName);
		assertNotNull("The attribute must not be renamed!", attribute);

		jpaDiagramEditor.directEditType("newAttrName");
		SWTBotGefEditPart oldAttribute = jpaDiagramEditor
				.getEditPart(attributeName);
		SWTBotGefEditPart newAttribute = jpaDiagramEditor
				.getEditPart("newAttrName");
		assertNotNull("The attribute must be renamed!", newAttribute);
		assertNull("The attribute must be renamed!", oldAttribute);
	}

	public void collapseExpandJPTViaButton(SWTBotGefEditPart jptType) {

		int heigth = ((PictogramElement) jptType.part().getModel())
				.getGraphicsAlgorithm().getHeight();

		pressEntityContextButton(jptType, "Collapse");
		waitASecond();

		int newHeight = ((PictogramElement) jptType.part().getModel())
				.getGraphicsAlgorithm().getHeight();
		assertEquals("Entity must be collapsed!",
				JPAEditorConstants.ENTITY_MIN_HEIGHT, newHeight);
		assertTrue(newHeight < heigth);

		pressEntityContextButton(jptType, "Expand");
		waitASecond();

		newHeight = ((PictogramElement) jptType.part().getModel())
				.getGraphicsAlgorithm().getHeight();
		assertEquals("Entity must be expanded!", heigth, newHeight);
		assertTrue(newHeight > JPAEditorConstants.ENTITY_MIN_HEIGHT);
	}

	public void collapseExpandJPTViaMenu(SWTBotGefEditPart jptType) {

		int heigth = ((PictogramElement) jptType.part().getModel())
				.getGraphicsAlgorithm().getHeight();

		jpaDiagramEditor.click(jptType);

		jpaDiagramEditor
				.clickContextMenu(JPAEditorMessages.JPAEditorToolBehaviorProvider_collapseEntityMenuItem);
		waitASecond();

		int newHeight = ((PictogramElement) jptType.part().getModel())
				.getGraphicsAlgorithm().getHeight();
		assertEquals("Entity must be collapsed!",
				JPAEditorConstants.ENTITY_MIN_HEIGHT, newHeight);
		assertTrue(newHeight < heigth);

		jpaDiagramEditor
				.clickContextMenu(JPAEditorMessages.JPAEditorToolBehaviorProvider_expandEntityMenuItem);
		waitASecond();

		newHeight = ((PictogramElement) jptType.part().getModel())
				.getGraphicsAlgorithm().getHeight();
		assertEquals("Entity must be expanded!", heigth, newHeight);
		assertTrue(newHeight > JPAEditorConstants.ENTITY_MIN_HEIGHT);
	}

	public void collapseExpandAllJPTsViaMenu(SWTBotGefEditPart jptType1,
			SWTBotGefEditPart jptType2) {

		int heigth1 = ((PictogramElement) jptType1.part().getModel())
				.getGraphicsAlgorithm().getHeight();

		int heigth2 = ((PictogramElement) jptType2.part().getModel())
				.getGraphicsAlgorithm().getHeight();

		jpaDiagramEditor
				.clickContextMenu(JPAEditorMessages.JPAEditorToolBehaviorProvider_collapseAllEntitiesMenuItem);
		waitASecond();

		// check that entity1 is collapsed
		int newHeight1 = ((PictogramElement) jptType1.part().getModel())
				.getGraphicsAlgorithm().getHeight();
		assertEquals("Entity1 must be collapsed!",
				JPAEditorConstants.ENTITY_MIN_HEIGHT, newHeight1);
		assertTrue(newHeight1 < heigth1);

		// check that entity2 is collapsed
		int newHeight2 = ((PictogramElement) jptType2.part().getModel())
				.getGraphicsAlgorithm().getHeight();
		assertEquals("Entity2 must be collapsed!",
				JPAEditorConstants.ENTITY_MIN_HEIGHT, newHeight2);
		assertTrue(newHeight2 < heigth2);

		jpaDiagramEditor
				.clickContextMenu(JPAEditorMessages.JPAEditorToolBehaviorProvider_expandAllEntitiesMenuItem);
		waitASecond();

		// check that entity1 is expanded
		newHeight1 = ((PictogramElement) jptType1.part().getModel())
				.getGraphicsAlgorithm().getHeight();
		assertEquals("Entity must be expanded!", heigth1, newHeight1);
		assertTrue(newHeight1 > JPAEditorConstants.ENTITY_MIN_HEIGHT);

		// check that entity2 is expanded
		newHeight2 = ((PictogramElement) jptType2.part().getModel())
				.getGraphicsAlgorithm().getHeight();
		assertEquals("Entity must be expanded!", heigth2, newHeight2);
		assertTrue(newHeight2 > JPAEditorConstants.ENTITY_MIN_HEIGHT);
	}

	public void discardChanges(SWTBotGefEditPart jptType, String attributeName) {

		assertFalse(
				"\"Other Attributes\" section must not be visible!",
				isSectionVisible(
						JPAEditorMessages.AddJPAEntityFeature_basicAttributesShapes,
						jptType));
		assertFalse(isJPTDirty(jptType));

		addAttributeToJPT(jptType, attributeName);
		assertTrue("Editor must be dirty", jpaDiagramEditor.isDirty());
		assertTrue(isJPTDirty(jptType));

		jptType.click();
		jpaDiagramEditor
				.clickContextMenu(JPAEditorMessages.JPAEditorToolBehaviorProvider_discardChangesMenuItem);
		SWTBotGefEditPart attribute = jpaDiagramEditor
				.getEditPart(attributeName);
		assertNull("Changes must be discard!", attribute);
		assertFalse(isJPTDirty(jptType));
	}

	public void removeAndDiscardChangesViaMenu(SWTBotGefEditPart jptType,
			String attributeName) {

		String jptName = getJPTObjectForGefElement(jptType).getSimpleName();

		assertFalse("Diagram must contain at least one entity!",
				jpaDiagramEditor.mainEditPart().children().isEmpty());

		assertFalse(
				"\"Other Attributes\" section must not be visible!",
				isSectionVisible(
						JPAEditorMessages.AddJPAEntityFeature_basicAttributesShapes,
						jptType));
		assertFalse(isJPTDirty(jptType));

		addAttributeToJPT(jptType, attributeName);
		assertTrue("Editor must be dirty", jpaDiagramEditor.isDirty());
		assertTrue(isJPTDirty(jptType));

		jptType.click();
		jpaDiagramEditor
				.clickContextMenu(JPAEditorMessages.JPAEditorToolBehaviorProvider_removeAndDiscardAllEntitiesAction);
		confirmRemoveEntitiesFromDiagramDialog();
		assertTrue("Diagram must be empty!", jpaDiagramEditor.mainEditPart()
				.children().isEmpty());

		jpaDiagramEditor
				.clickContextMenu(JPAEditorMessages.JPAEditorToolBehaviorProvider_showAllTheEntities);

		bot.waitUntil(new ElementAppearsInDiagram(jpaDiagramEditor), 20000);

		assertFalse("Diagram must contain at least one entity!",
				jpaDiagramEditor.mainEditPart().children().isEmpty());

		jptType = jpaDiagramEditor.getEditPart(jptName);
		SWTBotGefEditPart attribute = jpaDiagramEditor
				.getEditPart(attributeName);
		assertNull("Changes must be discard!", attribute);
		assertFalse(isJPTDirty(jptType));
	}

	public void removeAndSaveChangesViaMenu(SWTBotGefEditPart jptType,
			String attributeName) {

		assertFalse("Diagram must contain at least one entity!",
				jpaDiagramEditor.mainEditPart().children().isEmpty());

		String jptName = getJPTObjectForGefElement(jptType).getSimpleName();

		assertFalse(
				"\"Other Attributes\" section must not be visible!",
				isSectionVisible(
						JPAEditorMessages.AddJPAEntityFeature_basicAttributesShapes,
						jptType));
		assertFalse(isJPTDirty(jptType));

		addAttributeToJPT(jptType, attributeName);
		assertTrue("Editor must be dirty", jpaDiagramEditor.isDirty());
		assertTrue(isJPTDirty(jptType));

		jptType.click();
		jpaDiagramEditor
				.clickContextMenu(JPAEditorMessages.JPAEditorToolBehaviorProvider_removeAndSaveAllEntitiesAction);
		confirmRemoveEntitiesFromDiagramDialog();
		assertTrue("Diagram must be empty!", jpaDiagramEditor.mainEditPart()
				.children().isEmpty());

		jpaDiagramEditor
				.clickContextMenu(JPAEditorMessages.JPAEditorToolBehaviorProvider_showAllTheEntities);

		bot.waitUntil(new ElementAppearsInDiagram(jpaDiagramEditor), 20000);

		assertFalse("Diagram must contain at least one entity!",
				jpaDiagramEditor.mainEditPart().children().isEmpty());

		jptType = jpaDiagramEditor.getEditPart(jptName);
		SWTBotGefEditPart attribute = jpaDiagramEditor
				.getEditPart(attributeName);
		assertNotNull("Changes must be discard!", attribute);
		assertFalse(isJPTDirty(jptType));
	}

	public void saveOnlyJPT(SWTBotGefEditPart jptType, String attributeName) {

		assertFalse(
				"\"Other Attributes\" section must not be visible!",
				isSectionVisible(
						JPAEditorMessages.AddJPAEntityFeature_basicAttributesShapes,
						jptType));
		assertFalse(isJPTDirty(jptType));

		addAttributeToJPT(jptType, attributeName);
		assertTrue("Editor must be dirty", jpaDiagramEditor.isDirty());
		assertTrue(isJPTDirty(jptType));

		jptType.click();
		jpaDiagramEditor
				.clickContextMenu(JPAEditorMessages.JPAEditorToolBehaviorProvider_saveButtonText);
		assertTrue("Editor must be dirty", jpaDiagramEditor.isDirty());
		assertFalse(isJPTDirty(jptType));
	}

	public void testUniDirRelation(String relationFeatureName,
			SWTBotGefEditPart owner, SWTBotGefEditPart inverse,
			RelType reltype, String linkLabel) {

		jpaDiagramEditor.activateTool(relationFeatureName, 0);

		jpaDiagramEditor.click(owner);
		jpaDiagramEditor.click(inverse);
		bot.waitUntil(new ConnectionIsShown(owner));

		waitASecond();
		jpaDiagramEditor.activateDefaultTool();

		assertConnectionIsCreated(owner, inverse, false);

		SWTBotGefConnectionEditPart connection = owner.sourceConnections().get(
				0);
		IRelation rel = getConnection(connection);
		assertNotNull(rel);
		assertEquals(IRelation.RelDir.UNI, rel.getRelDir());
		assertEquals(reltype, rel.getRelType());

		String attributeName = testOwnerRelationAttributeProperties(rel);
		assertNull(rel.getInverseAnnotatedAttribute());

		assertAttributeIsCorretlyMapped(attributeName, linkLabel);

		assertUniDirRelationIsNotDeleted(owner, inverse, connection,
				attributeName);

		assertUniDirRelationIsDeleted(owner, inverse, connection, attributeName);
	}

	public void testSelfUniDirRelation(String relationFeatureName,
			SWTBotGefEditPart entity, RelType reltype, String linkLabel) {

		jpaDiagramEditor.activateTool(relationFeatureName, 0);
		jpaDiagramEditor.click(entity);
		jpaDiagramEditor.click(entity);
		bot.waitUntil(new ConnectionIsShown(entity));

		waitASecond();
		jpaDiagramEditor.activateDefaultTool();

		assertSelfConnectionIsCreated(entity);

		SWTBotGefConnectionEditPart connection = entity.sourceConnections()
				.get(0);
		IRelation rel = getConnection(connection);
		assertNotNull(rel);
		assertEquals(IRelation.RelDir.UNI, rel.getRelDir());
		assertEquals(reltype, rel.getRelType());

		String attributeName = testOwnerRelationAttributeProperties(rel);
		assertNull(rel.getInverseAnnotatedAttribute());

		assertAttributeIsCorretlyMapped(attributeName, linkLabel);

		assertSelfUniDirRelationIsNotDeleted(entity, connection, attributeName);

		assertSelfUniDirRelationIsDeleted(entity, connection, attributeName);
	}

	public void testUniDirRelRemoveOwnerAttribute(String relationFeatureName,
			SWTBotGefEditPart owner, SWTBotGefEditPart inverse,
			RelType reltype, String linkLabel) {

		jpaDiagramEditor.activateTool(relationFeatureName, 0);
		jpaDiagramEditor.click(owner);
		jpaDiagramEditor.click(inverse);
		bot.waitUntil(new ConnectionIsShown(owner));

		waitASecond();
		jpaDiagramEditor.activateDefaultTool();

		assertConnectionIsCreated(owner, inverse, false);

		SWTBotGefConnectionEditPart connection = owner.sourceConnections().get(
				0);
		IRelation rel = getConnection(connection);
		assertNotNull(rel);
		assertEquals(IRelation.RelDir.UNI, rel.getRelDir());
		assertEquals(reltype, rel.getRelType());

		String attributeName = testOwnerRelationAttributeProperties(rel);
		assertNull(rel.getInverseAnnotatedAttribute());

		assertAttributeIsCorretlyMapped(attributeName, linkLabel);

		// delete the owner attribute
		SWTBotGefEditPart ownerAttrPart = jpaDiagramEditor
				.getEditPart(attributeName);
		ownerAttrPart.select();
		jpaDiagramEditor.clickContextMenu("Delete");
		confirmDelete();
		bot.waitUntil(new ElementDisappears(jpaDiagramEditor, attributeName),
				10000);
		// assert that the connection does not exists anymore
		assertTrue(owner.sourceConnections().isEmpty());
		assertTrue(inverse.targetConnections().isEmpty());
		assertNull(jpaDiagramEditor.getEditPart(attributeName));
		assertFalse(isSectionVisible(owner,
				JPAEditorMessages.AddJPAEntityFeature_relationAttributesShapes));
	}

	public void testBiDirRel(String relationFeatureName,
			SWTBotGefEditPart owner, SWTBotGefEditPart inverse,
			RelType reltype, String linkLabel) {
		testBiDirRelWithTwoMappingTypes(relationFeatureName, owner, inverse,
				reltype, linkLabel, linkLabel);
	}

	public void testSelfBiDirRel(String relationFeatureName,
			SWTBotGefEditPart owner, RelType reltype, String linkLabel) {
		testSelfBiDirRelWithTwoMappings(relationFeatureName, owner, reltype,
				linkLabel, linkLabel);
	}

	public void testBiDirRelWithTwoMappingTypes(String relationFeatureName,
			SWTBotGefEditPart owner, SWTBotGefEditPart inverse,
			RelType reltype, String ownerLinkLabel, String inverseLinkLabel) {

		jpaDiagramEditor.activateTool(relationFeatureName, 1);
		jpaDiagramEditor.click(owner);
		jpaDiagramEditor.click(inverse);
		bot.waitUntil(new ConnectionIsShown(owner));

		waitASecond();
		jpaDiagramEditor.activateDefaultTool();

		assertConnectionIsCreated(owner, inverse, true);

		SWTBotGefConnectionEditPart connection = owner.sourceConnections().get(
				0);
		IRelation rel = getConnection(connection);
		assertNotNull(rel);
		assertEquals(IRelation.RelDir.BI, rel.getRelDir());
		assertEquals(reltype, rel.getRelType());

		String ownerAttributeName = testOwnerRelationAttributeProperties(rel);

		String inverseAttributeName = testInverseRelationAttributeProperties(rel);

		assertAttributeIsCorretlyMapped(ownerAttributeName, ownerLinkLabel);
		assertAttributeIsCorretlyMapped(inverseAttributeName, inverseLinkLabel);

		assertBiDirRelationIsNotDeleted(owner, inverse, connection,
				ownerAttributeName, inverseAttributeName);

		assertBiDirRelationIsDeleted(owner, inverse, connection,
				ownerAttributeName, inverseAttributeName);
	}

	public void testSelfBiDirRelWithTwoMappings(String relationFeatureName,
			SWTBotGefEditPart entity, RelType reltype, String ownerLinkLabel,
			String inverseLinkLabel) {

		jpaDiagramEditor.activateTool(relationFeatureName, 1);
		jpaDiagramEditor.click(entity);
		jpaDiagramEditor.click(entity);
		bot.waitUntil(new ConnectionIsShown(entity));

		waitASecond();
		jpaDiagramEditor.activateDefaultTool();

		assertSelfConnectionIsCreated(entity);

		SWTBotGefConnectionEditPart connection = entity.sourceConnections()
				.get(0);
		IRelation rel = getConnection(connection);
		assertNotNull(rel);
		assertEquals(IRelation.RelDir.BI, rel.getRelDir());
		assertEquals(reltype, rel.getRelType());

		String ownerAttributeName = testOwnerRelationAttributeProperties(rel);

		String inverseAttributeName = testInverseRelationAttributeProperties(rel);

		assertAttributeIsCorretlyMapped(ownerAttributeName, ownerLinkLabel);
		assertAttributeIsCorretlyMapped(inverseAttributeName, inverseLinkLabel);

		assertSelfBiDirRelationIsNotDeleted(entity, connection,
				ownerAttributeName, inverseAttributeName);

		assertSelfBiDirRelationIsDeleted(entity, connection,
				ownerAttributeName, inverseAttributeName);
	}

	public void testBiDirRelRemoveInverseAttribute(String relationFeatureName,
			SWTBotGefEditPart owner, SWTBotGefEditPart inverse,
			RelType reltype, String linkLabel) {

		testBiDirRelWithTwoMappingsWithoutInverseAttr(relationFeatureName,
				owner, inverse, reltype, linkLabel, linkLabel);
	}

	public void testBiDirRelWithTwoMappingsWithoutInverseAttr(
			String relationFeatureName, SWTBotGefEditPart owner,
			SWTBotGefEditPart inverse, RelType reltype, String ownerLinkLabel,
			String inverseLinkLabel) {

		jpaDiagramEditor.activateTool(relationFeatureName, 1);
		jpaDiagramEditor.click(owner);
		jpaDiagramEditor.click(inverse);
		bot.waitUntil(new ConnectionIsShown(owner));

		waitASecond();
		jpaDiagramEditor.activateDefaultTool();

		assertConnectionIsCreated(owner, inverse, true);

		SWTBotGefConnectionEditPart connection = owner.sourceConnections().get(
				0);
		IRelation rel = getConnection(connection);
		assertNotNull(rel);
		assertEquals(IRelation.RelDir.BI, rel.getRelDir());
		assertEquals(reltype, rel.getRelType());

		String ownerAttributeName = testOwnerRelationAttributeProperties(rel);

		String inverseAttributeName = testInverseRelationAttributeProperties(rel);

		assertAttributeIsCorretlyMapped(ownerAttributeName, ownerLinkLabel);
		assertAttributeIsCorretlyMapped(inverseAttributeName, inverseLinkLabel);

		// delete the inverse attribute
		SWTBotGefEditPart inverseAttr = jpaDiagramEditor
				.getEditPart(inverseAttributeName);
		inverseAttr.select();
		jpaDiagramEditor.clickContextMenu("Delete");
		confirmDelete();

		waitASecond();
		// assert that the connection still exists, but it is unidirectional now
		assertConnectionIsCreated(owner, inverse, false);
		connection = owner.sourceConnections().get(0);
		rel = getConnection(connection);
		assertNotNull(rel);
		assertEquals(IRelation.RelDir.UNI, rel.getRelDir());
		assertEquals(reltype, rel.getRelType());
		assertEquals(ownerAttributeName,
				testOwnerRelationAttributeProperties(rel));
		assertNull(rel.getInverseAnnotatedAttribute());
		assertAttributeIsCorretlyMapped(ownerAttributeName, ownerLinkLabel);

		// delete the owner attribute
		SWTBotGefEditPart ownerAttr = jpaDiagramEditor
				.getEditPart(ownerAttributeName);
		ownerAttr.select();
		jpaDiagramEditor.clickContextMenu("Delete");
		confirmDelete();
		bot.waitUntil(new ElementDisappears(jpaDiagramEditor,
				ownerAttributeName), 10000);
		// assert that the connection does not exists anymore
		assertTrue(owner.sourceConnections().isEmpty());
		assertTrue(inverse.targetConnections().isEmpty());
		assertNull(jpaDiagramEditor.getEditPart(ownerAttributeName));
		assertNull(jpaDiagramEditor.getEditPart(inverseAttributeName));
		assertFalse(isSectionVisible(owner,
				JPAEditorMessages.AddJPAEntityFeature_relationAttributesShapes));
		assertFalse(isSectionVisible(inverse,
				JPAEditorMessages.AddJPAEntityFeature_relationAttributesShapes));
	}

	public void testBiDirRelRemoveOwnerAttr(String relationFeatureName,
			SWTBotGefEditPart owner, SWTBotGefEditPart inverse,
			RelType reltype, String linkLabel) {
		testBiDirRelWithTwoMappingsWithoutOwnerAttr(relationFeatureName, owner,
				inverse, reltype, linkLabel, linkLabel);
	}

	public void testBiDirRelWithTwoMappingsWithoutOwnerAttr(
			String relationFeatureName, SWTBotGefEditPart owner,
			SWTBotGefEditPart inverse, RelType reltype, String ownerLinkLabel,
			String inverseLinkLabel) {

		jpaDiagramEditor.activateTool(relationFeatureName, 1);
		jpaDiagramEditor.click(owner);
		jpaDiagramEditor.click(inverse);
		bot.waitUntil(new ConnectionIsShown(owner));

		waitASecond();
		jpaDiagramEditor.activateDefaultTool();

		assertConnectionIsCreated(owner, inverse, true);

		SWTBotGefConnectionEditPart connection = owner.sourceConnections().get(
				0);
		IRelation rel = getConnection(connection);
		assertNotNull(rel);
		assertEquals(IRelation.RelDir.BI, rel.getRelDir());
		assertEquals(reltype, rel.getRelType());

		String ownerAttributeName = testOwnerRelationAttributeProperties(rel);

		String inverseAttributeName = testInverseRelationAttributeProperties(rel);

		assertAttributeIsCorretlyMapped(ownerAttributeName, ownerLinkLabel);
		assertAttributeIsCorretlyMapped(inverseAttributeName, inverseLinkLabel);

		// delete the owner attribute
		SWTBotGefEditPart ownerAttrPart = jpaDiagramEditor
				.getEditPart(ownerAttributeName);
		ownerAttrPart.select();
		jpaDiagramEditor.clickContextMenu("Delete");
		confirmDelete();
		bot.waitUntil(new ElementDisappears(jpaDiagramEditor,
				ownerAttributeName), 10000);
		// assert that the connection does not exists anymore
		assertTrue(owner.sourceConnections().isEmpty());
		assertTrue(inverse.targetConnections().isEmpty());
		assertNull(jpaDiagramEditor.getEditPart(ownerAttributeName));
		// assert that the inverse attribute still exists
		assertNotNull(jpaDiagramEditor.getEditPart(inverseAttributeName));
		assertFalse(isSectionVisible(owner,
				JPAEditorMessages.AddJPAEntityFeature_relationAttributesShapes));
		// assert that the inverse attribute still exists
		assertTrue(isSectionVisible(inverse,
				JPAEditorMessages.AddJPAEntityFeature_relationAttributesShapes));
	}

	public void createInheritedEntity(SWTBotGefEditPart superclass,
			String subclassName, String superclassMappingLinkLabel,
			boolean byMappedSuperclass, boolean existing) {

		String superclassName = getJPTObjectForGefElement(superclass)
				.getSimpleName();

		jpaDiagramEditor
				.activateTool(JPAEditorMessages.CreateJPAEntityFromMappedSuperclassFeature_createInheritedEntityFeatureName);
		jpaDiagramEditor.click(superclass);
		jpaDiagramEditor.click(50, 200);

		bot.waitUntil(new ElementIsShown(jpaDiagramEditor, subclassName), 10000);

		SWTBotGefEditPart inheritedEntity = jpaDiagramEditor
				.getEditPart(subclassName);
		assertNotNull(inheritedEntity);
		testCreateAndDeleteIsARelation(superclass, subclassName,
				superclassMappingLinkLabel, byMappedSuperclass, superclassName,
				inheritedEntity, existing);
	}

	public void testCreateAndDeleteIsARelation(SWTBotGefEditPart superclass,
			String subclassName, String superclassMappingLinkLabel,
			boolean byMappedSuperclass, String superclassName,
			SWTBotGefEditPart inheritedEntity, boolean existing) {

		SWTBotGefConnectionEditPart connection = testIsARelationProperties(
				superclass, subclassName, superclassMappingLinkLabel,
				byMappedSuperclass, superclassName, inheritedEntity, existing);

		connection.select();
		jpaDiagramEditor.clickContextMenu("Delete");
		confirmDelete();
		waitASecond();
		assertTrue(superclass.sourceConnections().isEmpty());
		assertTrue(inheritedEntity.targetConnections().isEmpty());

		assertNull("The entity must not has a super persitent type.",
				getJPTObjectForGefElement(inheritedEntity)
						.getSuperPersistentType());
	}

	public SWTBotGefConnectionEditPart testIsARelationProperties(
			SWTBotGefEditPart superclass, String subclassName,
			String superclassMappingLinkLabel, boolean byMappedSuperclass,
			String superclassName, SWTBotGefEditPart inheritedEntity,
			boolean existing) {
		if (byMappedSuperclass) {
			assertTrue(isSectionVisible(inheritedEntity,
					JPAEditorMessages.AddJPAEntityFeature_primaryKeysShape));
		} else {
			assertFalse(isSectionVisible(inheritedEntity,
					JPAEditorMessages.AddJPAEntityFeature_primaryKeysShape));
		}
		assertFalse(isSectionVisible(inheritedEntity,
				JPAEditorMessages.AddJPAEntityFeature_relationAttributesShapes));
		if (existing) {
			assertTrue(isSectionVisible(inheritedEntity,
					JPAEditorMessages.AddJPAEntityFeature_basicAttributesShapes));
		} else {
			assertFalse(isSectionVisible(inheritedEntity,
					JPAEditorMessages.AddJPAEntityFeature_basicAttributesShapes));
		}

		jpaDiagramEditor.activateDefaultTool();

		assertIsARelationExists(superclass, inheritedEntity);

		SWTBotGefConnectionEditPart connection = superclass.targetConnections()
				.get(0);
		FreeFormConnection conn = (FreeFormConnection) connection.part()
				.getModel();
		assertTrue(IsARelation.isIsAConnection(conn));
		IsARelation rel = getIsARelationship();
		assertNotNull(rel);

		assertEquals(getJPTObjectForGefElement(inheritedEntity),
				rel.getSubclass());
		assertEquals(getJPTObjectForGefElement(superclass), rel.getSuperclass());

		assertTypeIsCorretlyMapped(superclass, superclassMappingLinkLabel);
		assertTypeIsCorretlyMapped(inheritedEntity,
				JptUiDetailsMessages.EntityUiProvider_linkLabel);

		JavaPersistentType superJPT = (JavaPersistentType) getJPTObjectForGefElement(
				inheritedEntity).getSuperPersistentType();
		assertNotNull("The entity must has a super persitent type.", superJPT);
		assertEquals(
				"The super persistent type must be the source of the connection.",
				superJPT, getJPTObjectForGefElement(superclass));

		return connection;
	}

	public void testNoConnectionIsCreated(String relationFeatureName,
			int indexInPallete, SWTBotGefEditPart owner,
			SWTBotGefEditPart inverse) {

		jpaDiagramEditor.activateTool(relationFeatureName, indexInPallete);

		jpaDiagramEditor.click(owner);
		jpaDiagramEditor.click(inverse);

		waitASecond();

		assertTrue("There is no connection created.", owner.sourceConnections()
				.isEmpty());
		assertTrue("There is no connection created.", inverse
				.sourceConnections().isEmpty());
		assertTrue("There is no connection.", inverse.targetConnections()
				.isEmpty());
	}

	public void testNoConnectionIsCreatedWithEmbeddable(
			String relationFeatureName, int indexInPallete,
			SWTBotGefEditPart owner, SWTBotGefEditPart inverse) {

		jpaDiagramEditor.activateTool(relationFeatureName, indexInPallete);

		jpaDiagramEditor.click(owner);
		jpaDiagramEditor.click(inverse);

		waitASecond();

		assertTrue("There is no connection created.", owner.sourceConnections()
				.isEmpty());
		assertTrue("There is no connection created.", inverse
				.sourceConnections().isEmpty());
	}

	public void testNoEmbeddedConnectionIsCreated(String relationFeatureName,
			int indexInPallete, SWTBotGefEditPart owner,
			SWTBotGefEditPart inverse, boolean alreadyEmbed) {

		jpaDiagramEditor.activateTool(relationFeatureName, indexInPallete);

		jpaDiagramEditor.click(owner);
		jpaDiagramEditor.click(inverse);

		waitASecond();

		assertTrue("There is no connection created.", owner.sourceConnections()
				.isEmpty());
		if (alreadyEmbed) {
			assertFalse("There is no connection created.", inverse
					.sourceConnections().isEmpty());
		} else {
			assertTrue("There is no connection created.", inverse
					.sourceConnections().isEmpty());
		}
		assertTrue("There is no connection.", inverse.targetConnections()
				.isEmpty());
	}

	public void setJpaDiagramEditor(SWTBotGefEditor jpaDiagramEditor) {
		this.jpaDiagramEditor = jpaDiagramEditor;
	}
}
