diff --git a/.dir-locals.el b/.dir-locals.el
index 2abef28921480f743fde18818ed00d030d3c81ad..f1800ab898184cca8799238cfeef0cff65fc6dfe 100644
--- a/.dir-locals.el
+++ b/.dir-locals.el
@@ -16,10 +16,8 @@
                               (catch-api-exceptions 0)
                               (check 1)
                               (checkp 1)
-                              (cond-as-> 2)
                               (context 2)
                               (create-database-definition 1)
-                              (engine-case 0)
                               (execute-query 1)
                               (execute-sql! 2)
                               (expect 0)
@@ -28,25 +26,18 @@
                               (expect-with-all-engines 0)
                               (expect-with-engine 1)
                               (expect-with-engines 1)
-                              (ins 1)
                               (let-400 1)
                               (let-404 1)
                               (let-500 1)
-                              (macrolet 1)
                               (match 1)
                               (match-$ 1)
-                              (org-perms-case 1)
                               (post-select 1)
                               (pre-cascade-delete 1)
                               (pre-insert 1)
                               (pre-update 1)
                               (project 1)
                               (qp-expect-with-engines 1)
-                              (query-with-temp-db 1)
                               (resolve-private-fns 1)
                               (select 1)
-                              (subselect 1)
                               (sync-in-context 2)
-                              (upd 2)
-                              (when-testing-engine 1)
-                              (with-credentials 1)))))))
+                              (when-testing-engine 1)))))))
diff --git a/src/metabase/api/common/internal.clj b/src/metabase/api/common/internal.clj
index 05b3710488cf041b0852061369d4434fa27bf3f1..1a84cb5bf22c291a0f887aff842d9c02f87fd5dd 100644
--- a/src/metabase/api/common/internal.clj
+++ b/src/metabase/api/common/internal.clj
@@ -181,11 +181,12 @@
 
     (typify-route \"/:id/card\") -> [\"/:id/card\" :id #\"[0-9]+\"]"
   [route]
-  (if (vector? route) route
-      (let [arg-types (->> (route-arg-keywords route)
-                           typify-args)]
-        (if (empty? arg-types) route
-            (apply vector route arg-types)))))
+  (if (vector? route)
+    route
+    (let [arg-types (typify-args (route-arg-keywords route))]
+      (if (empty? arg-types)
+        route
+        (apply vector route arg-types)))))
 
 
 ;;; ## ROUTE ARG AUTO PARSING
