           (first (drop-while #(-> % :type primitive-widgets not)
                      (iterate widget data)))))
 
+(defn memoize-simple [function]
+  (let [last-computation-atom (atom [::nothing nil])]
+    (fn [& args]
+      (let [[last-args last-result] @last-computation-atom]
+        (if (identical? args last-args)
+          last-result
+          (let [result (apply function args)]
+            (reset! last-computation-atom [args result])
+            result))))))
+
+(def expand-memo (memoize-simple expand))
+        
 (defn transform-object [{:keys [transform l t x y w h
                          scale-x scale-y scale rotate] :as m}]
    (if (or x y w h rotate scale scale-x scale-y)

    (dorun
      (map #(with-g2d-state [g2d %]
                            (draw-primitive g2d %))
           (denest (expand widgets))))))

(defn draw-error [graphics e]
  (draw graphics


(defn triggered-mouse-actions [action-type [x y] data]
  (->> data
       expand-memo
       (filter #(and (% action-type)
                     (-> (.createTransformedShape
                           (% :transform) (% :shape)) (.contains x y))))
