    component state which will be merged into the overall state"
   [state uid fns]
   (let [wrapped-fns (for [f fns] (mk-component-fn uid f))]
-    (assoc state :components {uid {:fns fns :state {}}})))
+    (assoc state :components {uid {:fns wrapped-fns :state {}}})))
 
 (println "test mk-component"
          (mk-component {} :my-component [identity]))
+
+(defn mk-system-fn
+  "Returns a function representing a system.
+
+   Has two arrities:
+   - [f] function f is called with state and wrapped to merge the return
+     value of the function with state
+   - [f component-id] function f is called with state, a collection of
+     component functions, and a collection of entity ids that match the
+     given component id. Results are merged with game state."
+  ([f]
+   (fn [state]
+     (deep-merge state (f state (:entities state)))))  
+  ([f component-id]
+   (fn [state]
+     (let [entities (entities-with-component (:entities state) component-id)
+           component-fns (get-component-fns state component-id)]
+       (deep-merge state (f state component-fns entities))))))
+
+(println "test mk-system-fn"
+         ((mk-system-fn (fn [s fns ents] s) :b) {:entities {:a [:b]}}))
+
+(defn integration-test
+  "Test the entire CES implementation with a system that changes component state"
+  []
+  (let [sys-fn (fn [state fns entity-ids]
+                 (apply deep-merge (for [f fns, e entity-ids] (f state e))))
+        test-system (mk-system-fn sys-fn :testable)
+        scenes (-> {}
+                   (mk-scene :test-scene [test-system]))
+        test-fn (fn [component-state entity-id]
+                  (println "testing" entity-id
+                           component-state "->"
+                           (assoc component-state :x
+                                  (inc (or (:x component-state) 0))))
+                  (assoc component-state :x (inc (or (:x component-state) 0))))
+        state (-> {}
+                  (mk-entity :player1 [:testable])
+                  (mk-entity :player2 [:testable])
+                  (mk-component :testable [test-fn]))]
+    (game-loop scenes :test-scene state 0)))
+
+(println "Running integration-test" (integration-test))

   merged into the game state."
  [component-id f]
  (fn [state entity-id]
    (mk-component-state
     component-id
     entity-id
     (f entity-id
        (get-component-state state component-id entity-id)))))

(println "test mk-component-fn"
         ((mk-component-fn :test (fn [& args] (identity {:foo "bar"})))

;; creates a new copy on every change to state in the game loop due to
;; structural sharing


(defn mk-scene
  "Add or update existing scene in the scenes hashmap"
  [scenes-hm uid fns]
  (assoc scenes-hm uid fns))

(println "test add-scene" (mk-scene {} :yo [identity]))

(defn iter-fns
  "Pass an initial value through a collection of functions with the 
