   (.write out (int 0)) ;; terminator
   (.flush out))
 
-(defn read-response [^BufferedReader in]
-  (let [sb (StringBuilder.)]
-    (loop [sb sb c (.read in)]
-      (cond
-       (= c 1) (let [ret (str sb)]
-                 (print ret)
-                 (recur (StringBuilder.) (.read in)))
-       (= c 0) (str sb)
-       :else (do
-               (.append sb (char c))
-               (recur sb (.read in)))))))
+(defn read-messages [^BufferedReader in response-channel]
+  (loop [sb (StringBuilder.) c (.read in)]
+    (cond
+      (= c -1) (do
+                 (when-let [ch @response-channel]
+                   (deliver ch :eof))
+                 :eof)
+      (= c 1) (do
+                (print (str sb))
+                (flush)
+                (recur (StringBuilder.) (.read in)))
+      (= c 0) (do
+                (deliver @response-channel (str sb))
+                (recur (StringBuilder.) (.read in)))
+      :else (do
+              (.append sb (char c))
+              (recur sb (.read in))))))
+
+(defn start-reading-messages
+  "Starts a thread reading inbound messages."
+  [repl-env]
+  (.start
+        (Thread.
+          #(try
+            (let [rv (read-messages (:in @(:socket repl-env)) (:response-channel repl-env))]
+              (when (= :eof rv)
+                (close-socket @(:socket repl-env))))
+            (catch IOException e
+              (when-not (.isClosed (:socket @(:socket repl-env)))
+                (.printStackTrace e)))))))
 
 (defn stack-line->frame
   "Parses a stack line into a frame representation, returning nil

    (Thread/sleep 300)
    (reset! (:socket repl-env)
      (socket (:host repl-env) (:port repl-env)))
    ;; compile cljs.core & its dependencies, goog/base.js must be available
    ;; for bootstrap to load, use new closure/compile as it can handle
    ;; resources in JARs

             (js/CLOSURE_IMPORT_SCRIPT
               (aget (.. js/goog -dependencies_ -nameToPath) name))))))))

(defrecord JscEnv [host port socket response-channel]
  repl/IJavaScriptEnv
  (-setup [this opts]
    (setup this opts))
