    "Return content of buffer between two points or empty string if points are not valid"
    (if (< start end) (buffer-substring-no-properties start end) ""))
 
-(defun merlin-tell-piece (mode &optional start end)
-  "Send raw content to merlin.
-If START and END are specified, they are interpreted as positions in the buffer
-  and delimits the content to be sent.
-If only START is specified, it is directly used as argument.
-MODE can be 'source, 'more or 'end."
-  (cond ((and start end)
-         (merlin-send-command (list 'tell mode (merlin-buffer-substring start end))))
-        (start (merlin-send-command (list 'tell mode start)))
-        (t     (merlin-send-command '(tell end)))))
-
-(defun merlin-tell-till-end-of-phrase ()
-  "Feed merlin with as much content as it needs starting from (POINT).
-To be called only when merlin is waiting for input (e.g. after a `tell source'
-or `tell definitions')."
-  (let ((curr (point))
-        (chunk 10)
-        (pos 'null))
-    (forward-line chunk)
-    (while
-        (progn
-          (setq pos (if (< curr (point-max))
-                        (merlin-tell-piece 'more curr (point))
-                      (merlin-tell-piece 'end)))
-          (equal pos 'null))
-      (setq curr (point))
-      (forward-line chunk)
-      (if (< chunk 20000)
-          (setq chunk (* chunk 2))))
-    (merlin-make-point pos)))
+(defun merlin-tell-source (code)
+  "Tell CODE to merlin and returns whether the position of the
+anchor matches the current position."
+  (let ((result (merlin-parse-position (merlin-send-command (list 'tell 'source code)))))
+    (setq merlin-lock-point (car result))
+    (if (equal (cdr result) 'true)
+        (car result))))
+  
+(defun merlin-tell-till-end-of-definition ()
+  "Tell merlin till anchor and cursor agree."
+  (let ((before (point))
+        (after (point)))
+    (merlin-send-command (list 'tell 'marker))
+    (forward-line 10)
+    (setq after (point))
+    (while (and (not (= before (point-max)))
+               (setq before (merlin-tell-source (merlin-buffer-substring before after))))
+      (forward-line 10)
+      (setq after (point)))))
+
+(defun merlin-tell (start end)
+  "Tell to merlin part of the buffer between START and END. START
+may be nil, in that case the current cursor of merlin is used."
+  (let* ((data 
+          (if start
+              (merlin-send-command (list 'tell 'start (merlin-unmake-point start)))
+            (merlin-send-command (list 'tell 'start))))
+         (pos (car (merlin-parse-position data)))
+         (before nil)
+         (after nil))
+    (save-excursion
+      (merlin-tell-source (merlin-buffer-substring pos end))
+      (merlin-tell-till-end-of-definition))))
 
 (defun merlin-tell-to-point (&optional point)
   "Ensure that merlin view of the buffer is consistent up to POINT."
-  (save-excursion
+  (setq point (if point point (point)))
+  (when (or (< merlin-lock-point (point)) (< (merlin-get-position) point))
     (if (not (merlin-is-last-user-p))
         (merlin-rewind))
-    (unless point (setq point (point)))
-    (let ((start (merlin-seek-before merlin-lock-point)))
-      (when (< start point)
-        (merlin-tell-piece 'source start point)
-        (goto-char point)
-        (setq merlin-lock-point
-              (merlin-tell-till-end-of-phrase))))))
+    (merlin-tell nil point)))
 
 (defun merlin-tell-definitions (count &optional point)
   "Synchronize up to POINT then feed merlin with up to COUNT definitions."

  "Makes sure the buffer is synchronized on merlin-side and centered around (point)."
  (unless point (setq point (point)))
  (merlin-tell-to-point point)
  (merlin-seek-exact point)
  (merlin-sync-lock-zone-display))

;;;;;;;;;;;;;;;;;;

  "Return the completion for ident IDENT."
  (merlin-send-command (list 'complete 'prefix ident 'at (merlin-unmake-point (point)))))

(defun merlin-parse-position (result)
  (list
   (merlin-make-point (lookup-default 'cursor result nil))
   (lookup-default 'marker result nil)))

(defun merlin-get-position ()
  "Get the current position of merlin."
  (car (merlin-parse-position (merlin-send-command '(seek position)))))

(defun merlin-seek-before (point)
  "Move merlin's point to the valid definition before POINT."
  (merlin-parse-position (merlin-send-command (list 'seek 'before (merlin-unmake-point point)))))

(defun merlin-seek-exact (point)
  "Move merlin's point to the definition containing POINT."
  (merlin-parse-position (merlin-send-command (list 'seek 'exact (merlin-unmake-point point)))))

(defun merlin-seek-end ()
  "Move merlin's point to the end of its own view of the buffer."
  (merlin-parse-position (merlin-send-command '(seek end))))

;;;;;;;;;;;;;;;;;;;;
;; FILE SWITCHING ;;
