   [tree]
   (if (seq? tree)
     (if (> (lrand) @global-node-selection-leaf-probability)
-      (second (rand-nth (filter #(seq? (first %)) (map #(list %1 %2) (all-items tree) (iterate inc 0)))))
+      (second (lrand-nth (filter #(seq? (first %)) (map #(list %1 %2) (all-items tree) (iterate inc 0)))))
       (let [indexed-leaves (filter #(not (seq? (first %))) (map #(list %1 %2) (all-items tree) (iterate inc 0)))]
-        (if (empty? indexed-leaves) 0 (second (rand-nth indexed-leaves)))))
+        (if (empty? indexed-leaves) 0 (second (lrand-nth indexed-leaves)))))
     0))
 
 (defn choose-node-index-by-tournament

           gaussian-mutation-standard-deviation 0.1
	   reuse-errors true
	   problem-specific-report default-problem-specific-report
           }}]
  ;; set globals from parameters
  (reset! global-atom-generators atom-generators)
  (reset! global-max-points-in-program max-points)
  (reset! global-evalpush-limit evalpush-limit)
  (reset! global-evalpush-time-limit evalpush-time-limit)
  (reset! global-node-selection-method node-selection-method)
  (reset! global-node-selection-leaf-probability node-selection-leaf-probability)
  (reset! global-node-selection-tournament-size node-selection-tournament-size)
  (reset! global-pop-when-tagging pop-when-tagging)
  (reset! global-reuse-errors reuse-errors)
  (printf "\nStarting PushGP run.\n\n") (flush)
  (print-params 
    (error-function error-threshold population-size max-points atom-generators max-generations 
      mutation-probability mutation-max-points crossover-probability
      simplification-probability gaussian-mutation-probability 
      gaussian-mutation-per-number-mutation-probability gaussian-mutation-standard-deviation
      tournament-size report-simplifications final-report-simplifications
      trivial-geography-radius decimation-ratio decimation-tournament-size evalpush-limit
      evalpush-time-limit node-selection-method node-selection-tournament-size
      node-selection-leaf-probability pop-when-tagging reuse-errors
      ))
  (printf "\nGenerating initial population...\n") (flush)
  (let [pop-agents (vec (doall (for [_ (range population-size)] 
                                 (agent (make-individual 
                                          :program (random-code max-points atom-generators))
                                   :error-handler (fn [agnt except] (println except))))))
        child-agents (vec (doall (for [_ (range population-size)]
                                   (agent (make-individual)
                                     :error-handler (fn [agnt except] (println except))))))
        rand-gens (vec (doall (for [_ (range population-size)]
                                (java.util.Random.))))]
    (loop [generation 0]
      (printf "\n\n-----\nProcessing generation: %s\nComputing errors..." generation) (flush)
      (dorun (map #(send % evaluate-individual error-function %2) pop-agents rand-gens))
      (apply await pop-agents) ;; SYNCHRONIZE ; might this need a dorun?
      (printf "\nDone computing errors.") (flush)
      
;; some debugging code trying to track down nil agent results.... leaving in case not fixed
;(println (map :total-error (vec (doall (map deref pop-agents)))))(flush) ;***
;(loop [ers (map :total-error (vec (doall (map deref pop-agents))))] ;***
;  (when (some not ers) 
;    (println (map :total-error (vec (doall (map deref pop-agents)))))(flush) 
;    (recur (map :total-error (vec (doall (map deref pop-agents)))))))
      
      ;; report and check for success
      (let [best (report (vec (doall (map deref pop-agents))) generation error-function 
			 report-simplifications problem-specific-report)]
        (if (<= (:total-error best) error-threshold)
          (do (printf "\n\nSUCCESS at generation %s\nSuccessful program: %s\nErrors: %s\nTotal error: %s\nHistory: %s\nSize: %s\n\n"
                generation (not-lazy (:program best)) (not-lazy (:errors best)) (:total-error best) 
                (not-lazy (:history best)) (count-points (:program best)))
            (when print-ancestors-of-solution
              (printf "\nAncestors of solution:\n")
              (println (:ancestors best)))
            (auto-simplify best error-function final-report-simplifications true 500))
          (do (if (>= generation max-generations)
                (printf "\nFAILURE\n")
                (do (printf "\nProducing offspring...") (flush)
                  (let [pop (decimate (vec (doall (map deref pop-agents))) 
                              (int (* decimation-ratio population-size))
                              decimation-tournament-size 
                              trivial-geography-radius)]
                    (dotimes [i population-size]
                      (send (nth child-agents i) 
                        breed i (nth rand-gens i) pop error-function population-size max-points atom-generators 
                        mutation-probability mutation-max-points crossover-probability 
                        simplification-probability tournament-size reproduction-simplifications 
                        trivial-geography-radius gaussian-mutation-probability 
                        gaussian-mutation-per-number-mutation-probability gaussian-mutation-standard-deviation)))
                  (apply await child-agents) ;; SYNCHRONIZE
                  (printf "\nInstalling next generation...") (flush)
                  (dotimes [i population-size]
                    (send (nth pop-agents i) (fn [av] (deref (nth child-agents i)))))
                  (apply await pop-agents) ;; SYNCHRONIZE
                  (recur (inc generation))))))))))

(defn pushgp-map
  "Calls pushgp with the args in argmap."

  "Returns a random expression containing the given number of points."
  [points atom-generators]
  (if (< points 2)
    (let [element (lrand-nth atom-generators)]
      (if (fn? element)
        (element)
        element))
