 ;{:args ("i" "in" "nums"), :tag-name "for", :tag-type :expr}
 
 #_(read-tag-info (java.io.StringReader. "{ nums }}"))
-;{:tag-value "nums", :tag-type :value}
 
-(defn tag-content [end-tag rdr]
-  (let [content (transient [])
-        buf (StringBuilder.)]
-    (loop [ch (read-char rdr)]
-      (if (= tag-open ch)
-        (let [{:keys [tag-name tag-type] :as tag} (read-tag-info rdr)]
-          (when (not= end-tag tag-name)
-            (conj! content (.toString buf))
-            (.setLength buf 0)
-            (conj! content (if (= :filter tag-type)
-                             (filter-tag tag)
-                             (expr-tag tag rdr)))
-            (recur (read-char rdr))))
+(defn parse-tag [{:keys [tag-type] :as tag} rdr]
+  (if (= :filter tag-type)
+    (filter-tag tag)
+    (expr-tag tag rdr)))
+
+(defn tag-content [rdr & end-tags]
+  (let [buf (StringBuilder.)]    
+    (loop [ch       (read-char rdr)
+           tags     {}
+           content  []
+           end-tags end-tags]
+      (cond 
+        (empty? end-tags)
+        tags 
+        
+        (= tag-open ch)
+        (let [{:keys [tag-name tag-type] :as tag} (read-tag-info rdr)]            
+          (if (some #{tag-name} end-tags)              
+            (let [tags     (assoc tags tag-name (conj content (.toString buf)))
+                  end-tags (rest (drop-while #(not= tag-name %) end-tags))]                                
+              (.setLength buf 0)
+              (recur (read-char rdr) tags [] end-tags))
+            (let [content (-> content 
+                                  (conj (.toString buf))
+                                  (conj (parse-tag tag rdr)))]
+              (.setLength buf 0)
+              (recur (read-char rdr) tags content end-tags))))
+        :else
         (do
           (.append buf ch)
-          (recur (read-char rdr)))))
-    (conj! content (.toString buf))
-    (persistent! content)))
+          (recur (read-char rdr) tags content end-tags))))))
 
-#_(tag-content "endfor" (java.io.StringReader. "foo {{name}} bar {% endfor %}"))
+#_(tag-content (java.io.StringReader. "foo bar {%else%} baz{% endif %}") :else :endif)
+#_(tag-content (java.io.StringReader. "foo {{name}} bar  baz {{test}} bat{% endfor %}") :endfor)
 
-#_(render (tag-content "endfor" (java.io.StringReader. "foo {{name.first}} bar {% endfor %}")) {:name {:first "Bob"}})
+#_(render (tag-content (java.io.StringReader. "foo {{name.first}} bar {% endfor %}") :endfor) {:name {:first "Bob"}})
 ;"foo Bob bar "
 
 (defn handle-tag [rdr]
   (let [tag (read-tag-info rdr)]
-    (if (= :filter (:tag-type tag))
-      (filter-tag tag)
-      (expr-tag tag rdr))))
+    (parse-tag tag rdr)))
 
 (defn parse [file]
   (with-open [rdr (clojure.java.io/reader file)]

           ch2 (read-char rdr)]
      (when-not (and (or (= filter-close ch1) (= tag-second ch1))
                     (= tag-close ch2))
        (.append buf ch1)        
        (recur ch2 (read-char rdr))))    
    (let [content (->>  (.split (.toString buf ) " ") (remove empty?) (map (memfn trim)))]
      (merge {:tag-type tag-type}
             (if (= :filter tag-type)

            (if (= tag-open ch)
              (do
                ;we hit a tag so we append the buffer content to the template
                ; and empty the buffer, then we proceed to parse the tag
                (conj! template (.toString buf))
                (.setLength buf 0)
                (conj! template (handle-tag rdr))
