+(defun company--fetch-candidates (prefix)
+ (let ((c (if company--manual-action
+ (company-call-backend 'candidates prefix)
+ (company-call-backend-raw 'candidates prefix)))
+ res)
+ (if (not (eq (car c) :async))
+ c
+ (let ((buf (current-buffer))
+ (win (selected-window))
+ (tick (buffer-chars-modified-tick))
+ (pt (point))
+ (backend company-backend))
+ (funcall
+ (cdr c)
+ (lambda (candidates)
+ (if (not (and candidates (eq res 'done)))
+ ;; There's no completions to display,
+ ;; or the fetcher called us back right away.
+ (setq res candidates)
+ (setq company-backend backend
+ company-candidates-cache
+ (list (cons prefix
+ (company--preprocess-candidates candidates))))
+ (company-idle-begin buf win tick pt)))))
+ ;; FIXME: Relying on the fact that the callers
+ ;; will interpret nil as "do nothing" is shaky.
+ ;; A throw-catch would be one possible improvement.
+ (or res
+ (progn (setq res 'done) nil)))))
+
+(defun company--preprocess-candidates (candidates)
+ (unless (company-call-backend 'sorted)
+ (setq candidates (sort candidates 'string<)))
+ (when (company-call-backend 'duplicates)
+ (company--strip-duplicates candidates))
+ candidates)
+
+(defun company--postprocess-candidates (candidates)
+ (when (or company-candidates-predicate company-transformers)
+ (setq candidates (copy-sequence candidates)))
+ (when company-candidates-predicate
+ (setq candidates (cl-delete-if-not company-candidates-predicate candidates)))
+ (company--transform-candidates candidates))
+