@@ -195,11 +196,11 @@
   that can be used in a `let` form."
   [arg-symbol]
   (when (symbol? arg-symbol)
-    (some-> (arg-type arg-symbol)                                    ; :int
-            *auto-parse-types*                                       ; {:parser ... }
-            :parser                                                  ; Integer/parseInt
+    (some-> (arg-type arg-symbol)                                     ; :int
+            *auto-parse-types*                                        ; {:parser ... }
+            :parser                                                   ; Integer/parseInt
             ((fn [parser] `(when ~arg-symbol (~parser ~arg-symbol)))) ; (when id (Integer/parseInt id))
-            ((partial vector arg-symbol)))))                         ; [id (Integer/parseInt id)]
+            ((partial vector arg-symbol)))))                          ; [id (Integer/parseInt id)]
 
 (defmacro auto-parse
   "Create a `let` form that applies corresponding parse-fn for any symbols in ARGS that are present in `*auto-parse-types*`."
diff --git a/src/metabase/api/database.clj b/src/metabase/api/database.clj
index d3613b50e0f77da5566ec19914c0e6b1776c7b8f..11c20e44bc261e03f3c566273019dfa306eb79f4 100644
--- a/src/metabase/api/database.clj
+++ b/src/metabase/api/database.clj
@@ -115,8 +115,7 @@
                          details
                          (assoc details :password (get-in database [:details :password])))
           conn-error   (test-database-connection engine details)
-          is_full_sync (if (nil? is_full_sync)
-                         nil
+          is_full_sync (when-not (nil? is_full_sync)
                          (boolean is_full_sync))]
       (if-not conn-error
         ;; no error, proceed with update
diff --git a/src/metabase/api/tiles.clj b/src/metabase/api/tiles.clj
index e4bbf05e8dd1a36a62d12f3e9753fb2df8370482..62afdc0b8cec4f3ca3da4f92214ce0691110f98a 100644
--- a/src/metabase/api/tiles.clj
+++ b/src/metabase/api/tiles.clj
@@ -81,7 +81,7 @@
           (.setColor graphics color-white)
           (.fillRect graphics (tile-pixel :x) (tile-pixel :y) pin-size pin-size)
           (.setColor graphics color-blue)
-          (.fillRect graphics (+ 1 (tile-pixel :x)) (+ 1 (tile-pixel :y)) (- pin-size 2) (- pin-size 2))))
+          (.fillRect graphics (inc (tile-pixel :x)) (inc (tile-pixel :y)) (- pin-size 2) (- pin-size 2))))
       (catch Throwable e
         (.printStackTrace e))
       (finally
diff --git a/src/metabase/driver.clj b/src/metabase/driver.clj
index 61709800a98a29961368d5f7d86d175f47436bdf..5270cc4ada289ac4ee3bfa148c24579f23efce29 100644
--- a/src/metabase/driver.clj
+++ b/src/metabase/driver.clj
@@ -221,12 +221,13 @@
                                  (filter identity)
                                  (take max-sync-lazy-seq-results))
         field-values-count (count field-values)]
-    (if (= field-values-count 0) 0
-        (int (math/round (/ (->> field-values
-                                 (map str)
-                                 (map count)
-                                 (reduce +))
-                            field-values-count))))))
+    (if (zero? field-values-count)
+      0
+      (int (math/round (/ (->> field-values
+                               (map str)
+                               (map count)
+                               (reduce +))
+                          field-values-count))))))
 
 
 (def IDriverDefaultsMixin
diff --git a/src/metabase/driver/druid/query_processor.clj b/src/metabase/driver/druid/query_processor.clj
index 3ece09b11c5337105e9038376f8b1338de36959c..eb6a8406a3f34272b72ca20df0656106b3f55ea2 100644
--- a/src/metabase/driver/druid/query_processor.clj
+++ b/src/metabase/driver/druid/query_processor.clj
@@ -132,7 +132,7 @@
 (defn- handle-aggregation [query-type {{ag-type :aggregation-type, ag-field :field} :aggregation} druid-query]
   (when (isa? query-type ::ag-query)
     (merge druid-query
-           (let [ag-type (if (= ag-type :rows) nil ag-type)]
+           (let [ag-type (when-not (= ag-type :rows) ag-type)]
              (match [ag-type ag-field]
                ;; For 'distinct values' queries (queries with a breakout by no aggregation) just aggregate by count, but name it :___count so it gets discarded automatically
                [nil     nil] {:aggregations [(ag:count :___count)]}
diff --git a/src/metabase/driver/generic_sql.clj b/src/metabase/driver/generic_sql.clj
index 4198e5f8d7f8fee84cc31ed2a70517fe498dfe32..87586ad86d4f8057584661d881a184dcb6554122 100644
--- a/src/metabase/driver/generic_sql.clj
+++ b/src/metabase/driver/generic_sql.clj
@@ -252,7 +252,7 @@
         0)))
 
 (defn- url-percentage [url-count total-count]
-  (if (and total-count (> total-count 0) url-count)
+  (if (and total-count (pos? total-count) url-count)
     (float (/ url-count total-count))
     0.0))
 
@@ -367,13 +367,11 @@
 
 (defn- describe-table-fks [driver database table]
   (with-metadata [metadata driver database]
-    (set (->> (.getImportedKeys metadata nil (:schema table) (:name table))
-              jdbc/result-set-seq
-              (mapv (fn [result]
-                      {:fk-column-name   (:fkcolumn_name result)
-                       :dest-table       {:name   (:pktable_name result)
-                                          :schema (:pktable_schem result)}
-                       :dest-column-name (:pkcolumn_name result)}))))))
+    (set (for [result (jdbc/result-set-seq (.getImportedKeys metadata nil (:schema table) (:name table)))]
+           {:fk-column-name   (:fkcolumn_name result)
+            :dest-table       {:name   (:pktable_name result)
+                               :schema (:pktable_schem result)}
+            :dest-column-name (:pkcolumn_name result)}))))
 
 
 (defn analyze-table
diff --git a/src/metabase/driver/mongo.clj b/src/metabase/driver/mongo.clj
index 61d7da4df8854e4caf12e3a02413f5660ad41db7..9dccabc2dd56b89cfa88f95728fa9a906e1ba94e 100644
--- a/src/metabase/driver/mongo.clj
+++ b/src/metabase/driver/mongo.clj
@@ -1,6 +1,7 @@
 (ns metabase.driver.mongo
   "MongoDB Driver."
-  (:require [clojure.set :as set]
+  (:require (clojure [set :as set]
+                     [string :as s])
             [clojure.tools.logging :as log]
             [cheshire.core :as json]
             (monger [collection :as mc]
@@ -74,40 +75,42 @@
       fields
       (recur more-keys (update fields k (partial update-field-attrs (k field-value)))))))
 
+(defn- safe-inc [n]
+  (inc (or n 0)))
+
 (defn- update-field-attrs [field-value field-def]
-  (let [safe-inc #(inc (or % 0))]
-    (-> field-def
-        (update :count safe-inc)
-        (update :len #(if (string? field-value)
-                       (+ (or % 0) (count field-value))
-                       %))
-        (update :types (fn [types]
-                         (update types (type field-value) safe-inc)))
-        (update :special-types (fn [special-types]
-                                 (if-let [st (val->special-type field-value)]
-                                   (update special-types st safe-inc)
-                                   special-types)))
-        (update :nested-fields (fn [nested-fields]
-                                 (if (isa? (type field-value) clojure.lang.IPersistentMap)
-                                   (find-nested-fields field-value nested-fields)
-                                   nested-fields))))))
+  (-> field-def
+      (update :count safe-inc)
+      (update :len #(if (string? field-value)
+                      (+ (or % 0) (count field-value))
+                      %))
+      (update :types (fn [types]
+                       (update types (type field-value) safe-inc)))
+      (update :special-types (fn [special-types]
+                               (if-let [st (val->special-type field-value)]
+                                 (update special-types st safe-inc)
+                                 special-types)))
+      (update :nested-fields (fn [nested-fields]
+                               (if (isa? (type field-value) clojure.lang.IPersistentMap)
+                                 (find-nested-fields field-value nested-fields)
+                                 nested-fields)))))
 
 (defn- describe-table-field [field-kw field-info]
   ;; TODO: indicate preview-display status based on :len
   (cond-> {:name      (name field-kw)
-           :base-type (->> (into [] (:types field-info))
+           :base-type (->> (vec (:types field-info))
                            (sort-by second)
                            last
                            first
                            driver/class->base-type)}
-          (= :_id field-kw) (assoc :pk? true)
-          (:special-types field-info) (assoc :special-type (->> (into [] (:special-types field-info))
-                                                               (filter #(not (nil? (first %))))
-                                                               (sort-by second)
-                                                               last
-                                                               first))
-          (:nested-fields field-info) (assoc :nested-fields (set (for [field (keys (:nested-fields field-info))]
-                                                                  (describe-table-field field (field (:nested-fields field-info))))))))
+    (= :_id field-kw)           (assoc :pk? true)
+    (:special-types field-info) (assoc :special-type (->> (vec (:special-types field-info))
+                                                          (filter #(not (nil? (first %))))
+                                                          (sort-by second)
+                                                          last
+                                                          first))
+    (:nested-fields field-info) (assoc :nested-fields (set (for [field (keys (:nested-fields field-info))]
+                                                             (describe-table-field field (field (:nested-fields field-info))))))))
 
 (defn- describe-database [database]
   (with-mongo-connection [^com.mongodb.DB conn database]
@@ -154,7 +157,7 @@
          name-components (rest (field/qualified-name-components field))]
      (assert (seq name-components))
      (for [row (mq/with-collection *mongo-connection* (:name table)
-                 (mq/fields [(apply str (interpose "." name-components))]))]
+                 (mq/fields [(s/join \. name-components)]))]
        (get-in row (map keyword name-components))))))
 
 
diff --git a/src/metabase/driver/mongo/query_processor.clj b/src/metabase/driver/mongo/query_processor.clj
index b6dc241eab6e6e4506b9a9c9ed73c5afef6837b5..bd9ea858bd25f4e5c83d9213ec527676f7ad3a19 100644
--- a/src/metabase/driver/mongo/query_processor.clj
+++ b/src/metabase/driver/mongo/query_processor.clj
@@ -66,7 +66,7 @@
 (defn- field->name
   "Return a single string name for FIELD. For nested fields, this creates a combined qualified name."
   ^String [^Field field, ^String separator]
-  (apply str (interpose separator (rest (qualified-name-components field)))))
+  (s/join separator (rest (qualified-name-components field))))
 
 (defmacro ^:private mongo-let
   {:style/indent 1}
diff --git a/src/metabase/driver/sqlite.clj b/src/metabase/driver/sqlite.clj
index 0f080076bf79d81ac0248c72420494985e0d79b7..d65bc4509ff525bd0a216d742c57bfbf8055f681 100644
--- a/src/metabase/driver/sqlite.clj
+++ b/src/metabase/driver/sqlite.clj
@@ -1,5 +1,6 @@
 (ns metabase.driver.sqlite
-  (:require [clojure.set :as set]
+  (:require (clojure [set :as set]
+                     [string :as s])
             (honeysql [core :as hsql]
                       [format :as hformat])
             [metabase.config :as config]
@@ -32,7 +33,7 @@
 ;; register the SQLite concatnation operator `||` with HoneySQL as `sqlite-concat`
 ;; (hsql/format (hsql/call :sqlite-concat :a :b)) -> "(a || b)"
 (defmethod hformat/fn-handler "sqlite-concat" [_ & args]
-  (str "(" (apply str (interpose " || " (map hformat/to-sql args))) ")"))
+  (str "(" (s/join " || " (map hformat/to-sql args)) ")"))
 
 (def ^:private ->date     (partial hsql/call :date))
 (def ^:private ->datetime (partial hsql/call :datetime))
diff --git a/src/metabase/events.clj b/src/metabase/events.clj
index 763e23e692b7c6e46ae66c884125848accec1bcc..d5e7b0e32d94a601440198b2f69b372991896635 100644
--- a/src/metabase/events.clj
+++ b/src/metabase/events.clj
@@ -53,7 +53,7 @@
 (def ^:private events-publication
   "Publication for general events channel.
    Expects a map as input and the map must have a `:topic` key."
-  (async/pub events-channel #(:topic %)))
+  (async/pub events-channel :topic))
 
 (defn publish-event
   "Publish an item into the events stream.
diff --git a/src/metabase/events/metabot_lifecycle.clj b/src/metabase/events/metabot_lifecycle.clj
index bc6406c01499c6322ae0ca1a55b81606441bc0ba..c93f8a2ddf532dd223b5551c83f3734bb60d0f8c 100644
--- a/src/metabase/events/metabot_lifecycle.clj
+++ b/src/metabase/events/metabot_lifecycle.clj
@@ -30,7 +30,7 @@
       (let [{:keys [slack-token metabot-enabled]} object]
         (cond
           (and (contains? object :metabot-enabled)
-               (not (= "true" metabot-enabled)))   (metabot/stop-metabot!)
+               (not= "true" metabot-enabled))      (metabot/stop-metabot!)
           (and (contains? object :slack-token)
                (seq slack-token))                  (metabot/start-metabot!)))
       (catch Throwable e
diff --git a/src/metabase/events/notifications.clj b/src/metabase/events/notifications.clj
index 43cd6ed75cbaec0e1e6c4b17743c0ee7f1f22785..f01b84f4c02630cc41532a15abdf9922a6c363bc 100644
--- a/src/metabase/events/notifications.clj
+++ b/src/metabase/events/notifications.clj
@@ -41,24 +41,26 @@
     ;; if we have no dependencies on cards then do nothing
     deps-by-model
     ;; otherwise pull out dependent card ids and add dashboard/pulse dependencies
-    (let [card-ids (mapv :model_id (get deps-by-model "Card"))]
+    (let [card-ids (map :model_id (get deps-by-model "Card"))]
       (assoc deps-by-model
-        "Dashboard" (for [dashcard (db/select [DashboardCard :dashboard_id], :card_id [:in card-ids])]
-                      (set/rename-keys dashcard {:dashboard_id :model_id}))
-        "Pulse"     (for [pulsecard (db/select [PulseCard :pulse_id], :card_id [:in card-ids])]
-                      (set/rename-keys pulsecard {:pulse_id :model_id}))))))
+        "Dashboard" (when (seq card-ids)
+                      (for [dashcard (db/select [DashboardCard :dashboard_id], :card_id [:in card-ids])]
+                        (set/rename-keys dashcard {:dashboard_id :model_id})))
+        "Pulse"     (when (seq card-ids)
+                      (for [pulsecard (db/select [PulseCard :pulse_id], :card_id [:in card-ids])]
+                        (set/rename-keys pulsecard {:pulse_id :model_id})))))))
 
 (defn- pull-dependencies [model model-id]
   (when-let [deps (db/select [Dependency :model :model_id]
                     :dependent_on_model model
                     :dependent_on_id    model-id)]
-    (let [deps-by-model     (-> (group-by :model deps)
-                                add-objects-dependent-on-cards)
+    (let [deps-by-model     (add-objects-dependent-on-cards (group-by :model deps))
           deps-with-details (for [model (keys deps-by-model)
                                   :let  [ids (mapv :model_id (get deps-by-model model))]]
                               ;; TODO: this is slightly dangerous because we assume :name and :creator_id are available
-                              (for [object (db/select [(model->entity (keyword model)) :id :name :creator_id]
-                                             :id [:in ids])]
+                              (for [object (when (seq ids)
+                                             (db/select [(model->entity (keyword model)) :id :name :creator_id]
+                                               :id [:in ids]))]
                                 (assoc object :model model)))]
       ;; we end up with a list of lists, so flatten before returning
       (flatten deps-with-details))))
diff --git a/src/metabase/metabot.clj b/src/metabase/metabot.clj
index 938b8ce34852673c0b7c968ec8bb6d50ede46d12..a1df63eaaf97f845d8e8fe5c46cff53c484d360f 100644
--- a/src/metabase/metabot.clj
+++ b/src/metabase/metabot.clj
@@ -26,9 +26,9 @@
   ([message m]
    (str message " " (keys-description m)))
   ([m]
-   (apply str (interpose ", " (sort (for [[k varr] m
-                                          :when    (not (:unlisted (meta varr)))]
-                                      (str \` (name k) \`)))))))
+   (str/join ", " (sort (for [[k varr] m
+                              :when    (not (:unlisted (meta varr)))]
+                          (str \` (name k) \`))))))
 
 (defn- dispatch-fn [verb tag]
   (let [fn-map (into {} (for [[symb varr] (ns-interns *ns*)
@@ -102,7 +102,7 @@
      (throw (Exception. "Not Found"))))
   ;; If the card name comes without spaces, e.g. (show 'my 'wacky 'card) turn it into a string an recur: (show "my wacky card")
   ([word & more]
-   (show (apply str (interpose " " (cons word more))))))
+   (show (str/join " " (cons word more)))))
 
 
 (defn meme:up-and-to-the-right
diff --git a/src/metabase/models/dashboard_card.clj b/src/metabase/models/dashboard_card.clj
index 2f82f8bef27e035ff657ae10135e2d357fda1db3..f36a73edf428d58ff75b8fd4768a97976409c40c 100644
--- a/src/metabase/models/dashboard_card.clj
+++ b/src/metabase/models/dashboard_card.clj
@@ -73,7 +73,7 @@
   ;; first off, just delete all series on the dashboard card (we add them again below)
   (db/cascade-delete! DashboardCardSeries :dashboardcard_id id)
   ;; now just insert all of the series that were given to us
-  (when-not (empty? card-ids)
+  (when (seq card-ids)
     (let [cards (map-indexed (fn [i card-id]
                                {:dashboardcard_id id, :card_id card-id, :position i})
                              card-ids)]
diff --git a/src/metabase/models/field.clj b/src/metabase/models/field.clj
index 5e95585bb6425b6d1456856c5d66cd00b7a0ad89..55c8a5f05122a05401c5a3279da5e1a538fed514 100644
--- a/src/metabase/models/field.clj
+++ b/src/metabase/models/field.clj
@@ -1,6 +1,6 @@
 (ns metabase.models.field
-  (:require [clojure.data :as d]
-            [clojure.string :as s]
+  (:require (clojure [data :as d]
+                     [string :as s])
             [medley.core :as m]
             [metabase.db :as db]
             (metabase.models [common :as common]
@@ -112,7 +112,7 @@
 (defn qualified-name
   "Return a combined qualified name for FIELD, e.g. `table_name.parent_field_name.field_name`."
   [field]
-  (apply str (interpose \. (qualified-name-components field))))
+  (s/join \. (qualified-name-components field)))
 
 (defn table
   "Return the `Table` associated with this `Field`."
diff --git a/src/metabase/models/pulse.clj b/src/metabase/models/pulse.clj
index 0044440aad10e3080083c48b17679240113b1ea2..e25d4590a4a98a300cb9a96a24787f66f4a1ed6c 100644
--- a/src/metabase/models/pulse.clj
+++ b/src/metabase/models/pulse.clj
@@ -62,7 +62,7 @@
   ;; first off, just delete any cards associated with this pulse (we add them again below)
   (db/cascade-delete! PulseCard :pulse_id id)
   ;; now just insert all of the cards that were given to us
-  (when-not (empty? card-ids)
+  (when (seq card-ids)
     (let [cards (map-indexed (fn [idx itm] {:pulse_id id :card_id itm :position idx}) card-ids)]
       (db/insert-many! PulseCard cards))))
 
@@ -103,9 +103,11 @@
   (let [new-channels   (group-by (comp keyword :channel_type) channels)
         old-channels   (group-by (comp keyword :channel_type) (db/select PulseChannel :pulse_id id))
         handle-channel #(create-update-delete-channel! id (first (get new-channels %)) (first (get old-channels %)))]
-    (assert (= 0 (count (get new-channels nil))) "Cannot have channels without a :channel_type attribute")
+    (assert (zero? (count (get new-channels nil)))
+      "Cannot have channels without a :channel_type attribute")
     ;; for each of our possible channel types call our handler function
-    (dorun (map handle-channel (vec (keys pulse-channel/channel-types))))))
+    (doseq [[channel-type _] pulse-channel/channel-types]
+      (handle-channel channel-type))))
 
 (defn retrieve-pulse
   "Fetch a single `Pulse` by its ID value."
diff --git a/src/metabase/models/user.clj b/src/metabase/models/user.clj
index 783a8dfd3af9e11386e0ab4877c7dfa1491a1fde..94325d22bb508eb145445a99f0aceb551c9008b9 100644
--- a/src/metabase/models/user.clj
+++ b/src/metabase/models/user.clj
@@ -17,7 +17,7 @@
                (not (s/blank? password))))
   (assert (not (:password_salt user))
     "Don't try to pass an encrypted password to (ins User). Password encryption is handled by pre-insert.")
-  (let [salt     (.toString (java.util.UUID/randomUUID))
+  (let [salt     (str (java.util.UUID/randomUUID))
         defaults {:date_joined  (u/new-sql-timestamp)
                   :last_login   nil
                   :is_staff     true
@@ -81,7 +81,7 @@
                         :email      email-address
                         :first_name first-name
                         :last_name  last-name
-                        :password   (if (not (nil? password))
+                        :password   (if-not (nil? password)
                                       password
                                       (str (java.util.UUID/randomUUID))))]
     (when send-welcome
@@ -95,7 +95,7 @@
 (defn set-user-password!
   "Updates the stored password for a specified `User` by hashing the password with a random salt."
   [user-id password]
-  (let [salt     (.toString (java.util.UUID/randomUUID))
+  (let [salt     (str (java.util.UUID/randomUUID))
         password (creds/hash-bcrypt (str salt password))]
     ;; NOTE: any password change expires the password reset token
     (db/update! User user-id
diff --git a/src/metabase/pulse/render.clj b/src/metabase/pulse/render.clj
index de3efc45f59971ed6a42e392d82251417a3c798f..d11b61876eee29edd3d2a14e714410eb2c0efb5f 100644
--- a/src/metabase/pulse/render.clj
+++ b/src/metabase/pulse/render.clj
@@ -1,7 +1,7 @@
 (ns metabase.pulse.render
   (:require [clojure.java.io :as io]
             (clojure [pprint :refer [cl-format]]
-                     [string :refer [upper-case]])
+                     [string :as s])
             [clojure.tools.logging :as log]
             (clj-time [coerce :as c]
                       [core :as t]
@@ -80,9 +80,9 @@
 
      (style {:font-weight 400, :color \"white\"}) -> \"font-weight: 400; color: white;\""
   [& style-maps]
-  (apply str (interpose " " (for [[k v] (into {} style-maps)
-                                  :let  [v (if (keyword? v) (name v) v)]]
-                              (str (name k) ": " v ";")))))
+  (s/join " " (for [[k v] (into {} style-maps)
+                    :let  [v (if (keyword? v) (name v) v)]]
+                (str (name k) ": " v ";"))))
 
 
 (defn- datetime-field?
@@ -109,7 +109,11 @@
     :hour          (f/unparse (f/formatter "h a - MMM YYYY") (c/from-long timestamp))
     :week          (str "Week " (f/unparse (f/formatter "w - YYYY") (c/from-long timestamp)))
     :month         (f/unparse (f/formatter "MMMM YYYY") (c/from-long timestamp))
-    :quarter       (str "Q" (+ 1 (int (/ (t/month (c/from-long timestamp)) 3))) " - " (t/year (c/from-long timestamp)))
+    :quarter       (str "Q"
+                        (inc (int (/ (t/month (c/from-long timestamp))
+                                     3)))
+                        " - "
+                        (t/year (c/from-long timestamp)))
     :year          (str timestamp)
     :hour-of-day   (str timestamp) ; TODO: probably shouldn't even be showing sparkline for x-of-y groupings?
     :day-of-week   (str timestamp)
@@ -127,7 +131,8 @@
     (t/within? (t/interval (t/minus interval-start interval) interval-start)                   date) last-interval-name))
 
 (defn- start-of-this-week    [] (-> (org.joda.time.LocalDate.) .weekOfWeekyear .roundFloorCopy .toDateTimeAtStartOfDay))
-(defn- start-of-this-quarter [] (t/date-midnight (year) (+ 1 (* 3 (Math/floor (/ (dec (month)) 3))))))
+(defn- start-of-this-quarter [] (t/date-midnight (year) (inc (* 3 (Math/floor (/ (dec (month))
+                                                                                 3))))))
 
 (defn- format-timestamp-relative
   "Formats timestamps with relative names (today, yesterday, this *, last *) based on column :unit, if possible, otherwie returns nil"
@@ -223,15 +228,15 @@
     [:table {:style (style {:padding-bottom :8px, :border-bottom (str "4px solid " color-gray-1)})}
      [:thead
       [:tr
-       (for [col-idx col-indexes :let [col (-> cols (nth col-idx))]]
+       (for [col-idx col-indexes :let [col (nth cols col-idx)]]
          [:th {:style (style bar-td-style bar-th-style {:min-width :60px})}
-          (h (upper-case (name (or (:display_name col) (:name col)))))])
+          (h (s/upper-case (name (or (:display_name col) (:name col)))))])
        (when bar-column
          [:th {:style (style bar-td-style bar-th-style {:width "99%"})}])]]
      [:tbody
       (map-indexed (fn [row-idx row]
                      [:tr {:style (style {:color (if (odd? row-idx) color-gray-2 color-gray-3)})}
-                      (for [col-idx col-indexes :let [col (-> cols (nth col-idx))]]
+                      (for [col-idx col-indexes :let [col (nth cols col-idx)]]
                         [:td {:style (style bar-td-style (when (and bar-column (= col-idx 1)) {:font-weight 700}))}
                          (-> row (nth col-idx) (format-cell col) h)])
                       (when bar-column
@@ -319,7 +324,7 @@
   (let [ft-row (if (datetime-field? (first cols))
                  #(.getTime ^Date (u/->Timestamp %))
                  identity)
-        rows   (if (> (ft-row (first (first rows)))
+        rows   (if (> (ft-row (ffirst rows))
                       (ft-row (first (last rows))))
                  (reverse rows)
                  rows)
diff --git a/src/metabase/query_processor.clj b/src/metabase/query_processor.clj
index 0cf39c682248ca63f2830c6acf48d5a3c767f3d5..4ae647ba714d42d3321165599a9eef7440da7985 100644
--- a/src/metabase/query_processor.clj
+++ b/src/metabase/query_processor.clj
@@ -577,7 +577,7 @@
   {:arglists '([query options])}
   [query {:keys [executed_by]}]
   {:pre [(integer? executed_by)]}
-  (let [query-uuid      (.toString (java.util.UUID/randomUUID))
+  (let [query-uuid      (str (java.util.UUID/randomUUID))
         query-hash      (hash query)
         query-execution {:uuid              query-uuid
                          :executor_id       executed_by
diff --git a/src/metabase/query_processor/resolve.clj b/src/metabase/query_processor/resolve.clj
index b350942cc4506ec3a4a50e464f97894fcea5be02..55b8e49cd053fae7f319775c7dcaabef1378a557 100644
--- a/src/metabase/query_processor/resolve.clj
+++ b/src/metabase/query_processor/resolve.clj
@@ -166,10 +166,10 @@
 
 (defn- collect-ids-with [f expanded-query-dict]
   (let [ids (transient #{})]
-    (->> expanded-query-dict
-         (walk/postwalk (fn [form]
-                          (when-let [id (f form)]
-                            (conj! ids id)))))
+    (walk/postwalk (fn [form]
+                     (when-let [id (f form)]
+                       (conj! ids id)))
+                   expanded-query-dict)
     (persistent! ids)))
 
 (def ^:private collect-unresolved-field-ids (partial collect-ids-with unresolved-field-id))
@@ -186,7 +186,7 @@
    Record `:table-ids` referenced in the Query."
   [expanded-query-dict]
   (loop [max-iterations 5, expanded-query-dict expanded-query-dict]
-    (when (< max-iterations 0)
+    (when (neg? max-iterations)
       (throw (Exception. "Failed to resolve fields: too many iterations.")))
     (let [field-ids (collect-unresolved-field-ids expanded-query-dict)]
       (if-not (seq field-ids)
diff --git a/src/metabase/setup.clj b/src/metabase/setup.clj
index 5336011eb62393637d1013cffdb4cc25d83ed364..37f3c671e90bc9356f8d80251e82573809ec4535 100644
--- a/src/metabase/setup.clj
+++ b/src/metabase/setup.clj
@@ -19,7 +19,7 @@
   "Create and set a new `@setup-token`.
    Returns the newly created token."
   []
-  (reset! setup-token (.toString (java.util.UUID/randomUUID))))
+  (reset! setup-token (str (java.util.UUID/randomUUID))))
 
 (defn token-clear
   "Clear the `@setup-token` if it exists and reset it to nil."
diff --git a/src/metabase/sync_database/analyze.clj b/src/metabase/sync_database/analyze.clj
index 98be0e459eb0de1b0af4ccb60c28947ec2958b1d..b888a2a0b8b85a6481e276c4be75209f681d3946 100644
--- a/src/metabase/sync_database/analyze.clj
+++ b/src/metabase/sync_database/analyze.clj
@@ -70,8 +70,8 @@
                           non-nil-values)]
     ;; TODO: eventually we can check for :nullable? based on the original values above
     (cond-> (assoc field-stats :values distinct-values)
-            (and (nil? (:special_type field))
-                 (< 0 (count distinct-values))) (assoc :special-type :category))))
+      (and (nil? (:special_type field))
+           (pos? (count distinct-values))) (assoc :special-type :category))))
 
 (defn- test:no-preview-display
   "If FIELD's is textual and its average length is too great, mark it so it isn't displayed in the UI."
@@ -117,11 +117,10 @@
         (s/blank? val)         (recur at-least-one-non-nil-value? more)
         ;; If val is non-nil, check that it's a JSON dictionary or array. We don't want to mark Fields containing other
         ;; types of valid JSON values as :json (e.g. a string representation of a number or boolean)
-        :else                  (let [val (json/parse-string val)]
-                                 (when (not (or (map? val)
-                                                (sequential? val)))
-                                   (throw (Exception.)))
-                                 (recur true more))))
+        :else                  (do (u/prog1 (json/parse-string val)
+                                     (assert (or (map? <>)
+                                                 (sequential? <>))))
+                                   (recur true more))))
     (catch Throwable _
       false)))
 
@@ -134,8 +133,7 @@
     ;; this field isn't suited for this test
     field-stats
     ;; check for json values
-    (if-not (values-are-valid-json? (->> (driver/field-values-lazy-seq driver field)
-                                         (take driver/max-sync-lazy-seq-results)))
+    (if-not (values-are-valid-json? (take driver/max-sync-lazy-seq-results (driver/field-values-lazy-seq driver field)))
       field-stats
       (do
         (log/debug (u/format-color 'green "Field '%s' looks like it contains valid JSON objects. Setting special_type to :json." (field/qualified-name field)))
@@ -193,7 +191,7 @@
             :visibility_type (when (false? preview-display) :details-only)
             :special_type    special-type))
         ;; handle field values, setting them if applicable otherwise clearing them
-        (if (and id values (< 0 (count (filter identity values))))
+        (if (and id values (pos? (count (filter identity values))))
           (field-values/save-field-values! id values)
           (field-values/clear-field-values! id))))
 
diff --git a/src/metabase/task.clj b/src/metabase/task.clj
index 3ee62d74efcda18121610400ec086059e2974b0d..10e76440173fb4f27336470ee3ad94fcfa928a96 100644
--- a/src/metabase/task.clj
+++ b/src/metabase/task.clj
@@ -34,7 +34,7 @@
   (when-not @quartz-scheduler
     (log/debug "Starting Quartz Scheduler")
     ;; keep a reference to our scheduler
-    (reset! quartz-scheduler (-> (qs/initialize) qs/start))
+    (reset! quartz-scheduler (qs/start (qs/initialize)))
     ;; look for job/trigger definitions
     (find-and-load-tasks!)))
 
diff --git a/src/metabase/task/send_pulses.clj b/src/metabase/task/send_pulses.clj
index 6e2100127b8b14e9b19da46094bb7ec4e6fe171a..d709b295098334b8c2185d6552f840038a4ae910 100644
--- a/src/metabase/task/send_pulses.clj
+++ b/src/metabase/task/send_pulses.clj
@@ -48,7 +48,7 @@
         curr-hour          (time/hour now)
                            ;; joda time produces values of 1-7 here (Mon -> Sun) and we subtract 1 from it to
                            ;; make the values zero based to correspond to the indexes in pulse-channel/days-of-week
-        curr-weekday       (->> (- (time/day-of-week now) 1)
+        curr-weekday       (->> (dec (time/day-of-week now))
                                 (get pulse-channel/days-of-week)
                                 :id)
         curr-monthday      (monthday now)
diff --git a/src/metabase/task/sync_databases.clj b/src/metabase/task/sync_databases.clj
index 00b75b9e8829720d9cda012a633d0c26fdf81d5f..f9cedbf5cb9ba248dece1f0725f0210e826a5aca 100644
--- a/src/metabase/task/sync_databases.clj
+++ b/src/metabase/task/sync_databases.clj
@@ -21,7 +21,7 @@
   (doseq [database (db/select Database, :is_sample false)] ; skip Sample Dataset DB
     (try
       ;; NOTE: this happens synchronously for now to avoid excessive load if there are lots of databases
-      (if-not (and (= 0 (t/hour (t/now)))
+      (if-not (and (zero? (t/hour (t/now)))
                    (driver/driver-supports? (driver/engine->driver (:engine database)) :dynamic-schema))
         ;; most of the time we do a quick sync and avoid the lengthy analysis process
         (sync-database/sync-database! database :full-sync? false)
diff --git a/src/metabase/util.clj b/src/metabase/util.clj
index 4c5aaf28b062641ce7492cf39cfc751f0aa75686..d933b3e449ef902529dd318c9d6b5563fd5a1617 100644
--- a/src/metabase/util.clj
+++ b/src/metabase/util.clj
@@ -273,7 +273,7 @@
       (loop [acc []]
         (if-let [line (.readLine this)]
           (recur (conj acc line))
-          (apply str (interpose "\n" acc))))))
+          (s/join "\n" acc)))))
 
   ;; H2 -- See also http://h2database.com/javadoc/org/h2/jdbc/JdbcClob.html
   org.h2.jdbc.JdbcClob
@@ -472,8 +472,8 @@
             filleds      (int (* percent-done meter-width))
             blanks       (- meter-width filleds)]
         (str "["
-             (apply str (repeat filleds "*"))
-             (apply str (repeat blanks "·"))
+             (s/join (repeat filleds "*"))
+             (s/join (repeat blanks "·"))
              (format "] %s  %3.0f%%" (percent-done->emoji percent-done) (* percent-done 100.0)))))))
 
 (defn filtered-stacktrace
@@ -544,26 +544,6 @@
   [timeout-ms & body]
   `(deref-with-timeout (future ~@body) ~timeout-ms))
 
-(defmacro cond-as->
-  "Anaphoric version of `cond->`. Binds EXPR to NAME through a series
-   of pairs of TEST and FORM. NAME is successively bound to the value
-   of each FORM whose TEST succeeds.
-
-     (defn maybe-wrap-fn [before after f]
-       (as-> f <>
-         (fn? before) (fn [] (before) (<>))
-         (fn? after)  (fn [] (try (<>)
-                                  (finally (after))))))"
-  {:arglists '([expr nm tst form & more])}
-  [expr nm & clauses]
-  {:pre [(even? (count clauses))]}
-  `(let [~nm ~expr
-         ~@(apply concat (for [[tst form] (partition 2 clauses)]
-                           [nm `(if ~tst
-                                  ~form
-                                  ~nm)]))]
-     ~nm))
-
 (defn round-to-decimals
   "Round (presumabily floating-point) NUMBER to DECIMAL-PLACE. Returns a `Double`.
 
@@ -613,10 +593,10 @@
    Downcase the name and replace non-alphanumeric characters with underscores."
   ^String [s]
   (when (seq s)
-    (apply str (for [c (s/lower-case (name s))]
-                 (if (contains? slugify-valid-chars c)
-                   c
-                   \_)))))
+    (s/join (for [c (s/lower-case (name s))]
+              (if (contains? slugify-valid-chars c)
+                c
+                \_)))))
 
 (defn do-with-auto-retries
   "Execute F, a function that takes no arguments, and return the results.
diff --git a/src/metabase/util/infer_spaces.clj b/src/metabase/util/infer_spaces.clj
index f0295e14229ec6fd5ca1c768354bdcdf8b1ce11f..6c36640e73b77a7e2cc0adf5c5641a8395cee67a 100644
--- a/src/metabase/util/infer_spaces.clj
+++ b/src/metabase/util/infer_spaces.clj
@@ -3,60 +3,60 @@
               [clojure.string :as s])
     (:import java.lang.Math))
 
