                                   "  caused by=" (.getMessage e)))))))
 
 (defn validate-parse-leaf
-  "Validate & parse a leaf msg value given a leaf schema (Enlive-format)."
-  [schema val]
+  "Validate & parse a leaf msg value given a leaf leaf-schema (Enlive-format)."
+  [leaf-schema leaf-val]
   (try
-    (assert (= (grab :tag schema) :leaf))
-    (let [leaf-name-schema (keyword (get-leaf schema [:leaf :identifier]))
-          leaf-name-val    (grab :tag val)
+    (assert (= (grab :tag leaf-schema) :leaf))
+    (let [leaf-name-schema (keyword (get-leaf leaf-schema [:leaf :identifier]))
+          leaf-name-val    (grab :tag leaf-val)
           xx              (assert (= leaf-name-schema leaf-name-val))
           ; #todo does not yet verify any attrs;  what rules?
-          parser-fn       (leaf-schema->parser schema)
-          parsed-value    (parser-fn (only (grab :content val)))]
+          parser-fn       (leaf-schema->parser leaf-schema)
+          parsed-value    (parser-fn (only (grab :content leaf-val)))]
       parsed-value)
     (catch Exception e
-      (throw (RuntimeException. (str "validate-parse-val: failed for schema=" schema \newline
-                                  "  val=" val \newline
+      (throw (RuntimeException. (str "validate-parse-leaf-val: failed for leaf-schema=" leaf-schema \newline
+                                  "  leaf-val=" leaf-val \newline
                                   "  caused by=" (.getMessage e)))))))
 
 (def rpc-fn-map
-  {
-   :add  (fn fn-add [& args] (apply + args))
+  {:add  (fn fn-add [& args] (apply + args))
    :mult (fn fn-mult [& args] (apply * args))
-   :pow  (fn fn-power [x y] (Math/pow x y)) })
-
-(defn leaf-schema->parser
-  [schema]
+   :pow  (fn fn-power [x y] (Math/pow x y))})
+
+(defn validate-parse-rpc
+  "Validate & parse a rpc msg valueue given an rpc rpc-schema (Enlive-format)."
+  [rpc-schema rpc-msg]
   (try
-    (let [type      (get-leaf schema [:leaf :type :identifier]) ; eg "decimal64"
-          parser-fn (grab type parser-map)]
-      parser-fn)
-    (catch Exception e
-      (throw (RuntimeException. (str "leaf-schema->parser: failed for schema=" schema \newline
-                                  "  caused by=" (.getMessage e)))))))
-(defn validate-parse-rpc
-  "Validate & parse a rpc msg valueue given an rpc schema (Enlive-format)."
-  [schema value]
-  (try
-   ;(spyx-pretty schema)
-   ;(spyx-pretty value)
-    (assert (= :rpc (grab :tag schema) (grab :tag value)))
-    (let [rpc-attrs       (grab :attrs value)
-          rpc-tag-schema  (keyword (get-leaf schema [:rpc :identifier]))
-          rpc-value       (get-leaf value [:rpc])
+    ; (spyx-pretty rpc-schema)
+    ; (spyx-pretty rpc-msg)
+    (assert (= :rpc (grab :tag rpc-schema) (grab :tag rpc-msg)))
+    (let [rpc-attrs       (grab :attrs rpc-msg)
+          rpc-tag-schema  (keyword (get-leaf rpc-schema [:rpc :identifier]))
+          rpc-value       (get-leaf rpc-msg [:rpc])
           rpc-value-tag   (grab :tag rpc-value)
           rpc-value-attrs (grab :attrs rpc-value)
           xx              (assert (= rpc-tag-schema rpc-value-tag))
           ; #todo does not yet verify any attrs ;  what rules?
-          fn-args-schema  (grab :content (get-tree schema [:rpc :input]))
-          fn-args-value   (grab :content (get-tree value [:rpc rpc-value-tag]))
+          fn-args-schema  (grab :content (get-tree rpc-schema [:rpc :input]))
+          fn-args-value   (grab :content (get-tree rpc-msg [:rpc rpc-value-tag]))
           parsed-args     (mapv validate-parse-leaf fn-args-schema fn-args-value)
           rpc-fn          (grab rpc-value-tag rpc-fn-map)
           rpc-fn-result   (apply rpc-fn parsed-args)

                           :attrs   rpc-attrs
                           :content [{:tag     :data
                                      :attrs   {}
                                      :content [rpc-fn-result]}]} ]
       rpc-result)
    (catch Exception e
      (throw (RuntimeException. (str "validate-parse-leaf: failed for schema=" schema \newline
                                  "  value=" value \newline
                                  "  caused by=" (.getMessage e)))))))

(def leaf-schema-1 (hiccup->enlive [:leaf [:identifier "x"] [:type [:identifier "decimal64"]]]))

(def rpc-msg-id (atom 100))
(def rpc-deliver-map (atom {}))

(s/defn rpc-call-2 :- s/Any
  [msg :- tsk/KeyMap]
  (let [rpc-msg-id     (swap! rpc-msg-id inc)
        msg            (glue msg {:attrs {:message-id rpc-msg-id
                                          :xmlns      "urn:ietf:params:xml:ns:netconf:base:1.0"}})
        result-promise (promise)]
    (swap! rpc-deliver-map glue {rpc-msg-id result-promise}) ;  #todo temp!

    (future         ; Simulate calling out to http server in another thread
      (try
        (Thread/sleep *rpc-delay-simulated-ms*) ; simulated network delay
        (let [rpc-result        (validate-parse-rpc rpc-schema msg)
              rpc-reply-msg-id  (fetch-in rpc-result [:attrs :message-id])
              fpc-reply-promise (grab rpc-reply-msg-id @rpc-deliver-map)]
          (deliver fpc-reply-promise rpc-result))
        (catch Exception e
          (deliver result-promise ; deliver any exception to caller
            (RuntimeException. (str "rpc-call-2: failed  msg=" msg \newline
                                 "  caused by=" (.getMessage e)))))))

    result-promise  ; return promise to caller immediately
    ))

(defn add-2 [x y]
  (let [result-promise (rpc-call-2
