           (.write (name tag))
           (.write ">"))))))
 
+(defn emit-comment [^Comment c ^Writer out]
+  (doto out
+    (.write "<!--")
+    (.write (xml-escape-comment (.text c)))
+    (.write "-->")))
+
+(defn emit-cdata [^CData cd ^Writer out]
+  (when (.contains (.text cd) "]]>")
+    (throw (IllegalArgumentException. "Illegal end sequence in CDATA text.")))
+  (doto out
+    (.write "<![CDATA[")
+    (.write (.text cd))
+    (.write "]]>")))
+
+(defn emit-pi [^PI pi ^Writer out]
+  (let [{:keys [target text]} pi]
+    ;; TODO - validate target: http://www.w3.org/TR/REC-xml/#sec-pi
+    (when (.contains text "?>")
+      (throw (IllegalArgumentException. "Illegal end sequence in processing instruction " target)))
+    (doto out
+      (.write "<?")
+      (.write target)
+      (.write " ")
+      (.write text)
+      (.write "?>"))))
+
+
 (extend-protocol XMLWritable
 
   nil

         (apply concat))))


(defn ignore
  "Filters out events of the given types."
  [events & event-types]

  "Given a source of XML, returns a sequence of events, in the form of
  vectors. See xml-handler."
  [in]
  (let [^InputSource in (as-input-source in)
        parser  (XMLReaderFactory/createXMLReader)
        [put events] (pipe/pipe)
        handler (xml-handler put)]
    (.setContentHandler parser handler)
    (.setProperty parser "http://xml.org/sax/properties/lexical-handler" handler)
