 
 (defn- find-symbol-in-file [fully-qualified-name file]
   (let [file-content (slurp file)
-        locs (->> file-content
-                  ns-ast
+        locs (->> (ns-ast file-content)
                   (find-symbol-in-ast fully-qualified-name)
-                  (filter #(first %)))]
-    (when-not (empty? locs)
-      (map #(conj % (.getCanonicalPath file) (match file-content (first %) (second %)))
-           locs))))
+                  (filter first))
+        gather (fn [info]
+                 (conj info
+                       (.getCanonicalPath file)
+                       (match file-content
+                              (first info)
+                              (second info))))]
+    (when (seq locs) (map gather locs))))
 
 (defn- find-global-symbol [file ns var-name clj-dir]
   (let [dir (or clj-dir ".")
-        namespace (or ns (ns-from-string (slurp file)))
+        namespace (or ns (util/ns-from-string (slurp file)))
         fully-qualified-name (if (= namespace "clojure.core")
                                var-name
                                (str/join "/" [namespace var-name]))]
-    (->> dir
-         list-project-clj-files
+    (->> (util/list-project-clj-files dir)
          (mapcat (partial find-symbol-in-file fully-qualified-name))
          (map identity))))
 

  "Finds fn invokes in the AST.
  Returns a list of line, end-line, column, end-column and fn name tuples"
  [ast fn-names]
  (find-nodes ast (partial fns-invoked? (into #{} (str/split fn-names #",")) (alias-info ast))))

(defn- contains-var [var-name alias-info node]
  (contains-var? #{var-name} alias-info node))

(def ^:private symbol-regex #"[\w\.:\*\+\-_!\?]+")

(defn- contains-const? [var-name alias-info node]
  (let [[ns name] (str/split var-name #"/")
        const-node? (= :const (:op node))
        node-val-words (when const-node? (->> node
                                              :val
                                              str
                                              (re-seq symbol-regex)
                                              set))]
    (and const-node?
         (node-val-words ns)
         (or (not name)
             (node-val-words name))
         var-name)))

(defn- contains-var-or-const? [var-name alias-info node]
  (or (contains-var var-name alias-info node)
      (contains-const? var-name alias-info node)))

(defn- find-symbol-in-ast [name ast]
  (when ast
    (find-nodes ast (partial contains-var-or-const? name (alias-info ast)))))

(defn- match [file-content line end-line]
  (let [line-index (dec line)

(ns refactor-nrepl.find-symbol
  (:require [clojure.string :as str]
            [clojure.tools.analyzer.ast :refer [nodes]]
            [refactor-nrepl
             [analyzer :refer [ns-ast]]
             [util :as util]]))

(defn- node->var
  "Returns a fully qualified symbol for vars other those from clojure.core, for
  which the non-qualified name is returned."
  [alias-info node]
  (let [class (or (:class node)
                  (-> (str (:var node))
                      (str/replace "#'" "")
                      (str/replace "clojure.core/" "")))
        full-class (get alias-info class class)]
    (str/join "/" (remove nil? [full-class (:field node)]))))

(defn- fns-invoked?
  "Checks if `node` is a function-call present in `fn-set`."
  [fn-set alias-info node]
  (and (= :invoke (:op node))
       (fn-set (node->var alias-info (:fn node)))))

(defn- contains-var?
  "Checks if the var of `node` is present in the `var-set`."
  [var-set alias-info node]
  (var-set (node->var alias-info node)))

(defn- find-nodes
  "Filters `ast` with `pred` and returns a list of vectors with line-beg, line-end,
  colum-beg, column-end and the result of applying pred to the node for each
  node in the AST."
  [ast pred]
  (->> (mapcat nodes ast)
       (filter pred)
       (map (juxt (comp :line :env)
                  (comp :end-line :env)
