     # Redraw the main canvas
     @redrawMain()
 
+Editor::getClosestDroppableBlock = (position) ->
+  best = null; min = Infinity
+
+  if not (@dropPointQuadTree)
+    return null
+
+  testPoints = @dropPointQuadTree.retrieve {
+    x: position.x - MAX_DROP_DISTANCE
+    y: position.y - MAX_DROP_DISTANCE
+    w: MAX_DROP_DISTANCE * 2
+    h: MAX_DROP_DISTANCE * 2
+  }, (point) =>
+    unless (point.acceptLevel is helper.DISCOURAGE) and not event.shiftKey
+      # Find a modified "distance" to the point
+      # that weights horizontal distance more
+      distance = position.from(point)
+      distance.y *= 2; distance = distance.magnitude()
+
+      # Select the node that is closest by said "distance"
+      if distance < min and position.from(point).magnitude() < MAX_DROP_DISTANCE and
+         @view.getViewNodeFor(point._droplet_node).highlightArea?
+        best = point._droplet_node
+        min = distance
+  best
+
+Editor::isDragPointOverSocket = (position) ->
+  if not @currentlyUsingBlocks
+    return true
+
+  mainPoint = @trackerPointToMain(position)
+  dropBlock = @getClosestDroppableBlock(mainPoint)
+  return (dropBlock) and dropBlock.type is 'socket'
+
 Editor::getAcceptLevel = (drag, drop) ->
   if drop.type is 'socket'
     if drag.type is 'list'


      # Substitute in expansion for this palette entry, if supplied.
      expansion = @clickedBlockPaletteEntry.expansion
      if 'function' is typeof expansion then expansion = expansion()
      if (expansion) then expansion = parseBlock(@mode, expansion)
      @draggingBlock = (expansion or @draggingBlock).clone()

    else
      # Find the line on the block that we have

    @dragCanvas.style.left = "#{position.x - rect.left}px"

    mainPoint = @trackerPointToMain(position)

    # Check to see if the tree is empty;
    # if it is, drop on the tree always
