/** {@inheritDoc} */
  @Override
  public ICommand create(ConfigureRequest request) {

    ICommand configureCommand = null;

    Shell shell = Display.getDefault().getActiveShell();
    // Start dialog to identify the new part type
    Property part = (Property) request.getElementToConfigure();
    Package partPkg = part.getNearestPackage();

    CreateOrSelectBlockPropertyTypeDialog dialog =
        new CreateOrSelectBlockPropertyTypeDialog(shell, partPkg);
    dialog.open();
    if (dialog.getReturnCode() == Window.OK) {

      final ICommand typeCreationCommand = dialog.getNewTypeCreateCommand();
      final Type partType = (Type) dialog.getExistingType();

      // Abort if type creation command exists but is not executable
      if ((typeCreationCommand != null) && (!typeCreationCommand.canExecute())) {
        return cancelCommand(request);
      } else {
        configureCommand = CompositeCommand.compose(configureCommand, typeCreationCommand);
      }

      // Create the configure command that will set the part type
      ICommand setTypeCommand =
          new ConfigureElementCommand(request) {

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

              Property part = (Property) getElementToEdit();
              if (partType != null) {
                part.setType(partType);
              } else {
                Type newType = (Type) GMFCommandUtils.getCommandEObjectResult(typeCreationCommand);
                part.setType(newType);
              }
              return CommandResult.newOKCommandResult(part);
            }
          };

      configureCommand = CompositeCommand.compose(configureCommand, setTypeCommand);
      return configureCommand;
    }

    return cancelCommand(request);
  }
  /**
   * Override to : -> Put in "Movin state" this edit part and all its children which are Group
   * Framework concern
   */
  @Override
  public Command getCommand(Request request) {
    if (request instanceof ChangeBoundsRequest) {
      final ChangeBoundsRequest req = (ChangeBoundsRequest) request;
      CompositeCommand cc = new CompositeCommand("GroupNotifyingEditPolicy ");
      for (final EditPart part : Utils.getTargetedEditPart(req)) {
        ICommand cmd =
            getGroupRequestAdvisor()
                .notifyGroupFramework(
                    new AbstractGroupRequest(
                        (IGraphicalEditPart) getHost(),
                        Utils.getChangeBoundsRequestCopy(req, part),
                        part,
                        getTargetGroupDescriptor(part)) {

                      public GroupRequestType getGroupRequestType() {
                        return GroupRequestType.MOVE;
                      }
                    });
        if (cmd != null && cmd.canExecute()) {
          cc.compose(cmd);
        }
      }
      stopMovingPartState(req);
      if (cc != null && cc.canExecute()) {
        return new ICommandProxy(cc);
      }
    }
    return null;
  }
  @Override
  protected ICommand getBeforeSetCommand(SetRequest request) {

    ICommand setCommand = super.getBeforeSetCommand(request);

    Set<View> viewsToDestroy = new HashSet<View>();

    // Get modified object and retrieve inconsistent view
    EObject modifiedObject = request.getElementToEdit();
    if ((modifiedObject != null)
        && (modifiedObject instanceof Property)
        && (request.getFeature() == UMLPackage.eINSTANCE.getProperty_Aggregation())
        && (request.getValue() != AggregationKind.COMPOSITE_LITERAL)) {

      viewsToDestroy.addAll(getViewsToDestroy(modifiedObject));
    }

    if ((modifiedObject != null)
        && (modifiedObject instanceof Property)
        && (request.getFeature() == UMLPackage.eINSTANCE.getTypedElement_Type())
        && (request.getValue() instanceof Type)
        && !((ISpecializationType) SysMLElementTypes.BLOCK)
            .getMatcher()
            .matches((Type) request.getValue())) {

      viewsToDestroy.addAll(getViewsToDestroy(modifiedObject));
    }

    if (!viewsToDestroy.isEmpty()) {
      DestroyDependentsRequest ddr =
          new DestroyDependentsRequest(
              request.getEditingDomain(), request.getElementToEdit(), false);
      ddr.setClientContext(request.getClientContext());
      ddr.addParameters(request.getParameters());
      ICommand destroyViewsCommand = ddr.getDestroyDependentsCommand(viewsToDestroy);
      setCommand = CompositeCommand.compose(setCommand, destroyViewsCommand);
    }

    return setCommand;
  }
  @Override
  protected ICommand getAfterReorientRelationshipCommand(ReorientRelationshipRequest request) {
    ICommand defaultCommand = super.getAfterReorientRelationshipCommand(request);

    int reorientDirection = request.getDirection();
    Edge reorientedEdgeView = RequestParameterUtils.getReconnectedEdge(request);
    View newEndView = RequestParameterUtils.getReconnectedEndView(request);
    View oppositeEndView =
        (reorientDirection == ReorientRelationshipRequest.REORIENT_SOURCE)
            ? reorientedEdgeView.getTarget()
            : reorientedEdgeView.getSource();

    // Restrict this advice action to the end of Connector creation gesture (before clicking on
    // target)
    // in order to add SysML specific constraint
    Connector connector = (Connector) request.getRelationship();

    // Restrict action to SysML Connector (meaning owned by Block)
    if (((ISpecializationType) SysMLElementTypes.BLOCK)
        .getMatcher()
        .matches(connector.eContainer())) {

      // If the source or target view is enclosed in a structure encapsulated view, forbid creation.
      if (utils.isCrossingEncapsulation(newEndView, oppositeEndView)
          || utils.isCrossingEncapsulation(oppositeEndView, newEndView)) {
        return UnexecutableCommand.INSTANCE;
      }

      int tmpNestedPathDirection = -1;
      List<Property> tmpNestedPath = Collections.emptyList();

      // Check if new end view is nested
      tmpNestedPathDirection =
          (reorientDirection == ReorientRelationshipRequest.REORIENT_SOURCE)
              ? SetNestedPathCommand.NESTED_SOURCE
              : SetNestedPathCommand.NESTED_TARGET;
      tmpNestedPath = utils.getNestedPropertyPath(newEndView, oppositeEndView);
      defaultCommand =
          CompositeCommand.compose(
              defaultCommand,
              new SetNestedPathCommand(
                  "Set connector nested source path",
                  request.getRelationship(),
                  request,
                  tmpNestedPath,
                  tmpNestedPathDirection)); //$NON-NLS-0$

      // Check if opposite end view is nested
      tmpNestedPathDirection =
          (reorientDirection == ReorientRelationshipRequest.REORIENT_SOURCE)
              ? SetNestedPathCommand.NESTED_TARGET
              : SetNestedPathCommand.NESTED_SOURCE;
      tmpNestedPath = utils.getNestedPropertyPath(oppositeEndView, newEndView);
      defaultCommand =
          CompositeCommand.compose(
              defaultCommand,
              new SetNestedPathCommand(
                  "Set connector nested target path",
                  request.getRelationship(),
                  request,
                  tmpNestedPath,
                  tmpNestedPathDirection)); //$NON-NLS-0$
    }

    return defaultCommand;
  }