/**
  * Can display existing link between views.
  *
  * @param connector the connector
  * @param sourceView the source view
  * @param targetView the target view
  * @return true, if successful
  * @see
  *     org.eclipse.papyrus.infra.gmfdiag.common.editpolicies.AbstractShowHideRelatedLinkEditPolicy#canDisplayExistingLinkBetweenViews(org.eclipse.uml2.uml.Connector,
  *     org.eclipse.gmf.runtime.notation.View, org.eclipse.gmf.runtime.notation.View)
  */
 @Override
 public boolean canDisplayExistingLinkBetweenViews(
     final EObject element, final View sourceView, final View targetView) {
   return (element instanceof Connector)
       && ConnectorUtils.canDisplayExistingConnectorBetweenViewsAccordingToNestedPaths(
           (Connector) element, sourceView, targetView);
 }
  /**
   * Gets the show link command from updater link descriptor.
   *
   * @param linkToShow the link to show
   * @param domain2NotationMap the domain2 notation map
   * @param descriptor the descriptor
   * @return the show link command from updater link descriptor
   */
  private ICommand getShowLinkCommandFromUpdaterLinkDescriptor(
      final EObject linkToShow,
      final Domain2Notation domain2NotationMap,
      UpdaterLinkDescriptor descriptor) {
    ConnectorUtils connectorUtils = new ConnectorUtils();

    if (descriptor != null) {

      Set<View> sourceViewList = domain2NotationMap.get(descriptor.getSource());
      Set<View> targetViewList = domain2NotationMap.get(descriptor.getDestination());

      final Set<View> linkSet = domain2NotationMap.get(linkToShow);

      CompositeCommand compositeCommand = new CompositeCommand("Restore All Related Links");
      for (View sourceView : sourceViewList) {
        for (View targetView : targetViewList) {
          if (canDisplayExistingLinkBetweenViews(linkToShow, sourceView, targetView)) {

            if (ConnectorUtils.canDisplayExistingConnectorBetweenViewsAccordingToNestedPaths(
                (Connector) linkToShow, sourceView, targetView)) {
              boolean alreadyDisplayed = false;
              if (linkSet != null) {
                for (View viewLink : linkSet) {
                  boolean linkForViews =
                      isLinkForViews(
                          (org.eclipse.gmf.runtime.notation.Connector) viewLink,
                          sourceView,
                          targetView);
                  alreadyDisplayed = alreadyDisplayed || linkForViews;
                }
              }

              if (!alreadyDisplayed) {
                EditPart sourceEditPart = getEditPartFromView(sourceView);
                EditPart targetEditPart = getEditPartFromView(targetView);

                // If the parts are still null...
                if (sourceEditPart == null || targetEditPart == null) {
                  return null;
                }
                String semanticHint = getSemanticHint(linkToShow);
                CreateConnectionViewRequest.ConnectionViewDescriptor viewDescriptor =
                    new CreateConnectionViewRequest.ConnectionViewDescriptor(
                        descriptor.getSemanticAdapter(),
                        semanticHint,
                        ViewUtil.APPEND,
                        false,
                        ((GraphicalEditPart) getHost()).getDiagramPreferencesHint());
                CreateConnectionViewRequest ccr = new CreateConnectionViewRequest(viewDescriptor);
                ccr.setType(org.eclipse.gef.RequestConstants.REQ_CONNECTION_START);
                ccr.setSourceEditPart(sourceEditPart);
                sourceEditPart.getCommand(ccr);
                ccr.setTargetEditPart(targetEditPart);
                ccr.setType(org.eclipse.gef.RequestConstants.REQ_CONNECTION_END);
                CommandProxy commandProxy = new CommandProxy(targetEditPart.getCommand(ccr));
                compositeCommand.add(commandProxy);
              }
            }
          }
        }
      }
      return compositeCommand;
    }
    return null;
  }
  @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;
  }