      (let [res# @p#]
        (when (instance? Throwable res#)
          (throw res#))
-       res# )
+       res#)
      ))
 
 (defn navigator 


(defn clone [{:keys [datacenter] :as allocation} {:keys [template hostname] :as machine}]
  (with-service
    (if-let [vm (find* "VirtualMachine" template)]
      (wait-for (.cloneVM_Task vm (.getParent vm) hostname (clone-spec allocation machine)))
      (throw+ {:type ::missing-template :message (str "No matching template found " template)})
      )))

(def power-to-s
  {VirtualMachinePowerState/poweredOn :running 
   VirtualMachinePowerState/poweredOff :stopped 
   VirtualMachinePowerState/suspended :suspended})

(defn status [hostname]
  (with-service
    (let [vm (find* "VirtualMachine" hostname)]
      (-> (bean vm) :summary bean :runtime bean :powerState power-to-s ))))

(defn power-on [hostname]
  (with-service
    (let [vm (find* "VirtualMachine" hostname)]
      (wait-for (.powerOnVM_Task vm nil)))))

(defn power-off [hostname]
  (with-service
    (let [vm (find* "VirtualMachine" hostname)]
      (wait-for (.powerOffVM_Task vm)))))

(defn destroy [hostname]
  (with-service
    (let [vm (find* "VirtualMachine" hostname)]
      (wait-for (.destroy_Task vm)))))

(comment
  (try 
    (clone {:datacenter "playground"} 
           {:template "ubuntu-13.04_puppet-3.1" :hostname "bar" :disk-format :sparse :cpus 1 :memory 512})
    (catch Throwable e (error e)) 
    )
  (map deref (repeatedly 40 (fn []  (future (status "foo") ))))
  (status "foo")
  (power-on "foo")
  (power-off "foo")
  (destroy "foo") 
  (clojure.pprint/pprint  (bean (.getServerConnection (deref (first (services))))))
  (clojure.pprint/pprint (.getKey (:currentSession (bean (.getSessionManager (deref (first (services))))))))
  (clojure.pprint/pprint (.getKey (:currentSession (bean (.getSessionManager (deref (second (services))))))))


(defn find*  
  "Find entity by type and name"
  ([type name*] (find* type name* (navigator)))
  ([type name* within] 
   (if-let [entity (.searchManagedEntity within type name*)]
     entity 
     (throw+ {:type ::missing-entity :message (str "No matching entity found " name*)}))))

(defn find-vm 
  "locates a vm or a template" 
  [name*]
  (find* "VirtualMachine" name*))

(defn resource-pools [dcname]
  (find-all "ResourcePool" (navigator (find* "Datacenter" dcname))))
