       (update :model remove-chars)))
 
 
-(defn longest-starting-match [a b]
+(defn common-prefix-length
+  "Returns the length of the longest common prefix between a and b."
+  [a b]
   (reduce (fn [match-len [a b]]
             (if (= a b)
               (inc match-len)

  (let [products (mapv prepare-product (load-input (:products-uri conf)))]
    (with-open [listings (io/reader (:listings-uri conf))
                out (io/writer (:out-uri conf))]
      (doseq [result (->> (line-seq listings)
                          (map parse-json)
                          (map #(match-product products %)))]
        (json/generate-stream result out)))))

       (some #(when (.startsWith (remove-chars (:manufacturer listing)) %)
                %))))

(defn match-title
  "Attempts to match listing to a product in products, returning a vector
  [score matching-product] if successful, else nil."
  [products listing]
        ; Longer than just manufacturer name
  (let [min-match-len (max 3 (count (:manufacturer listing)))
        matches (->> products
                     (map #(vector (common-prefix-length (:title listing)
                                                         (:product_name %))
                                   %))
                     (filter (fn [[score prod]]
                               (and (> score min-match-len)
