 
 (declare bind-to-show)
 
+(defonce ^:private ^{:doc "The thread used to run [[bind-bottleneck]]
+  and serialize the auto-binding of potential controllers that have
+  been found."}
+  auto-bind-thread
+  (atom nil))
+
 (defn- bind-bottleneck
   "Takes potential auto-bind devices from the incoming queue one by
   one and tries binding to them. This is used to make sure that we are
   only trying one device at a time, taking as long as it needs,
-  without backing up the main MIDI event handler thread."
+  without backing up the main MIDI event handler thread.
+
+  Entries on the cue are a tuple containing the device which has been
+  identified as a potential new controller port, the show to which it
+  should be bound if it turns out to be suitable, and any optional
+  arguments which should be passed along to [[bind-to-show]].
+
+  If the special flag value `:done` is passed as the third element in
+  the tuple, it signals the loop to end, because auto-binding has been
+  canceled."
   []
   (loop [[device show args] (.take bind-queue)]
     (when device

(defn cancel-auto-bind
  "Stop any [[auto-bind]] which may be in effect."
  []
  (swap! auto-bind-handler (fn [former-handler]
                             (when former-handler
                               (amidi/remove-new-device-handler! former-handler))
                             nil)))

  [show & {:keys [device-filter] :as args}]
  {:pre [(have? some? show)]}
  (load-built-in-controllers)  ; Make sure controller implementations are registered
  (swap! auto-bind-thread start-auto-bind-thread)  ; Make sure the auto-bind thread is running
  (letfn [(connection-handler
            ([device]
             (connection-handler device true))
