    "Print out a message using a speech bubble. The message will stay
    for 2.5 seconds until it vanishes. A second call will remove any
    currently displayed message first."
-   [director scene msg]
+   [director scene msg & {:keys [x y duration]
+                          :or {duration 2500
+                               x 20 y (fn [w h]
+                                        (- (.height director) h 20))}}]
    (when current.object
      (log/info logger (str "Expiring old message bubble: " current.object))
      (.setExpired current.object (.time scene)))
-   (let [new-message (gen-bubble
-                      director scene msg
-                      :x 20
-                      :y (fn [w h]
-                           (- (.height director) h 20)) :time 2500)]
+   (let [new-message (gen-bubble director scene msg :x x :y y :time duration)]
      (add! scene new-message)
      (set! current.object new-message))))
 

    ;; (log/info logger (str "Src: " source ";Dest: " destination))
    (let [body (.getChildAt basket 0)
          head (.getChildAt basket 1)]
      (log/info logger (str "Head: " head ";Body: " body))
      (basket-body-shake! body)
      ;; TODO: have the basket do the talking after it has opened up
      ;; (basket-head-talk! head)
      )
    (set! target.trashed true)
    (doto target
      (.enableEvents false)
      (.addBehavior (gen-move-behavior target :from [(.x source) (.y source)] :to [(.x destination) (.y destination)]))
      (.addBehavior (doto (CAAT/ScaleBehavior.)
                      (.setFrameTime (.time target) total-animation-time)
                      (.setValues 1 0.1 1 0.1)))

(defn gen-move-behavior
  "Generate & return a move behavior for the target. Still must be added by calling .addBehavior.
   Examples: 
   (gen-move-behavior :to {:up 30})
   (gen-move-behavior :from {:up 30} :to {:down 30})
   (gen-move-behavior :from {:down 30})

   (gen-move-behavior :from [0 0] :to [50 50] :time 120)
   (gen-move-behavior :from [50 50] :to [0 0] :time [120 120])"
  [& {:keys [from to time auto-rotate?]
      :or {time 120 auto-rotate? false}}]
  (let [nr (fn [n] (or n 0))
        [to-x to-y] (if (vector? to) to)
        [from-x from-y] (if (vector? from) from)
        [start-time time] (if (vector? time) time [0 time])]
    ;; (log/info logger
    ;;           (str (+ (nr (:right from)) (- (nr (:left from)))) " " (+ (nr (:down from)) (- (nr (:up from)))) " -> "
    ;;                (+ (nr (:right to)) (- (nr (:left to)))) " " (+ (nr (:down to)) (- (nr (:up to))))))
    ;; (log/info logger (str start-time " " time))
    (doto (CAAT/PathBehavior.)
      (.setFrameTime start-time time)
      (.setAutoRotate (if auto-rotate? true false) (if (fn? auto-rotate?) auto-rotate? nil))
