     (assert root-type "No root type found in schema.")
     (if (seq var-errors)
       [var-errors nil]
-      (execute-fields selection-set (assoc state :variables updated-variables) root-type :root))))
+      (execute-fields selection-set (assoc state :variables updated-variables) root-type {:vals :root}))))
 
 (defn- execute-document
   [document state]

(defn- execute-field
  "return vector of [errors field]"
  [selection field-map state parent-type-name parent-value]
  (let [selection-name (:name selection)
        field-def (get field-map selection-name)
        _ (assert selection-name (format "No name for selection: %s." selection))

                  (into {}))]
    (merge default-args args)))

(defn validate-result-format
  [result]
  (println "validate-result-format:" result)
  (if (map? result)
    (let [errors (:errors result)
          vals (:vals result)]
      (if (and (or (empty? errors)
                   (map? (first errors)))
               (or (contains? result :errors)
                   (contains? result :vals)))
        result
        (throw (ex-info "result format is incorrect" {:result result}))))
    (throw (ex-info "result is not a map." {:result result}))))

(defn- resolve-field-on-object
  [{:keys [resolver-fn name arguments] :as field-entry} field-def {:keys [context resolver variables] :as state} parent-type-name parent-result]
  (assert field-entry (format "field-entry is nil! parent-type-name: %s." parent-type-name))
  (assert field-def (format "field-def is nil!"))
  (assert (validate-result-format parent-result) "parent-result is not valid.")
  (let [resolve (or resolver-fn
                    (resolver (str parent-type-name) (str name)))
        default-arguments (:arguments field-def)]
    (assert resolve (format "Resolver is nil: parent-type-name:%s, name:%s." parent-type-name name))
    {:vals (resolve context parent-result (args arguments default-arguments variables))}))

(declare execute-fields)

(defn- rollup-errors
  "For list of [errors result], accumunate errors and flatten to one
  list as new-errors, and accomunate result and flatten to another
  list as new-results, return [new-erros new-results]"
  [result]
  (let [errors (->> result
                    (filter :errors)
                    (map :errors)
                    flatten
                    vec)
        vals (->> result
                  (filter :vals)
                  (map :vals)
                  vec)
        rollup-result {:errors errors
                       :vals vals}]
    (prn "rollup-result:BEGIN:" rollup-result ":END")
    (validate-result-format rollup-result)))

(defn- complete-value
  "return pair of errors and result"
  [{:keys [selection-set name type resolved-type] :as field-entry} {:keys [schema] :as state} {:keys [errors vals] :as passing-result}]
  (assert (validate-result-format passing-result) "complete-value passing-result is not valid.")
  (when (and (:required resolved-type) (nil? vals))
    (throw (ex-info (format "NOT_NULL field \"%s\" assigned a null value." name)
                    {:errors [{:message (format "NOT_NULL field \"%s\" assigned a null value." name)}]})))
  (assert type (format "type if nil for field(%s)." name))
  (let [type-name (:name type)
        tag (:tag type)
        inner-type (:inner-type type)
        result (when vals
                 (cond
                   (#{:scalar-definition :union-definition :enum-definition} tag) passing-result
                   (#{:type-definition} tag) (execute-fields selection-set state type-name passing-result)
                   (#{:interface-definition} tag) (execute-fields selection-set state type-name passing-result)
                   (#{:basic-type} tag) (let [unwrapped-type (get-in schema [:type-map type-name])]
                                          (complete-value (assoc field-entry :type unwrapped-type) state passing-result))
                   (#{:list-type} tag) (do
                                         (let [list-result (map #(complete-value {:selection-set selection-set
                                                                                  :type inner-type
                                                                                  :require (:required type)} state %)
                                                                ;; Wrap value in right format
                                                                (map (fn [val] {:vals val}) vals))
                                               _ (prn "list-result:" list-result)
                                               rollup-result (rollup-errors list-result)]
                                           (prn "rollup-result:" rollup-result)
                                           rollup-result))
                   :else (gerror/throw-error (format "Unhandled field(%s) type: %s%n field-entry:%s%n" name type field-entry))))]
    (prn "complete-result:" result)
    result))

(defn- get-field-entry [{:keys [alias name field-name] :as selection} field-def state parent-type-name parent-result]
  (assert selection "selection is nil!")
  (assert field-def (format "field-def is nil for selection: %s." selection))
  (assert (validate-result-format parent-result) "parent-result is not valid.")
  (let [{:keys [errors result] :as completed-value} (->> (resolve-field-on-object selection field-def state parent-type-name parent-result)
                                                         (complete-value selection state))]
    (prn "complete-value:" completed-value)
    {:errors errors
     :vals [(str (or alias name field-name)) result]}))

(defn- get-field-type
  [schema parent-type-name field-name]
