         p (.getParameterTypes m)]
         (alength p)))
 
+(defn children [node] (.getChildren node))
+
 (defn pre-tree
   ([f node] (pre-tree f node 1))
   ([f node index]
 
-   (let [children (.getChildren node)
+   (let [children (children node)
          ret (case (arg-count f)
                    1 (f node)
                    2 (f node index))]
 
      (conj 
-           (for [iast-node (.getChildren node)]
+           (for [iast-node (children node)]
              (pre-tree f iast-node (inc index)))
            ret))))
 

  (inc
   (apply max 0
          (map depth
               (.getChildren node)))))

(defn leaf? [node] (empty? (.getChildren node)))

(defn leaves [node]
  (if (leaf? node)
    node
    (flatten (map leaves (.getChildren node)))))

(defn node-str
  "Convert single node to string"
  [node]
  (if (nil? node)
    "nil1"
    (let [stx (.getSyntax node)]
      (if (nil? stx)
        "nil2"
        (.getImage stx)))))

(map node-str (leaves root))

(defn write [node]
  (let [writer (ASTWriter.)]
    (.write writer node)))

(print (write (ancestor 2 (nth (leaves root) 11))))
(println "\n\n")

(defn stringify
  "Convert multiple tree to string"

(defn ancestor
  "Get the nth grandparent of the node"
  [n node]
  (fn-pow #(.getParent %) node (dec n)))

(defn filter-depth
  "Return every sub-tree of size n"
  [n node]
  ;; start from the leaves of the tree and walk upwards n generations
  (let [candidates (distinct (map #(ancestor n %) (leaves node)))]
    ;; candidates may still have deeper branches than the one we came up from
    (filter #(= n (depth %)) candidates)))

(defn type [node]
  (let [name (-> node .getClass .getSimpleName)]
    (nth (re-find #"CPPAST(.*)" name) 1)))


(def filename "/Users/dgopstein/nyu/confusion/atoms/simplifications/2000-natori/nonconfusing.c")
(def root (translation-unit filename))

(defn -main
  [& args]

  (doseq [ancestor (filter-depth 1 root)]
    (println (type ancestor) (write ancestor) "\n-----------------\n\n"))

  )
