            [java.io File BufferedReader BufferedWriter IOException]
            (javax.jmdns JmDNS ServiceListener)))
 
+(defn print-fn [opts]
+  (or (:print-no-newline opts) print))
+
+(defn println-fn [opts]
+  (or (:print opts) println))
+
+(defn flush-fn [opts]
+  (or (:flush opts) flush))
+
 (defn set-logging-level [logger-name level]
   (.setLevel (java.util.logging.Logger/getLogger logger-name) level))
 

                   (deliver resp-promise :eof))
                 :eof)
      (= c 1) (do
                ((:print-no-newline opts) (str sb))
                ((:flush opts))
                (recur (StringBuilder.) (.read in)))
      (= c 0) (do
                (deliver @response-promise (str sb))

        (when (empty? @name-endpoint-map)
          (Thread/sleep 100)
          (when (= 20 count)
            ((println-fn opts) "\nSearching for devices ..."))
          (recur (inc count))))
      (Thread/sleep 500)                                    ;; Sleep a little more to catch stragglers
      (loop [current-name-endpoint-map @name-endpoint-map]
        ((println-fn opts))
        (print-discovered-devices current-name-endpoint-map opts)
        (when-not choose-first-discovered?
          ((println-fn opts) "\n[R] Refresh\n")
          ((print-fn opts) "Choice: ")
          ((flush-fn opts)))
        (let [choice (if choose-first-discovered? "1" (read-line))]
          (if (= "r" (.toLowerCase choice))
            (recur @name-endpoint-map)
