 
     select_complete: (id, item) =>
         complete = @store.get('complete')
-        input    = @store.getIn(['cells', id, 'input'])
         @clear_complete()
         @set_mode('edit')
+        input = complete.get('code')
         if complete? and input? and not complete.get('error')?
             new_input = input.slice(0, complete.get('cursor_start')) + item + input.slice(complete.get('cursor_end'))
             # We don't actually make the completion until the next render loop,
             # so that the editor is already in edit mode.  This way the cursor is
             # in the right position after making the change.
-            setTimeout((=> @set_cell_input(id, new_input)), 0)
+            setTimeout((=> @merge_cell_input(id, complete.get('base'), new_input)), 0)
+
+    merge_cell_input: (id, base, input, save=true) =>
+        remote = @store.getIn(['cells', id, 'input'])
+        if not remote? or not base? or not input?
+            return
+        new_input = syncstring.three_way_merge
+            base   : base
+            local  : input
+            remote : remote
+        @set_cell_input(id, new_input, save)
+        return
 
     complete_handle_key: (keyCode) =>
         ###

                    if complete.status != 'ok'
                        complete = {error:'completion failed'}
                    delete complete.status
                complete.args = {code: code, pos:cursor_pos, id:id}
                # Set the result so the UI can then react to the change.
                if complete?.matches?.length == 0
                    # do nothing -- no completions at all
                    return
                if offset?

{IPynbImporter} = require('./import-from-ipynb')

DEFAULT_KERNEL = 'python2'

syncstring    = require('smc-util/syncstring')

###
The actions -- what you can do with a jupyter notebook, and also the
