                         (fn [rdr] 0))
    :get-file-name (constantly nil)})
 
+(defprotocol ReaderCoercer
+  (to-rdr [rdr]))
+
+(declare string-reader pushback-reader)
+
+(extend-protocol ReaderCoercer
+  Object
+  (to-rdr [rdr]
+    (if (satisfies? Reader rdr)
+      rdr
+      (throw (IllegalArgumentException. (str "Argument of type: " (class rdr) " cannot be converted to Reader")))))
+  clojure.tools.reader.reader_types.Reader
+  (to-rdr [rdr] rdr)
+  String
+  (to-rdr [str] (string-reader str))
+  java.io.Reader
+  (to-rdr [rdr] (java.io.PushbackReader. rdr)))
+
+(defprotocol PushbackReaderCoercer
+  (to-pbr [rdr buf-len]))
+
+(extend-protocol PushbackReaderCoercer
+  Object
+  (to-pbr [rdr buf-len]
+    (if (satisfies? Reader rdr)
+      (pushback-reader rdr buf-len)
+      (throw (IllegalArgumentException. (str "Argument of type: " (class rdr) " cannot be converted to IPushbackReader")))))
+  clojure.tools.reader.reader_types.Reader
+  (to-pbr [rdr buf-len] (pushback-reader rdr buf-len))
+  clojure.tools.reader.reader_types.PushbackReader
+  (to-pbr [rdr buf-len] (pushback-reader rdr buf-len))
+  String
+  (to-pbr [str buf-len] (pushback-reader str buf-len))
+  java.io.Reader
+  (to-pbr [rdr buf-len] (java.io.PushbackReader. rdr buf-len)))
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Source Logging support
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

   (source-logging-push-back-reader s-or-rdr buf-len nil))
  ([s-or-rdr buf-len file-name]
   (SourceLoggingPushbackReader.
    (if (string? s-or-rdr) (string-push-back-reader s-or-rdr buf-len) s-or-rdr)
    1
    1
    true

  (:require [clojure.tools.reader.impl.utils :refer
             [char whitespace? newline? compile-if >=clojure-1-5-alpha*? make-var]])
  (:import clojure.lang.LineNumberingPushbackReader
           (java.io InputStream BufferedReader Closeable)))

(defmacro ^:private update! [what f]
  (list 'set! what (list f what)))
