   | pattern-tokens         | URI pattern tokens to match against               |
   | attempt-partial-match? | flag to indicate whether to attempt partial-match |"
   [uri ^long begin-index pattern-tokens attempt-partial-match?]
-  (when-not (= begin-index FULL-MATCH-INDEX)  ; if already a full-match then no need to match any further
-    (let [token-count (count pattern-tokens)
-          actual-uri  (subs uri begin-index)
-          actual-len  (count actual-uri)]
-      (if (= token-count 1)  ; if length==1, then token must be string (static URI path)
-        (let [static-path (first pattern-tokens)
-              static-size (count static-path)]
-          (when (string/starts-with? actual-uri static-path)  ; URI begins with the path, so at least partial match exists
-            (if (= (count actual-uri) (count static-path))  ; if full match exists, then return as such
-              FULL-MATCH-NO-PARAMS
-              (when attempt-partial-match?
-                (partial-match static-size)))))
-        (loop [path-params  (transient {})
-               actual-index 0
-               token-index  0]
-          (if (>= token-index token-count)
-            (if (< actual-index actual-len)
-              (when attempt-partial-match?
-                (partial-match (persistent! path-params) actual-index))
-              (full-match (persistent! path-params)))
-            (let [token (get pattern-tokens token-index)]
-              (if (instance? String token)
-                ;; string token
-                (when (string/starts-with? actual-uri token)
-                  (recur path-params (unchecked-add actual-index (count token)) (unchecked-inc token-index)))
-                ;; must be a keyword
-                (let [[u-path-params
-                       u-actual-index] (loop [sb (transient [])  ; string buffer
-                                              j actual-index]
-                                         (if (>= j actual-len)  ; 'separator not found' implies URI has ended
-                                           [(assoc! path-params token (apply str (persistent! sb)))
-                                            actual-len]
-                                           (let [ch (get uri j)]
-                                             (if (= \/ ch)
-                                               [(assoc! path-params token (apply str (persistent! sb)))
-                                                j]
-                                               (recur (conj! sb ch) (unchecked-inc j))))))]
-                  (recur u-path-params (long u-actual-index) (unchecked-inc token-index)))))))))))
+  #?(:cljs (when-not (= begin-index FULL-MATCH-INDEX)  ; if already a full-match then no need to match any further
+             (let [token-count (count pattern-tokens)
+                   actual-uri  (subs uri begin-index)
+                   actual-len  (count actual-uri)]
+               (if (= token-count 1)  ; if length==1, then token must be string (static URI path)
+                 (let [static-path (first pattern-tokens)
+                       static-size (count static-path)]
+                   (when (string/starts-with? actual-uri static-path)  ; URI begins with path, so at least partial match exists
+                     (if (= (count actual-uri) (count static-path))  ; if full match exists, then return as such
+                       FULL-MATCH-NO-PARAMS
+                       (when attempt-partial-match?
+                         (partial-match static-size)))))
+                 (loop [path-params  (transient {})
+                        actual-index 0
+                        token-index  0]
+                   (if (>= token-index token-count)
+                     (if (< actual-index actual-len)
+                       (when attempt-partial-match?
+                         (partial-match (persistent! path-params) actual-index))
+                       (full-match (persistent! path-params)))
+                     (let [token (get pattern-tokens token-index)]
+                       (if (instance? String token)
+                         ;; string token
+                         (when (string/starts-with? actual-uri token)
+                           (recur path-params (unchecked-add actual-index (count token)) (unchecked-inc token-index)))
+                         ;; must be a keyword
+                         (let [[u-path-params
+                                u-actual-index] (loop [sb (transient [])  ; string buffer
+                                                       j actual-index]
+                                                  (if (>= j actual-len)  ; 'separator not found' implies URI has ended
+                                                    [(assoc! path-params token (apply str (persistent! sb)))
+                                                     actual-len]
+                                                    (let [ch (get uri j)]
+                                                      (if (= \/ ch)
+                                                        [(assoc! path-params token (apply str (persistent! sb)))
+                                                         j]
+                                                        (recur (conj! sb ch) (unchecked-inc j))))))]
+                           (recur u-path-params (long u-actual-index) (unchecked-inc token-index))))))))))
+      :clj (Util/matchURI uri begin-index pattern-tokens attempt-partial-match?)))

;; ----- URI match -----


(def ^:const NO-MATCH nil)


(def ^:const NO-PARAMS {})



  (:require
    [clojure.string :as string])
  #?(:clj (:import
            [java.util Map Map$Entry]
            [calfpath Util])))


(defn expected