-; ported from https://stackoverflow.com/questions/8870261/how-to-split-text-without-spaces-into-list-of-words/11642687#11642687
+;; ported from https://stackoverflow.com/questions/8870261/how-to-split-text-without-spaces-into-list-of-words/11642687#11642687
 
 (def ^:const ^:private special-words ["checkins"])
 
-; # Build a cost dictionary, assuming Zipf's law and cost = -math.log(probability).
+;; # Build a cost dictionary, assuming Zipf's law and cost = -math.log(probability).
 (def ^:private words (concat special-words (s/split-lines (slurp (io/resource "words-by-frequency.txt")))))
 
-; wordcost = dict((k, log((i+1)*log(len(words)))) for i,k in enumerate(words))
+;; wordcost = dict((k, log((i+1)*log(len(words)))) for i,k in enumerate(words))
 (def ^:private word-cost
   (apply hash-map (flatten (map-indexed
-    (fn [idx word] [word (Math/log (* (+ idx 1) (Math/log (count words))))]) words))))
+    (fn [idx word] [word (Math/log (* (inc idx) (Math/log (count words))))]) words))))
 
-; maxword = max(len(x) for x in words)
+;; maxword = max(len(x) for x in words)
 (def ^:private max-word (apply max (map count words)))
 
-; def infer_spaces(s):
-;     """Uses dynamic programming to infer the location of spaces in a string
-;     without spaces."""
-
-;     # Find the best match for the i first characters, assuming cost has
-;     # been built for the i-1 first characters.
-;     # Returns a pair (match_cost, match_length).
-;     def best_match(i):
-;         candidates = enumerate(reversed(cost[max(0, i-maxword):i]))
-;         return min((c + wordcost.get(s[i-k-1:i], 9e999), k+1) for k,c in candidates)
+;; def infer_spaces(s):
+;;     """Uses dynamic programming to infer the location of spaces in a string
+;;     without spaces."""
+;
+;;     # Find the best match for the i first characters, assuming cost has
+;;     # been built for the i-1 first characters.
+;;     # Returns a pair (match_cost, match_length).
+;;     def best_match(i):
+;;         candidates = enumerate(reversed(cost[max(0, i-maxword):i]))
+;;         return min((c + wordcost.get(s[i-k-1:i], 9e999), k+1) for k,c in candidates)
 (defn- best-match
   [i s cost]
   (let [candidates (reverse (subvec cost (max 0 (- i max-word)) i))]
-    (apply min-key first (map-indexed (fn [k c] [(+ c (get word-cost (subs s (- i k 1) i) 9e9999)) (+ k 1)]) candidates))))
+    (apply min-key first (map-indexed (fn [k c] [(+ c (get word-cost (subs s (- i k 1) i) 9e9999)) (inc k)]) candidates))))
 
