/** {@inheritedDoc}. */
  @Override
  public Command getDropObjectsCommand(DropObjectsRequest dropRequest) {
    TypeDropHelper helper = new TypeDropHelper(getEditingDomain());

    // Single drop management possible drop action list can be proposed
    if (dropRequest.getObjects().size() == 1) {

      // List of available drop commands
      final List<Command> commandChoice = new ArrayList<Command>();

      // 1. Try to set the target element type with dropped object
      Command dropAsSetType =
          helper.getDropAsTypedElementType(dropRequest, (GraphicalEditPart) getHost());
      if ((dropAsSetType != null) && (dropAsSetType.canExecute())) {
        commandChoice.add(dropAsSetType);
      }

      // 3. Build default drop command (show view of the dropped object)
      Command defaultDropCommand = super.getDropObjectsCommand(dropRequest);
      defaultDropCommand.setLabel("Default drop (Show dropped object in diagram)");
      if ((defaultDropCommand != null) && (defaultDropCommand.canExecute())) {
        commandChoice.add(defaultDropCommand);
      }

      // Prepare the selection command (if several command are available) or return the drop command
      if (commandChoice.size() > 1) {
        RunnableWithResult<ICommand> runnable;
        Display.getDefault()
            .syncExec(
                runnable =
                    new RunnableWithResult.Impl<ICommand>() {

                      public void run() {
                        setResult(
                            new SelectAndExecuteCommand(
                                "Select drop action for ",
                                PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
                                commandChoice));
                      }
                    });

        ICommand selectCommand = runnable.getResult();

        return new ICommandProxy(selectCommand);
      } else if (commandChoice.size() == 1) {
        return commandChoice.get(0);
      }

      // else (command choice is empty)
      return UnexecutableCommand.INSTANCE;
    }

    return super.getDropObjectsCommand(dropRequest);
  }
  /**
   * Gets the command to handle objects dropped into the Mapping diagram.
   *
   * @param dropRequest The drop request.
   * @return The executable command.
   */
  public Command getDropObjectsCommand(DropObjectsRequest dropRequest) {

    ModelRelEditPart modelRelEditPart = (ModelRelEditPart) getHost();
    CompoundCommand command = new CompoundCommand("Add model element references");
    IElementType elementType =
        MIDElementTypes.getElementType(ModelElementReferenceEditPart.VISUAL_ID);
    EReference containment = RelationshipPackage.Literals.MODEL_ENDPOINT_REFERENCE__MODEL_ELEM_REFS;

    Iterator<?> it = dropRequest.getObjects().iterator();
    while (it.hasNext()) {
      RelationshipDiagramOutlineDropObject dropObj =
          (RelationshipDiagramOutlineDropObject) it.next();
      ModelEndpointReference modelEndpointRef = dropObj.getModelEndpointReference();
      CreateElementRequest createReq =
          new CreateElementRequest(
              modelRelEditPart.getEditingDomain(), modelEndpointRef, elementType, containment);
      command.add(
          new ICommandProxy( // convert GMF command to GEF command
              new ModelElementReferenceDropCommand(createReq, dropObj)));
    }

    return command;
  }
  /**
   * Performs a <code>DropObjectsRequest</code> in a modal context thread. Verifies that the diagram
   * refreshes on the UI thread.
   *
   * @throws Exception if an unexpected exception occurs
   */
  public void test_drop_modalContextThread() throws Exception {

    // Open the test fixture diagram
    getTestFixture().openDiagram();
    final DiagramEditPart diagramEditPart = getDiagramEditPart();

    // Create an AND gate in the semantic model
    ICommand andCommand =
        new AbstractTransactionalCommand(
            getTestFixture().getEditingDomain(), "Create AND Gate", null) { // $NON-NLS-1$

          protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info)
              throws ExecutionException {

            AndGate newElement =
                (AndGate)
                    SemanticPackage.eINSTANCE
                        .getEFactoryInstance()
                        .create(SemanticPackage.eINSTANCE.getAndGate());

            ContainerElement semanticElement =
                (ContainerElement) diagramEditPart.resolveSemanticElement();

            semanticElement.getChildren().add(newElement);
            return CommandResult.newOKCommandResult(newElement);
          }
        };

    andCommand.execute(new NullProgressMonitor(), null);
    AndGate andGate = (AndGate) andCommand.getCommandResult().getReturnValue();

    // Get the initial number of edit parts on the diagram
    List primaryEditParts = diagramEditPart.getPrimaryEditParts();
    int initialEditPartCount = primaryEditParts.size();

    // Get the command to drop the AND gate onto the diagram
    Point dropLocation = ICanonicalShapeCompartmentLayout.UNDEFINED.getLocation();
    DropObjectsRequest request = new DropObjectsRequest();
    request.setObjects(Collections.singletonList(andGate));
    request.setAllowedDetail(DND.DROP_COPY);
    request.setLocation(dropLocation);

    Command command = diagramEditPart.getCommand(request);
    final CommandProxy proxy = new CommandProxy(command);

    // Execute the command in a forking progress monitor dialog
    IRunnableWithProgress runnable =
        new IRunnableWithProgress() {

          public void run(IProgressMonitor monitor)
              throws InvocationTargetException, InterruptedException {

            try {
              OperationHistoryFactory.getOperationHistory().execute(proxy, monitor, null);

            } catch (ExecutionException e) {
              throw new InvocationTargetException(e);
            }
          }
        };

    new ProgressMonitorDialog(null).run(true, true, runnable);

    // Verify that a new edit part has been added to the diagram for the AND gate
    primaryEditParts = getDiagramEditPart().getPrimaryEditParts();

    assertTrue(
        "Size of primary edit parts should have increased.",
        primaryEditParts.size() > initialEditPartCount); // $NON-NLS-1$

    IGraphicalEditPart andGateEditPart = null;
    for (Iterator i = primaryEditParts.iterator(); i.hasNext(); ) {
      IGraphicalEditPart nextEditPart = (IGraphicalEditPart) i.next();

      if (andGate.equals(nextEditPart.resolveSemanticElement())) {
        andGateEditPart = nextEditPart;
        break;
      }
    }
    assertNotNull("Expected a new edit part for the AND gate", andGateEditPart); // $NON-NLS-1$
  }
  /** {@inheritedDoc}. */
  @Override
  public Command getDropObjectsCommand(DropObjectsRequest dropRequest) {

    BlockDropHelper helper = new BlockDropHelper(getEditingDomain());

    // Single drop management possible drop action list can be proposed
    if (dropRequest.getObjects().size() == 1) {

      // List of available drop commands
      List<Command> commandChoice = new ArrayList<Command>();

      // 1. Build command to drop BlockProperty
      PartDropHelper partDropHelper = new PartDropHelper(getEditingDomain());
      Command dropPartOnPart =
          partDropHelper.getDropPartOnPart(dropRequest, (GraphicalEditPart) getHost());
      if ((dropPartOnPart != null) && (dropPartOnPart.canExecute())) {
        commandChoice.add(dropPartOnPart);
      }

      // 2. Try to create a Part typed by the dropped object
      Command dropAsTypedPart =
          helper.getDropAsStructureItemOnPart(
              dropRequest, (GraphicalEditPart) getHost(), SysMLElementTypes.PART_PROPERTY);
      if ((dropAsTypedPart != null) && (dropAsTypedPart.canExecute())) {
        commandChoice.add(dropAsTypedPart);
      }

      // 3. Try to create a Reference typed by the dropped object
      Command dropAsTypedReference =
          helper.getDropAsStructureItemOnPart(
              dropRequest, (GraphicalEditPart) getHost(), SysMLElementTypes.REFERENCE_PROPERTY);
      if ((dropAsTypedReference != null) && (dropAsTypedReference.canExecute())) {
        commandChoice.add(dropAsTypedReference);
      }

      // 4. Try to create an ActorPart typed by the dropped object
      Command dropAsTypedActorPart =
          helper.getDropAsStructureItemOnPart(
              dropRequest, (GraphicalEditPart) getHost(), SysMLElementTypes.ACTOR_PART_PROPERTY);
      if ((dropAsTypedActorPart != null) && (dropAsTypedActorPart.canExecute())) {
        commandChoice.add(dropAsTypedActorPart);
      }

      // 5. Try to create a Value typed by the dropped object
      Command dropAsTypedValue =
          helper.getDropAsStructureItemOnPart(
              dropRequest, (GraphicalEditPart) getHost(), SysMLElementTypes.VALUE_PROPERTY);
      if ((dropAsTypedValue != null) && (dropAsTypedValue.canExecute())) {
        commandChoice.add(dropAsTypedValue);
      }

      // 6. Try to create a Property typed by the dropped object
      Command dropAsTypedProperty =
          helper.getDropAsStructureItemOnPart(
              dropRequest, (GraphicalEditPart) getHost(), UMLElementTypes.PROPERTY);
      if ((dropAsTypedProperty != null) && (dropAsTypedProperty.canExecute())) {
        commandChoice.add(dropAsTypedProperty);
      }

      // 7. Build default drop command (show view of the dropped object)
      Command defaultDropCommand = super.getDropObjectsCommand(dropRequest);
      defaultDropCommand.setLabel("Default drop (Show dropped object in diagram)");
      if ((defaultDropCommand != null) && (defaultDropCommand.canExecute())) {
        commandChoice.add(defaultDropCommand);
      }

      // Prepare the selection command (if several command are available) or return the drop command
      if (commandChoice.size() > 1) {
        SelectAndExecuteCommand selectCommand =
            new SelectAndExecuteCommand(
                "Select drop action for ",
                PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
                commandChoice);
        return new ICommandProxy(selectCommand);

      } else if (commandChoice.size() == 1) {
        return commandChoice.get(0);
      }

      // else (command choice is empty)
      return UnexecutableCommand.INSTANCE;
    }

    return super.getDropObjectsCommand(dropRequest);
  }