// TODO redesign keep strategy to allow keeping both highest and lowest
        private static BigInteger roll(BigInteger dieType, long dieCount, long keepCount, KeepStrategy keepStrategy)
        {
            if (dieType <= 1) {
                throw new InvalidExpressionException ("invalid die");
            }

            // if the diecount is negative we will roll with the positive diecount, but negate the end result.
            // basically, "-5d6" is treated as "-(5d6)"
            bool negative = false;
            if (dieCount < 0) {
                negative = true;
                dieCount = -dieCount;
            }

            keepCount = Math.Min(keepCount, dieCount);

            // roll the dice and keep them in an array
            BigInteger[] results = new BigInteger[dieCount];
            for (int i = 0; i < dieCount; i++) {
                BigInteger num = new BigInteger ();
                num.genRandomBits (dieType.bitCount (), RAND);
                results [i] = num;
            }

            // add up the results based on the strategy used
            BigInteger result = 0;
            if (keepStrategy == KeepStrategy.ALL) {
                for (int i = 0; i < dieCount; i++) {
                    result += results [i];
                }
            } else { // we are only keeping some, so sort the list
                Array.Sort (results);
                if (keepStrategy == KeepStrategy.HIGHEST) {
                    for (long i = dieCount - 1; i >= dieCount - keepCount; i--) {
                        result += results [i];
                    }
                } else if (keepStrategy == KeepStrategy.LOWEST) {
                    for (int i = 0; i < keepCount; i++) {
                        result += results [i];
                    }
                }
            }
            if (negative) {
                result = -result;
            }
            return result;
        }
 /// <summary>
 /// Constructs a DiceToken using a BigInteger instead of a postfix token list
 /// </summary>
 public DiceToken(BigInteger count, BigInteger type, long keepCount, KeepStrategy strategy, Roller r)
     : this(new List<Token> (), type, keepCount, strategy, r)
 {
     this.countTokens.Add (new NumToken(count));
 }
 /// <summary>
 /// Constructs a DiceToken using a postfix token list as the diecount (allowing expressions determining how many dice to roll)
 /// </summary>
 public DiceToken(List<Token> count, BigInteger type, long keepCount, KeepStrategy strategy, Roller r)
 {
     this.countTokens = count;
     this.type = type;
     this.keepCount = keepCount;
     this.strategy = strategy;
     this.r = r;
 }