              (.toString dir)
              " Got exception while close()ing the writer,and directory is still locked."
              " Unlocking it. "
-             "[ should never happen, there is a race between this IndexWriter/unlock and other process/thread IndexWriter/open ]"
+             "[ should never happen, there is a race between this IndexWriter/unlock "
+             " and other process/thread IndexWriter/open ]"
              " Exception: " (ex-str e))))
 
 (defn safe-close-writer [^IndexWriter writer]

        (do
          (log-close-err (.getDirectory taxo) e)
          (DirectoryTaxonomyWriter/unlock (.getDirectory taxo)))))))

(defn use-writer [index callback]
  (let [writer (new-index-writer index)

  (try
    (doseq [dir (sub-directories)]
      (try
        (get-smanager-taxo (.getName ^File dir))
        (catch Exception e
          (log/warn (ex-str e)))))
    (catch Exception e
      (log/warn (ex-str e)))))

(defn get-smanager-taxo [index]
  (locking name->smanager-taxo*
    (when (nil? (@name->smanager-taxo* index))
      (swap! name->smanager-taxo* assoc index [(new-searcher-manager index)
                                               (try-new-taxo-reader index)]))
    (@name->smanager-taxo* index)))

(defn refresh-search-managers []
  (bootstrap-indexes)
  (locking name->smanager-taxo*
    (doseq [[index [^SearcherManager manager
                    ^DirectoryTaxonomyReader taxo]] @name->smanager-taxo*]
      (log/debug "refreshing: " index " " manager)
      (try
        (do
          (.maybeRefresh manager)
          (if-let [changed (DirectoryTaxonomyReader/openIfChanged taxo)]
            (swap! name->smanager-taxo* assoc-in [index 1] changed)))
        (catch Throwable e
          (do
            (log/info (str index " refresh exception, closing it. Exception: " (ex-str e)))
            (try-close-manager-taxo manager taxo)
            (swap! name->smanager-taxo* dissoc index)))))))


(defn shutdown []
  (locking name->smanager-taxo*
    (log/info "executing shutdown hook, current mapping: " @name->smanager-taxo*)
    (reset-search-managers)
    (log/info "mapping after cleanup: " @name->smanager-taxo*)))

(defn index-stat []
  (into {} (for [[name [manager taxo]] @name->smanager-taxo*]
             [name (use-searcher name
                                 (fn [^IndexSearcher searcher ^DirectoryTaxonomyReader taxo-reader]
                                   (let [reader (.getIndexReader searcher)]
                                     {:docs (.numDocs reader)
                                      :searcher {:to-string (.toString searcher)
                                                 :sim (.toString (.getSimilarity searcher))}
                                      :manager {:to-string (.toString manager)}
                                      :reader {:to-string (.toString reader)
                                               :leaves (count (.leaves reader))
                                               :refcnt (.getRefCount reader)
                                               :deleted-docs (.numDeletedDocs reader)
                                               :has-deletions (.hasDeletions reader)}
                                      :taxo {:size (.getSize taxo-reader)
                                             :to-string (.toString taxo-reader)
                                             :refcnt (.getRefCount taxo-reader)}})))])))