-;     # Build the cost array.
-;     cost = [0]
-;     for i in range(1,len(s)+1):
-;         c,k = best_match(i)
-;         cost.append(c)
+;;     # Build the cost array.
+;;     cost = [0]
+;;     for i in range(1,len(s)+1):
+;;         c,k = best_match(i)
+;;         cost.append(c)
 (defn- build-cost-array
   [s]
   (loop [i 1
          cost [0]]
-    (if-not (< i (+ 1 (count s)))
+    (if-not (< i (inc (count s)))
       cost
-      (recur (+ i 1)
+      (recur (inc i)
              (conj cost (first (best-match i s cost)))))))
 
-;     # Backtrack to recover the minimal-cost string.
-;     out = []
-;     i = len(s)
-;     while i>0:
-;         c,k = best_match(i)
-;         assert c == cost[i]
-;         out.append(s[i-k:i])
-;         i -= k
-;
-;     return " ".join(reversed(out))
+;;     # Backtrack to recover the minimal-cost string.
+;;     out = []
+;;     i = len(s)
+;;     while i>0:
+;;         c,k = best_match(i)
+;;         assert c == cost[i]
+;;         out.append(s[i-k:i])
+;;         i -= k
+;;
+;;     return " ".join(reversed(out))
 (defn infer-spaces
   "Splits a string with no spaces into words using magic"
   [input]
@@ -64,7 +64,7 @@
         cost (build-cost-array s)]
     (loop [i (count s)
            out []]
-      (if-not (> i 0)
+      (if-not (pos? i)
         (reverse out)
         (let [[c k] (best-match i s cost)]
           (recur (- i k)
diff --git a/test/metabase/api/database_test.clj b/test/metabase/api/database_test.clj
index 5f433ff72bd1e16c149cef4ea9705372f0fdc713..e405984a038365899b32f2c4d3d66e6041db1dd1 100644
--- a/test/metabase/api/database_test.clj
+++ b/test/metabase/api/database_test.clj
@@ -89,7 +89,7 @@
      :is_full_sync    false
      :organization_id nil
      :description     nil
-     :features        (into [] (driver/features (driver/engine->driver :postgres)))})
+     :features        (vec (driver/features (driver/engine->driver :postgres)))})
   (Database (:id db)))
 
 
diff --git a/test/metabase/middleware_test.clj b/test/metabase/middleware_test.clj
index 76535003d14648144cc33d5d21863785c8f88715..5dfb07f29b5a1a62f0cabfdf6757c996ff1a703a 100644
--- a/test/metabase/middleware_test.clj
+++ b/test/metabase/middleware_test.clj
@@ -60,8 +60,7 @@
   (auth-enforced-handler (mock/request :get "/anyurl")))
 
 (defn- random-session-id []
-  {:post [(string? %)]}
-  (.toString (java.util.UUID/randomUUID)))
+  (str (java.util.UUID/randomUUID)))
 
 ;; valid session ID
 (expect
diff --git a/test/metabase/test/data/datasets.clj b/test/metabase/test/data/datasets.clj
index c8e7e5e5737b87d0314aee4d5ca7a23da6f10c90..3fb58b4660e2442973412c7e0a081a143600072f 100644
--- a/test/metabase/test/data/datasets.clj
+++ b/test/metabase/test/data/datasets.clj
@@ -125,18 +125,6 @@
   [expected actual]
   `(expect-with-engines all-valid-engines ~expected ~actual))
 
-(defmacro engine-case
-  "Case statement that switches off of the current dataset.
-
-     (engine-case
-       :h2       ...
-       :postgres ...)"
-  [& pairs]
-  `(cond ~@(mapcat (fn [[engine then]]
-                     (assert (contains? all-valid-engines engine))
-                     [`(= *engine* ~engine)
-                      then])
-                   (partition 2 pairs))))
 
 ;;; Load metabase.test.data.* namespaces for all available drivers
 (doseq [[engine _] (driver/available-drivers)]
diff --git a/test/metabase/util_test.clj b/test/metabase/util_test.clj
index f0ee9da16215c87b24efba1adfcc98da1ebe70c7..cc64814e045f864415883bb303c5dbd835a68b93 100644
--- a/test/metabase/util_test.clj
+++ b/test/metabase/util_test.clj
@@ -83,27 +83,6 @@
   ((rpartial - 5 10) 8))
 
 
-;;; ## cond-as->
-(expect 100
-  (cond-as-> 100 <>))
-
-(expect 106
-  (cond-as-> 100 <>
-    true  (+  1 <>)
-    false (+ 10 <>)
-    :ok   (+  5 <>)))
-
-(expect 101
-  (cond-as-> 100 <>
-    (odd? <>)  (inc <>)
-    (even? <>) (inc <>)))
-
-(expect 102
-  (cond-as-> 100 <>
-    (even? <>) (inc <>)
-    (odd? <>)  (inc <>)))
-
-
 ;;; TESTS FOR key-by
 (expect
   {1 {:id 1, :name "Rasta"}