I left a comment on a old commit of yours (that I think github dropped?). In any case, you can ignore it now and I'll repeat it here.

It would be best to avoid calling "collect()" if possible since the pulls all the data into the driver for processing. It's better to push the processing out the executors. I would recommend using "aggregate" here similarlu to how we use "aggregate" in the FlagStat object. The aggregate call would return a SequenceDictionary. The aggregate command allows you to reuse the object for better performance (which the current FlagStat doesn't -- we can process the flags from a whole genome in less than a minute so I haven't taken the time to rewrite it yet).

````
  /**
   * Aggregate the elements of each partition, and then the results for all the partitions, using
   * given combine functions and a neutral "zero value". This function can return a different result
   * type, U, than the type of this RDD, T. Thus, we need one operation for merging a T into an U
   * and one operation for merging two U's, as in scala.TraversableOnce. Both of these functions are
   * allowed to modify and return their first argument instead of creating a new U to avoid memory
   * allocation.
   */
````

It would be nice to test this functionality on a whole genome if you have a few lying around. If not, I might be able to.