/**
   * Execute the command : create the model element, then the corresponding views
   *
   * @see org.eclipse.gef.commands.Command#execute()
   */
  @Override
  public void execute() {
    Object constraint = null;
    if (elementCreationCommand != null) {
      elementCreationCommand.execute();
      constraint = elementCreationCommand.getICommand().getCommandResult().getReturnValue();
    }
    if (constraint instanceof Constraint && compartment != null && type != null) {
      // construct the complete command for views creation and execute it.
      viewsCreationCommand = new CompoundCommand();
      // creation of the node by the compartment
      ViewDescriptor descriptor =
          new CreateViewRequest.ViewDescriptor(
              new EObjectAdapter((EObject) constraint),
              Node.class,
              type.getSemanticHint(),
              compartment.getDiagramPreferencesHint());
      CreateViewRequest request = new CreateViewRequest(descriptor);
      Command nodeCreationCommand = compartment.getCommand(request);
      viewsCreationCommand.add(nodeCreationCommand);

      // try and recover the created edit part, then create the link
      if (linkedActionEditPart != null && getLinkType() != null) {
        IAdaptable targetAdapter = extractResult(nodeCreationCommand);
        if (targetAdapter != null) {
          IAdaptable sourceAdapter = new SemanticAdapter(null, linkedActionEditPart.getModel());
          // descriptor of the link
          CreateConnectionViewRequest.ConnectionViewDescriptor linkdescriptor =
              new CreateConnectionViewRequest.ConnectionViewDescriptor(
                  getLinkType(),
                  getLinkType().getSemanticHint(),
                  compartment.getDiagramPreferencesHint());
          CommonDeferredCreateConnectionViewCommand aLinkCommand =
              new CommonDeferredCreateConnectionViewCommand(
                  EditorUtils.getTransactionalEditingDomain(),
                  getLinkType().getSemanticHint(),
                  sourceAdapter,
                  targetAdapter,
                  compartment.getViewer(),
                  compartment.getDiagramPreferencesHint(),
                  linkdescriptor,
                  null);
          aLinkCommand.setElement((EObject) constraint);
          viewsCreationCommand.add(new ICommandProxy(aLinkCommand));
        }
      }
      viewsCreationCommand.execute();
    }
  }
 /**
  * Undo model and views creation
  *
  * @see org.eclipse.gef.commands.Command#undo()
  */
 @Override
 public void undo() {
   if (viewsCreationCommand != null) {
     viewsCreationCommand.undo();
   }
   if (elementCreationCommand != null) {
     elementCreationCommand.undo();
   }
 }
  /**
   * transform binary association to n-ary association.
   *
   * @param createConnectionViewAndElementRequest the create connection view and element request
   * @param command the command
   * @return the command in charge of this job
   */
  private Command getAssociationToMultiAssociationCommand(
      CreateConnectionViewAndElementRequest createConnectionViewAndElementRequest,
      Command command) {
    // 0. creation of variables
    command = new CompoundCommand();
    Point sourceLocation = null;
    Point targetLocation = null;
    Point nodeLocation = null;
    NamedElement newSemanticElement = null; // element that will be added as
    // client ou supplier of the
    // association
    EStructuralFeature feature = null; // role client or supplier
    EditPart sourceEditPart = createConnectionViewAndElementRequest.getSourceEditPart();
    EditPart targetEditPart = createConnectionViewAndElementRequest.getTargetEditPart();
    View associationView = null;
    Association association = null;
    View parentView = null;

    Property sourceEnd = null;
    Property targetEnd = null;

    // ---------------------------------------------------------
    // help to debug
    //		System.err.println("\n+ 0. creation of variables");
    //		System.err.println("+-> editting domain"+ getEditingDomain());
    //		System.err.println("+-> sourceEditpart:" + sourceEditPart);
    //		System.err.println("+-> targetEditPart:" + targetEditPart);
    // ---------------------------------------------------------

    // 1. initialization
    ICommandProxy startcommand =
        ((ICommandProxy) createConnectionViewAndElementRequest.getStartCommand());
    if (startcommand == null) {
      return null;
    }
    Iterator<?> ite = ((CompositeCommand) startcommand.getICommand()).iterator();

    while (ite.hasNext()) {
      ICommand currentCommand = (ICommand) ite.next();
      if (currentCommand instanceof SetConnectionBendpointsCommand) {
        sourceLocation = ((SetConnectionBendpointsCommand) currentCommand).getSourceRefPoint();
        targetLocation = ((SetConnectionBendpointsCommand) currentCommand).getTargetRefPoint();
      }
    }

    if (targetEditPart != null) {
      // the source or the target must be a association
      // look for the edit part that represent the editpart
      if (((View) sourceEditPart.getModel()).getElement() != null
          && ((View) sourceEditPart.getModel()).getElement() instanceof Association) {
        associationView = ((View) sourceEditPart.getModel());
        association = (Association) ((View) sourceEditPart.getModel()).getElement();
        nodeLocation = sourceLocation;
        newSemanticElement = (NamedElement) ((View) targetEditPart.getModel()).getElement();
        feature = UMLPackage.eINSTANCE.getTypedElement_Type();
        sourceEnd =
            AssociationEndSourceLabelHelper.getInstance()
                .getUMLElement(
                    (org.eclipse.gef.GraphicalEditPart) sourceEditPart.getChildren().get(0));
        targetEnd =
            AssociationEndTargetLabelHelper.getInstance()
                .getUMLElement(
                    (org.eclipse.gef.GraphicalEditPart) sourceEditPart.getChildren().get(1));
      }

      if (((View) targetEditPart.getModel()).getElement() != null
          && ((View) targetEditPart.getModel()).getElement() instanceof Association) {
        associationView = ((View) targetEditPart.getModel());
        association = (Association) ((View) targetEditPart.getModel()).getElement();
        nodeLocation = targetLocation;
        newSemanticElement = (NamedElement) ((View) sourceEditPart.getModel()).getElement();
        feature = UMLPackage.eINSTANCE.getTypedElement_Type();
        sourceEnd =
            AssociationEndSourceLabelHelper.getInstance()
                .getUMLElement(
                    (org.eclipse.gef.GraphicalEditPart) targetEditPart.getChildren().get(0));
        targetEnd =
            AssociationEndTargetLabelHelper.getInstance()
                .getUMLElement(
                    (org.eclipse.gef.GraphicalEditPart) targetEditPart.getChildren().get(1));
      }

      if (associationView == null || (targetEditPart.getModel() instanceof Edge)) {
        return null;
      }
      parentView = (View) associationView.eContainer();
      // ---------------------------------------------------------
      // help to debug
      //			System.err.println("+ 1. initialization");
      //			System.err.println("+-> sourceLocation:" + sourceLocation);
      //			System.err.println("+-> targetLocation:" + targetLocation);
      //			System.err.println("+-> AssociationView:" + associationView);
      //			System.err.println("+-> association:" + association);
      //			System.err.println("+-> nodeLocation:" + nodeLocation);
      //			System.err.println("+-> newSemanticElement:" + newSemanticElement);
      //			System.err.println("+-> feature:" + feature);
      //			System.err.println("+-> parentView:" + parentView);
      // ---------------------------------------------------------
      // 8 Ensure that all member ends belong to the association
      ArrayList<Property> ownedProperty = new ArrayList<Property>();
      ownedProperty.addAll(association.getMemberEnds());
      IElementEditService provider = ElementEditServiceUtils.getCommandProvider(association);
      if (provider != null) {
        SetRequest setRequest =
            new SetRequest(
                association, UMLPackage.eINSTANCE.getAssociation_OwnedEnd(), ownedProperty);
        ICommand iCommand = provider.getEditCommand(setRequest);
        ((CompoundCommand) command).add(new ICommandProxy(iCommand));
      }

      // 2. Remove the view of the association
      DeleteCommand deleteCommand =
          new DeleteLinkDuringCreationCommand(
              getEditingDomain(), (Edge) associationView, sourceEditPart.getViewer());
      deleteCommand.setReuseParentTransaction(true);
      Command removecommand = new ICommandProxy(deleteCommand);
      // to execute
      ((CompoundCommand) command).add(removecommand);

      // ((CompoundCommand)command).add(removecommand);

      // ---------------------------------------------------------
      // help to debug
      //			System.err.println("+ 2. Remove the view of the association");
      //			System.err.println("+-> command:" + command.canExecute());
      // ---------------------------------------------------------

      // 3. set a new end association in the UML model
      // 3.1 creation of the property
      CreateElementRequest request =
          new CreateElementRequest(
              getEditingDomain(),
              association,
              UMLElementTypes.Property_3005,
              UMLPackage.eINSTANCE.getAssociation_OwnedEnd());
      request.setParameter("type", newSemanticElement);
      EditElementCommand propertyCreateCommand = new PropertyCommandForAssociation(request);
      propertyCreateCommand.setReuseParentTransaction(true);
      ((CompoundCommand) command).add(new ICommandProxy(propertyCreateCommand));

      // 3. Node creation at this position
      View associationViewSource = ((Edge) associationView).getSource();
      View associationViewTarget = ((Edge) associationView).getTarget();
      AssociationDiamonViewCreateCommand nodeCreation =
          new AssociationDiamonViewCreateCommand(
              getEditingDomain(),
              parentView,
              sourceEditPart.getViewer(),
              ((IGraphicalEditPart) sourceEditPart).getDiagramPreferencesHint(),
              nodeLocation,
              new SemanticAdapter(association, null));
      nodeCreation.setReuseParentTransaction(true);
      ((CompoundCommand) command).add(new ICommandProxy(nodeCreation));

      // 4. reconstruction of the old link by taking in account the old
      // connection
      ConnectionViewDescriptor viewDescriptor =
          new ConnectionViewDescriptor(
              UMLElementTypes.Association_4019,
              ((IHintedType) UMLElementTypes.Association_4019).getSemanticHint(),
              ((IGraphicalEditPart) sourceEditPart).getDiagramPreferencesHint());

      // 5. reconstruction of the first branch between old source to node
      ICommand firstBranchCommand =
          new GraphicalAssociationBranchViewCommand(
              getEditingDomain(),
              (IAdaptable) nodeCreation.getCommandResult().getReturnValue(),
              new SemanticAdapter(null, associationViewSource),
              sourceEditPart.getViewer(),
              ((IGraphicalEditPart) sourceEditPart).getDiagramPreferencesHint(),
              viewDescriptor,
              sourceEnd);

      // ICommand firstBranchCommand = new
      // CustomDeferredCreateConnectionViewCommand(getEditingDomain(),
      // ((IHintedType)UMLElementTypes.Association_4019).getSemanticHint(),
      // (IAdaptable)nodeCreation.getCommandResult().getReturnValue(), new SemanticAdapter(null,
      // associationViewSource), sourceEditPart.getViewer(),
      // ((IGraphicalEditPart)sourceEditPart).getDiagramPreferencesHint(), viewDescriptor, null);
      ((GraphicalAssociationBranchViewCommand) firstBranchCommand).setElement(association);
      ((CompoundCommand) command).add(new ICommandProxy(firstBranchCommand));
      // 6. reconstruction of the second branch between node to old target
      ICommand secondBranchCommand =
          new GraphicalAssociationBranchViewCommand(
              getEditingDomain(),
              (IAdaptable) nodeCreation.getCommandResult().getReturnValue(),
              new SemanticAdapter(null, associationViewTarget),
              sourceEditPart.getViewer(),
              ((IGraphicalEditPart) sourceEditPart).getDiagramPreferencesHint(),
              viewDescriptor,
              targetEnd);

      // ICommand secondBranchCommand = new
      // CustomDeferredCreateConnectionViewCommand(getEditingDomain(),
      // ((IHintedType)UMLElementTypes.Association_4019).getSemanticHint(),
      // (IAdaptable)nodeCreation.getCommandResult().getReturnValue(), new SemanticAdapter(null,
      // associationViewTarget), sourceEditPart.getViewer(),
      // ((IGraphicalEditPart)sourceEditPart).getDiagramPreferencesHint(), viewDescriptor, null);
      ((GraphicalAssociationBranchViewCommand) secondBranchCommand).setElement(association);
      ((CompoundCommand) command).add(new ICommandProxy(secondBranchCommand));

      // 7. Create of the third branch between node and target our source.
      ICommand thirdBranchCommand = null;

      if (associationView.equals((sourceEditPart.getModel()))) {
        // third branch node and target
        thirdBranchCommand =
            new GraphicalAssociationBranchViewCommand(
                getEditingDomain(),
                (IAdaptable) nodeCreation.getCommandResult().getReturnValue(),
                new SemanticAdapter(null, targetEditPart.getModel()),
                sourceEditPart.getViewer(),
                ((IGraphicalEditPart) sourceEditPart).getDiagramPreferencesHint(),
                viewDescriptor,
                request);

        // thirdBranchCommand = new CustomDeferredCreateConnectionViewCommand(getEditingDomain(),
        // ((IHintedType)UMLElementTypes.Association_4019).getSemanticHint(),
        // (IAdaptable)nodeCreation.getCommandResult().getReturnValue(), new SemanticAdapter(null,
        // targetEditPart.getModel()), sourceEditPart.getViewer(),
        // ((IGraphicalEditPart)sourceEditPart).getDiagramPreferencesHint(), viewDescriptor, null);
      } else {
        // third branch source and node
        thirdBranchCommand =
            new GraphicalAssociationBranchViewCommand(
                getEditingDomain(),
                new SemanticAdapter(null, sourceEditPart.getModel()),
                (IAdaptable) nodeCreation.getCommandResult().getReturnValue(),
                sourceEditPart.getViewer(),
                ((IGraphicalEditPart) sourceEditPart).getDiagramPreferencesHint(),
                viewDescriptor,
                request);

        // thirdBranchCommand = new CustomDeferredCreateConnectionViewCommand(getEditingDomain(),
        // ((IHintedType)UMLElementTypes.Association_4019).getSemanticHint(), new
        // SemanticAdapter(null, sourceEditPart.getModel()),
        // (IAdaptable)nodeCreation.getCommandResult().getReturnValue(), sourceEditPart.getViewer(),
        // ((IGraphicalEditPart)sourceEditPart).getDiagramPreferencesHint(), viewDescriptor, null);
      }
      ((GraphicalAssociationBranchViewCommand) thirdBranchCommand).setElement(association);
      ((CompoundCommand) command).add(new ICommandProxy(thirdBranchCommand));
    }
    return command;
  }
 @Override
 public boolean canExecute() {
   return elementCreationCommand != null && elementCreationCommand.canExecute();
 }