 
     @body.on 'mousemove', stopPropagationAndDefault (e) => @drag(e)
     @body.on 'mouseup', stopPropagationAndDefault (e) => @endDrag(e)
-
-    @dragSubscription = new Disposable =>
-      @body.off 'mousemove'
-      @body.off 'mouseup'
+    @initializeDragDisposable()
 
   drag: (e) ->
     if @dragging
       {pageX, pageY} = e
-      position = @cellPositionAtScreenPosition pageX, pageY
-
-      if position.row < @activeCellPosition.row
-        @selection.start.row = position.row
-        @selection.end.row = @activeCellPosition.row
-      else if position.row > @activeCellPosition.row
-        @selection.end.row = position.row
-        @selection.start.row = @activeCellPosition.row
-      else
-        @selection.end.row = @activeCellPosition.row
-        @selection.start.row = @activeCellPosition.row
-
-      if position.column < @activeCellPosition.column
-        @selection.start.column = position.column
-        @selection.end.column = @activeCellPosition.column
-      else if position.column > @activeCellPosition.column
-        @selection.end.column = position.column
-        @selection.start.column = @activeCellPosition.column
-      else
-        @selection.end.column = @activeCellPosition.column
-        @selection.start.column = @activeCellPosition.column
-
-      if position.row >= @getLastVisibleRow() - 1
-        @makeRowVisible(position.row + 1)
-      else if position.row <= @getFirstVisibleRow() + 1
-        @makeRowVisible(position.row - 1)
-
-      @requestUpdate()
-
-  endDrag: (e) ->
-    return unless @dragging
-
-    @drag(e)
-    @dragging = false
-    @dragSubscription.dispose()
-
-  startGutterDrag: (e) ->
-    return if @dragging
-
-    @dragging = true
-
-    @body.on 'mousemove', stopPropagationAndDefault (e) => @gutterDrag(e)
-    @body.on 'mouseup', stopPropagationAndDefault (e) => @endGutterDrag(e)
-
-    @dragSubscription = new Disposable =>
-      @body.off 'mousemove'
-      @body.off 'mouseup'
-
-    row = @findRowAtScreenPosition(e.pageY)
-    @setSelection(@getRowRange(row)) if row?
-
-  gutterDrag: (e) ->
-    if @dragging
-      row = @findRowAtScreenPosition(e.pageY)
+      {row, column} = @cellPositionAtScreenPosition pageX, pageY
 
       if row < @activeCellPosition.row
         @selection.start.row = row

        @selection.end.row = @activeCellPosition.row
        @selection.start.row = @activeCellPosition.row

      if row >= @getLastVisibleRow() - 1
        @makeRowVisible(row + 1)
      else if row <= @getFirstVisibleRow() + 1
        @makeRowVisible(row - 1)

      @requestUpdate()

  endGutterDrag: (e) ->

    @dragSubscription.dispose()
    @gutterDrag(e)
    @dragging = false

  scrollDuringDrag: (row) ->
    if row >= @getLastVisibleRow() - 1
      @makeRowVisible(row + 1)
    else if row <= @getFirstVisibleRow() + 1
      @makeRowVisible(row - 1)

  initializeDragDisposable: ->
    @dragSubscription = new Disposable =>
      @body.off 'mousemove'
      @body.off 'mouseup'

  #     ######   #######  ########  ######## #### ##    ##  ######
  #    ##    ## ##     ## ##     ##    ##     ##  ###   ## ##    ##
