function BendpointMove(injector, eventBus, canvas, dragging, rules, modeling) {
  this._injector = injector;

  this.start = function(event, connection, bendpointIndex, insert) {
    var gfx = canvas.getGraphics(connection),
        source = connection.source,
        target = connection.target,
        waypoints = connection.waypoints,
        type;

    if (!insert && bendpointIndex === 0) {
      type = RECONNECT_START;
    } else if (!insert && bendpointIndex === waypoints.length - 1) {
      type = RECONNECT_END;
    } else {
      type = UPDATE_WAYPOINTS;
    }

    var command = type === UPDATE_WAYPOINTS ? 'connection.updateWaypoints' : 'connection.reconnect';

    var allowed = rules.allowed(command, {
      connection: connection,
      source: source,
      target: target
    });

    if (allowed === false) {
      allowed = rules.allowed(command, {
        connection: connection,
        source: target,
        target: source
      });
    }

    if (allowed === false) {
      return;
    }

    dragging.init(event, 'bendpoint.move', {
      data: {
        connection: connection,
        connectionGfx: gfx,
        context: {
          allowed: allowed,
          bendpointIndex: bendpointIndex,
          connection: connection,
          source: source,
          target: target,
          insert: insert,
          type: type
        }
      }
    });
  };

  eventBus.on('bendpoint.move.hover', function(event) {
    var context = event.context,
        connection = context.connection,
        source = connection.source,
        target = connection.target,
        hover = event.hover,
        type = context.type;

    // cache hover state
    context.hover = hover;

    var allowed;

    if (!hover) {
      return;
    }

    var command = type === UPDATE_WAYPOINTS ? 'connection.updateWaypoints' : 'connection.reconnect';

    allowed = context.allowed = rules.allowed(command, {
      connection: connection,
      source: type === RECONNECT_START ? hover : source,
      target: type === RECONNECT_END ? hover : target
    });

    if (allowed) {
      context.source = type === RECONNECT_START ? hover : source;
      context.target = type === RECONNECT_END ? hover : target;

      return;
    }

    if (allowed === false) {
      allowed = context.allowed = rules.allowed(command, {
        connection: connection,
        source: type === RECONNECT_END ? hover : target,
        target: type === RECONNECT_START ? hover : source
      });
    }

    if (allowed) {
      context.source = type === RECONNECT_END ? hover : target;
      context.target = type === RECONNECT_START ? hover : source;
    }
  });

  eventBus.on([ 'bendpoint.move.out', 'bendpoint.move.cleanup' ], function(event) {
    var context = event.context,
        type = context.type;

    context.hover = null;
    context.source = null;
    context.target = null;

    if (type !== UPDATE_WAYPOINTS) {
      context.allowed = false;
    }
  });

  eventBus.on('bendpoint.move.end', function(event) {
    var context = event.context,
        allowed = context.allowed,
        bendpointIndex = context.bendpointIndex,
        connection = context.connection,
        insert = context.insert,
        newWaypoints = connection.waypoints.slice(),
        source = context.source,
        target = context.target,
        type = context.type,
        hints = context.hints || {};

    // ensure integer values (important if zoom level was > 1 during move)
    var docking = {
      x: round(event.x),
      y: round(event.y)
    };

    if (!allowed) {
      return false;
    }

    if (type === UPDATE_WAYPOINTS) {
      if (insert) {

        // insert new bendpoint
        newWaypoints.splice(bendpointIndex, 0, docking);
      } else {

        // swap previous waypoint with moved one
        newWaypoints[bendpointIndex] = docking;
      }

      // pass hints about actual moved bendpoint
      // useful for connection/label layout
      hints.bendpointMove = {
        insert: insert,
        bendpointIndex: bendpointIndex
      };

      newWaypoints = this.cropWaypoints(connection, newWaypoints);

      modeling.updateWaypoints(connection, filterRedundantWaypoints(newWaypoints), hints);
    } else {
      if (type === RECONNECT_START) {
        hints.docking = 'source';

        if (isReverse(context)) {
          hints.docking = 'target';

          hints.newWaypoints = newWaypoints.reverse();
        }
      } else if (type === RECONNECT_END) {
        hints.docking = 'target';

        if (isReverse(context)) {
          hints.docking = 'source';

          hints.newWaypoints = newWaypoints.reverse();
        }
      }

      modeling.reconnect(connection, source, target, docking, hints);
    }
  }, this);
}
Move bendpoints through drag and drop to add/remove bendpoints or reconnect connection.

@param {Injector} injector
@param {EventBus} eventBus
@param {Canvas} canvas
@param {Dragging} dragging
@param {Rules} rules
@param {Modeling} modeling