/**
   * {@inheritDoc}
   *
   * @see org.eclipse.sirius.tools.internal.command.builders.CommandBuilder#buildCommand()
   */
  @Override
  public Command buildCommand() {

    Command result = UnexecutableCommand.INSTANCE;

    if (permissionAuthority.canEditInstance(reconnectionSource)
        && permissionAuthority.canEditInstance(reconnectionTarget)
        && permissionAuthority.canEditInstance(edge)
        // Layouting mode on diagrams
        // if the ddiagram is in LayoutingMode, we do not allow reconnection
        && !isInLayoutingModeDiagram(edge)) {

      final EObject semanticSource =
          SiriusUtil.getNearestDecorateSemanticElement(reconnectionSource).getTarget();
      final EObject semanticTarget =
          SiriusUtil.getNearestDecorateSemanticElement(reconnectionTarget).getTarget();

      final Map<AbstractVariable, Object> variables = new HashMap<AbstractVariable, Object>();
      variables.put(tool.getElement(), edge.getTarget());
      variables.put(tool.getSource(), semanticSource);
      variables.put(tool.getSourceView(), reconnectionSource);
      variables.put(tool.getTarget(), semanticTarget);
      variables.put(tool.getTargetView(), reconnectionTarget);
      variables.put(tool.getEdgeView(), edge);

      // we create an hidden variable that will be used to
      // correct reconnection issues
      ICommandTask createOtherEndVariableTask = getOtherEndVariableCreationTask(variables);

      final DCommand cmd = createEnclosingCommand();
      cmd.getTasks().add(createOtherEndVariableTask);
      cmd.getTasks()
          .add(
              new InitInterpreterVariablesTask(
                  variables, InterpreterUtil.getInterpreter(reconnectionSource), uiCallback));
      Option<DDiagram> parentDiagram = getDDiagram();
      if (tool.getInitialOperation() != null
          && tool.getInitialOperation().getFirstModelOperations() != null) {
        cmd.getTasks()
            .add(
                taskHelper.buildTaskFromModelOperation(
                    parentDiagram.get(),
                    edge.getTarget(),
                    tool.getInitialOperation().getFirstModelOperations()));
      }
      final SetObject setObject = ToolFactory.eINSTANCE.createSetObject();
      final String featureName = getReconnectionKindFeatureName();
      setObject.setFeatureName(featureName);
      setObject.setObject(reconnectionTarget);

      Option<DRepresentation> representation = new EObjectQuery(edge).getRepresentation();
      final CommandContext edgeContext = new CommandContext(edge, representation.get());
      cmd.getTasks()
          .add(
              new SetValueTask(
                  edgeContext,
                  this.modelAccessor,
                  setObject,
                  new EObjectQuery(edge).getSession().getInterpreter()));

      final EdgeMapping newEdgeMapping = getEdgeMappingReconnector();
      addRefreshTask(edge, cmd, tool);
      final CompoundCommand cc = new CompoundCommand();
      if (newEdgeMapping != null && !newEdgeMapping.equals(edge.getActualMapping())) {
        cc.append(new SetEdgeActualMappingCommand(editingDomain, edge, newEdgeMapping));
      }
      if (reconnectionSource.equals(oldSource)
          && (newEdgeMapping != null && !newEdgeMapping.isUseDomainElement()
              || isEdgeActualMappingUsingDomainElement())) {
        cc.append(
            new ReconnectSourceNodeCommand(
                editingDomain, edge, reconnectionTarget, semanticTarget));
      }
      cc.append(cmd);
      result = cc;
    }
    return result;
  }