     (cond
       (is-scalar-field-type? field-type) result
       (is-enum-field-type? field-type) result
-      (is-object-field-type? field-type) (log/spy (execute-fields context type-meta-fn field-type result sub-selection-set fragments))
-      (is-list-field-type? field-type) (log/spy (map #(execute-fields context type-meta-fn (type-meta-fn (:innerType field-type)) % sub-selection-set fragments) result))
-      (is-not-null-type? field-type) (log/spy (let [not-null-result (complete-value context type-meta-fn (type-meta-fn (:innerType field-type)) result sub-selection-set fragments)]
+      (is-object-field-type? field-type) (log/spy (execute-fields context schema resolver-fn field-type result sub-selection-set fragments))
+      (is-list-field-type? field-type) (log/spy (map #(execute-fields context schema resolver-fn (type/get-type-in-schema schema (:innerType field-type)) % sub-selection-set fragments) result))
+      (is-not-null-type? field-type) (log/spy (let [not-null-result (complete-value context schema resolver-fn (type/get-type-in-schema schema (:innerType field-type)) result sub-selection-set fragments)]
                                                 (if not-null-result
                                                   not-null-result
                                                   (throw (ex-info (format "NOT_NULL type %s returns null." field-type {:field-type field-type}))))))
       :else (throw (ex-info (format "Unhandled field type %s." field-type) {:field-type field-type})))))
 
-(defn get-field-entry [context type-meta-fn parent-type parent-object field fragments]
+(defn get-field-entry [context schema resolver-fn parent-type parent-object field fragments]
   (log/debug "*** get-field-entry: " field)
   (log/debug "get-field-entry: fragments: " fragments)
   (log/debug "get-field-entry: parent-object: " parent-object)
   (let [first-field-selection field
         response-key (get-selection-name first-field-selection)
-        field-type (get-field-type-from-object-type type-meta-fn parent-type first-field-selection)
+        field-type (get-field-type-from-object-type schema resolver-fn parent-type first-field-selection)
         inner-type (:innerType field-type)
-        inner-field-type (when inner-type (type-meta-fn inner-type))
+        inner-field-type (when inner-type (type/get-type-in-schema schema inner-type))
         field-entry first-field-selection]
     (log/debug "field-type" field-type)
     (if (not (nil? field-type))
-      (let [resolved-object (resolve-field-on-object context parent-object field-type inner-field-type field-entry)
+      (let [resolved-object (resolve-field-on-object context schema resolver-fn parent-object field-type inner-field-type field-entry)
             field-selection-set (get-field-selection-set field)
             fields (collect-fields field-type field-selection-set fragments)]
         (log/debug "get-field-entry: fields: " fields)

                  (let [response-key (get-selection-name field)
                        ;; field-type (get-field-type-from-object-type parent-type field)
                        ;; resolved-object (resolve-field-on-object field-type root-value field)
                        field-entry (get-field-entry context type-meta-fn parent-type root-value field fragments)]
                    (log/spy field-entry)))
                fields)))

(defn execute-query [context query type-meta-fn fragments]
  (let [selection-set (:selection-set query)
        _ (log/debug "fragments: " fragments)
        object-type (type-meta-fn :query)
        fields (collect-fields object-type selection-set fragments)]
    (execute-fields context type-meta-fn object-type :root fields fragments)))

(defn execute-definition
  [context definition type-meta-fn]
  (log/debug "*** execute-definition: " definition)
  (let [operation (:operation-definition definition)
        operation-type (:operation-type operation)
        fragments (:fragments definition)]
    (log/debug "*** execute-definition: fragments: " fragments)
    (case operation-type
      "query" (log/spy (execute-query context operation type-meta-fn fragments))
      (throw (ex-info (format "Unhandled operation root type: %s." operation-type) {})))))

(defn execute
  [context document type-meta-fn]
  (let [root (first document)
        definitions (rest document)]
    (if (not (= root :document))
      (throw (ex-info (format "Root(%s) is not a valid document" root) {}))
      {:data (into {} (log/spy (map (fn [definition]
                                      (execute-definition context definition type-meta-fn)) definitions)))})))

(comment
  (execute nil (parser/transform (parser/parse "query {user {id}}")) (graphql-clj.type/create-type-meta-fn graphql-clj.type/demo-schema))


(defn get-field-type-from-object-type
  "FIXME"
  [schema resolver-fn object-type field-selection]
  (log/debug (format "get-field-type-from-object-type: object-type: %s." object-type))
  (log/debug (format "get-field-type-from-object-type: field-selection: %s." field-selection))
  (let [field-name (get-selection-object-name field-selection)
