 
 (defn metamodel [#^Model src-model]
   (let [metametadata (seq-metadata 1)
-	metamodel (model (str "Meta-" (.getName src-model)) nil metametadata)]
+	prefix (.getName src-model)
+	prefix-fn (fn [& _] prefix)
+	metamodel (model (str "Meta-" prefix) nil metametadata)]
     (insert *metamodel* metamodel)
-    (insert metamodel [src-model])
-    [metamodel (.getMetadata src-model) []]))
+    (insert metamodel [src-model '()])
+    [metamodel (.getMetadata src-model) prefix []]))
 
 (import org.dada.core.View)
 (import org.dada.core.Update)
 
 (defn meta-view [#^String suffix #^Model src-metamodel f]
+  ;; create a metamodel into which t place our results...
   (let [tgt-metamodel (model (str (.getName src-metamodel) suffix) nil (.getMetadata src-metamodel))]
-  (insert *metamodel* tgt-metamodel)
-  (connect
-   src-metamodel
-   (proxy [View] []
-	  (update [insertions alterations deletions]
-		  (doall (map (fn [#^Update insertion] (apply f tgt-metamodel (.getNewValue insertion))) insertions)))))
-  tgt-metamodel))
-
-(defn split [[#^Model src-metamodel #^Metadata src-metadata #^Collection extra-keys] split-key & [split-key-fn subchain]]
+    ;; register it with the global metamodel
+    (insert *metamodel* tgt-metamodel)
+    ;; view upstream metamodel for arrival of results
+    (connect
+     src-metamodel
+     (proxy [View] []
+	    (update [insertions alterations deletions]
+		    (doall (map (fn [#^Update insertion] (apply f tgt-metamodel (.getNewValue insertion))) insertions)))))
+    tgt-metamodel))
+
+(defn split [[#^Model src-metamodel #^Metadata src-metadata prefix #^Collection extra-keys] split-key & [split-key-fn subchain]]
+  (println "split" prefix "by" split-key ":" extra-keys)
   [(meta-view
-    (str ".split(" split-key")")
+    (str ".split|" split-key)
     src-metamodel
-    (fn [tgt-metamodel model & extra-values]
+    ;; create our own metamodel and view upstream metamodel for new
+    ;; models - each time one is inserted call following fn...
+    (fn [tgt-metamodel model extra-values]
 	(do-split
 	 model
 	 split-key
 	 (or split-key-fn list)
 	 identity
+	 ;; each time a model is inserted into this metamodel, create
+	 ;; a new metamodel for branch of our parent and kick off a
+	 ;; fresh split into it...
 	 (fn [#^Model model extra-value]
-	     (let [model-entry (list* model (concat extra-values [extra-value]))]
+	     (let [model-entry (list model (concat extra-values [extra-value]))]
 	       (insert tgt-metamodel model-entry)
 	       (insert *metamodel* model)
 	       (if subchain

			     count-key
			     extra-values)]
	    (insert *metamodel* count-model)
	    (insert tgt-metamodel (list* count-model extra-values))
	    (connect src-model count-model))))
     tgt-metadata
     extra-keys]))


(defn union [[#^Model src-metamodel #^Metadata src-metadata #^Collection extra-keys] & [#^String prefix]]
  (let [tgt-model (model (str (or prefix (name (gensym "UNION"))) ".union()") nil src-metadata)
	tgt-metamodel (meta-view ".union()" src-metamodel (fn [tgt-metamodel src-model & extra-values] (connect src-model tgt-model)))]
    (insert *metamodel* tgt-model)
    (insert tgt-metamodel [tgt-model])
    [tgt-metamodel src-metadata extra-keys]))

(defn pivot-metadata [#^Metadata src-metadata #^Collection keys #^Collection pivot-values value-key]
  (let [value-type (.getAttributeType src-metadata value-key)]

;; pivot-key - e.g. :time
;; pivot-values - e.g. years
;; value-key - e.g. :count(*) - needed to find type of new columns
(defn pivot [[#^Model src-metamodel #^Metadata src-metadata prefix #^Collection extra-keys] pivot-key pivot-values value-key]
  (println "pivot" prefix ":" extra-keys)
  (let [pivot-name (str ".pivot(" value-key "/" pivot-key")")
	pivot-metadata (pivot-metadata src-metadata extra-keys pivot-values value-key)
	tgt-model (PivotModel. 
		   (str prefix pivot-name)
		   src-metadata
		   (fn [old new] new)	;TODO - sort out version-fn
		   value-key
		   pivot-values
		   pivot-metadata)
