             [clojure.data.json :as json])
   (:import java.net.Socket
            java.lang.StringBuilder
-           [java.io File BufferedReader BufferedWriter]))
+           [java.io File BufferedReader BufferedWriter IOException]))
 
 (defn socket [host port]
   (let [socket (Socket. host port)

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

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

  (.write out (int 0)) ;; terminator
  (.flush out))

(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
