public static long eval(CardSet cs) {
    final long enc = HandEvaluator.encode(cs);
    int val = 0;

    switch (cs.size()) {
      case 2:
        final int r0 = cs.get(0).getRank().ordinal();
        final int r1 = cs.get(1).getRank().ordinal();
        final int s0 = cs.get(0).getSuit().ordinal();
        final int s1 = cs.get(1).getSuit().ordinal();
        if (r0 == r1) {
          val = 1 << 9;
        }
        val |= Math.max(r0, r1) << 5;
        val |= Math.min(r0, r1) << 1;
        if (s0 == s1) {
          val |= 1;
        }
        break;

      case 5:
        val = HandEvaluator.hand5Eval(enc);
        break;

      case 6:
        val = HandEvaluator.hand6Eval(enc);
        break;

      case 7:
        val = HandEvaluator.hand7Eval(enc);
        break;
    }

    return val;
  }
  // initializer block
  static {
    int mask, bitCount;
    int shiftReg, i;
    int value;

    for (mask = 1; mask < HandEvaluator.ARRAY_SIZE; ++mask) {
      bitCount = 0;
      shiftReg = mask;
      for (i = HandEvaluator.ACE_RANK - 1; i > 0; --i, shiftReg <<= 1) {
        if ((shiftReg & 0x1000) != 0) {
          switch (++bitCount) {
            case 1:
              HandEvaluator.hiTopRankTWO_PAIR[mask] =
                  HandEvaluator.TWO_PAIR | ((i + 1) << HandEvaluator.TOP_SHIFT);
              HandEvaluator.hiBotRank[mask] = (i + 1) << HandEvaluator.BOT_SHIFT;
              HandEvaluator.hiRankMask[mask] = 0x1000 >> (HandEvaluator.ACE_RANK - 1 - i);
              break;
            case 2:
              HandEvaluator.hi2RanksMask[mask] =
                  (shiftReg & 0x03FFF000) >> (HandEvaluator.ACE_RANK - 1 - i);
              break;
            case 3:
              HandEvaluator.hi3RanksMask[mask] =
                  (shiftReg & 0x03FFF000) >> (HandEvaluator.ACE_RANK - 1 - i);
              break;
            case 5:
              HandEvaluator.hi5RanksMask[mask] =
                  (shiftReg & 0x03FFF000) >> (HandEvaluator.ACE_RANK - 1 - i);
          }
        }
      }
      HandEvaluator.nbrOfRanks[mask] = bitCount;

      bitCount = 0;
      /* rotate the 13 bits left to get ace into LS bit */
      /* we don't need to mask the low 13 bits of the result */
      /* as we're going to look only at the low order 8 bits */
      shiftReg = (mask << 1) + ((mask ^ 0x1000) >> 12);
      value = 0;
      for (i = 0; i < 8; ++i, shiftReg >>= 1) {
        if ((shiftReg & 1) != 0) {
          value |= (1 << i); /* undo previous shifts, copy bit */
          if (++bitCount == 5) {
            HandEvaluator.lo5RanksMask[mask] = value;
            break;
          }
          if (bitCount == 3) {
            HandEvaluator.lo3RanksMask[mask] = value;
          }
        }
      }
      HandEvaluator.loEvalOrNo8Low[mask] = (bitCount == 5) ? value : HandEvaluator.NO_8_LOW;
    }
    for (mask = 0x1F00 /* A..T */; mask >= 0x001F /* 6..2 */; mask >>= 1) {
      HandEvaluator.setStraight(mask);
    }
    HandEvaluator.setStraight(HandEvaluator.WHEEL); /* A,5..2 */
  }
 /**
  * Returns a value which can be used as a parameter to one of the HandEval evaluation methods.
  *
  * @param cs a {@link CardSet}
  * @return a value which can be used as a parameter to one of the HandEval evaluation methods. The
  *     value may also be bitwise OR'ed or added to other such values to build an evaluation method
  *     parameter.
  */
 public static long encode(final CardSet cs) {
   long result = 0;
   for (final Card c : cs) {
     result |= HandEvaluator.encode(c);
   }
   return result;
 }
  /**
   * Returns the value of the best 5-card high poker hand from 7 cards.
   *
   * @param hand bit mask with one bit set for each of 7 cards.
   * @return the value of the best 5-card high poker hand.
   */
  public static int hand7Eval(long hand) {
    int i, j, ranks;

    /*
     * The low-order 52 bits of hand contains four 13-bit fields, one
     * field per suit. The high-order 12 bits are clear. Get the
     * respective fields into variables.
     * We don't care which suit is which; we arbitrarily call them c,d,h,s.
     */
    final int c = (int) hand & 0x1FFF;
    final int d = ((int) hand >>> 13) & 0x1FFF;
    final int h = (int) (hand >>> 26) & 0x1FFF;
    final int s = (int) (hand >>> 39);

    switch (HandEvaluator.nbrOfRanks[ranks = c | d | h | s]) {
      case 2:
        /*
         * quads with trips kicker
         */
        i = c & d & h & s; /* bit for quads */
        return HandEvaluator.FOUR_OF_A_KIND | HandEvaluator.hiBotRank[i] | (i ^ ranks);

      case 3:
        /*
         * trips and pair (full house) with non-playing pair,
         * or two trips (full house) with non-playing singleton,
         * or quads with pair and singleton
         */
        /* bits for singleton, if any, and trips, if any: */
        if (HandEvaluator.nbrOfRanks[i = c ^ d ^ h ^ s] == 3) {
          /* two trips (full house) with non-playing singleton */
          if (HandEvaluator.nbrOfRanks[i = c & d] != 2) {
            if (HandEvaluator.nbrOfRanks[i = c & h] != 2) {
              if (HandEvaluator.nbrOfRanks[i = c & s] != 2) {
                if (HandEvaluator.nbrOfRanks[i = d & h] != 2) {
                  if (HandEvaluator.nbrOfRanks[i = d & s] != 2) {
                    i = h & s; /* bits for the trips */
                  }
                }
              }
            }
          }
          return HandEvaluator.FULL_HOUSE
              | HandEvaluator.hiBotRank[i]
              | (i ^ HandEvaluator.hiRankMask[i]);
        }
        if ((j = c & d & h & s) != 0) {
          /* quads with pair and singleton */
          return HandEvaluator.FOUR_OF_A_KIND
              | HandEvaluator.hiBotRank[j]
              | (HandEvaluator.hiRankMask[ranks ^ j]);
        }
        /* trips and pair (full house) with non-playing pair */
        return HandEvaluator.FULL_HOUSE
            | HandEvaluator.hiBotRank[i]
            | (HandEvaluator.hiRankMask[ranks ^ i]);

      case 4:
        /*
         * three pair and singleton,
         * or trips and pair (full house) and two non-playing singletons,
         * or quads with singleton kicker and two non-playing singletons
         */
        i = c ^ d ^ h ^ s; // the bit(s) of the trips, if any, and singleton(s)
        if (HandEvaluator.nbrOfRanks[i] == 1) {
          /* three pair and singleton */
          j = ranks ^ i; /* the three bits for the pairs */
          ranks = HandEvaluator.hiRankMask[j]; /* bit for the top pair */
          j ^= ranks; /* bits for the two bottom pairs */
          return HandEvaluator.hiTopRankTWO_PAIR[ranks]
              | HandEvaluator.hiBotRank[j]
              | HandEvaluator.hiRankMask[(HandEvaluator.hiRankMask[j] ^ j) | i];
        }
        if ((j = c & d & h & s) == 0) {
          // trips and pair (full house) and two non-playing singletons
          i ^= ranks; /* bit for the pair */
          if ((j = (c & d) & (~i)) == 0) {
            j = (h & s) & (~i); /* bit for the trips */
          }
          return HandEvaluator.FULL_HOUSE | HandEvaluator.hiBotRank[j] | i;
        }
        // quads with singleton kicker and two non-playing singletons
        return HandEvaluator.FOUR_OF_A_KIND
            | HandEvaluator.hiBotRank[j]
            | (HandEvaluator.hiRankMask[i]);

      case 5:
        /*
         * flush and/or straight,
         * or two pair and three singletons,
         * or trips and four singletons
         */
        if ((i = HandEvaluator.flushAndOrStraight7(ranks, c, d, h, s)) != 0) {
          return i;
        }
        i = c ^ d ^ h ^ s; // the bits of the trips, if any, and singletons
        if (HandEvaluator.nbrOfRanks[i] != 5) {
          /* two pair and three singletons */
          j = i ^ ranks; /* the two bits for the pairs */
          return HandEvaluator.hiTopRankTWO_PAIR[j]
              | HandEvaluator.hiBotRank[HandEvaluator.hiRankMask[j] ^ j]
              | HandEvaluator.hiRankMask[i];
        }
        /* trips and four singletons */
        if ((j = c & d) == 0) {
          j = h & s;
        }
        return HandEvaluator.THREE_OF_A_KIND
            | HandEvaluator.hiBotRank[j]
            | (HandEvaluator.hi2RanksMask[i ^ j]);

      case 6:
        /*
         * flush and/or straight,
         * or one pair and three kickers and two nonplaying singletons
         */
        if ((i = HandEvaluator.flushAndOrStraight7(ranks, c, d, h, s)) != 0) {
          return i;
        }
        i = c ^ d ^ h ^ s; /* the bits of the five singletons */
        return HandEvaluator.PAIR
            | HandEvaluator.hiBotRank[ranks ^ i]
            | HandEvaluator.hi3RanksMask[i];

      case 7:
        /*
         * flush and/or straight or no pair
         */
        if ((i = HandEvaluator.flushAndOrStraight7(ranks, c, d, h, s)) != 0) {
          return i;
        }
        return /* NO_PAIR | */ HandEvaluator.hi5RanksMask[ranks];
    } /* end switch */

    return 0; /* never reached, but avoids compiler warning */
  }
  /**
   * Returns the value of the best 5-card high poker hand from 6 cards.
   *
   * @param hand bit mask with one bit set for each of 6 cards.
   * @return the value of the best 5-card high poker hand.
   */
  public static int hand6Eval(long hand) {

    final int c = (int) hand & 0x1FFF;
    final int d = ((int) hand >>> 13) & 0x1FFF;
    final int h = (int) (hand >>> 26) & 0x1FFF;
    final int s = (int) (hand >>> 39);

    final int ranks = c | d | h | s;
    int i, j, k;

    switch (HandEvaluator.nbrOfRanks[ranks]) {
      case 2: /*
               * quads with pair kicker,
               * or two trips (full house)
               */
        /* bits for trips, if any: */
        if ((HandEvaluator.nbrOfRanks[i = c ^ d ^ h ^ s]) != 0) {
          /* two trips (full house) */
          return HandEvaluator.FULL_HOUSE
              | HandEvaluator.hiBotRank[i]
              | (i ^ HandEvaluator.hiRankMask[i]);
        }
        /* quads with pair kicker */
        i = c & d & h & s; /* bit for quads */
        return HandEvaluator.FOUR_OF_A_KIND | HandEvaluator.hiBotRank[i] | (i ^ ranks);

      case 3: /*
               * quads with singleton kicker and non-playing singleton,
               * or full house with non-playing singleton,
               * or two pair with non-playing pair
               */
        if ((c ^ d ^ h ^ s) == 0) {
          /* no trips or singletons: three pair */
          i = HandEvaluator.hiRankMask[ranks]; /* bit for the top pair */
          k = ranks ^ i; /* bits for the bottom two pairs */
          j = HandEvaluator.hiRankMask[k]; /* bit for the middle pair */
          return HandEvaluator.hiTopRankTWO_PAIR[i] | HandEvaluator.hiBotRank[j] | (k ^ j);
        }
        if ((i = c & d & h & s) == 0) {
          /* full house with singleton */
          if ((i = c & d & h) == 0) {
            if ((i = c & d & s) == 0) {
              if ((i = c & h & s) == 0) {
                i = d & h & s; /* bit of trips */
              }
            }
          }
          j = c ^ d ^ h ^ s; /*
                                        * the bits of the trips
                                        * and singleton
                                        */
          return HandEvaluator.FULL_HOUSE | HandEvaluator.hiBotRank[i] | (j ^ ranks);
        }
        /* quads with kicker and singleton */
        return HandEvaluator.FOUR_OF_A_KIND
            | HandEvaluator.hiBotRank[i]
            | (HandEvaluator.hiRankMask[i ^ ranks]);

      case 4: /*
               * trips and three singletons,
               * or two pair and two singletons
               */
        if ((i = c ^ d ^ h ^ s) != ranks) {
          /* two pair and two singletons */
          j = i ^ ranks; /* the two bits for the pairs */
          return HandEvaluator.hiTopRankTWO_PAIR[j]
              | HandEvaluator.hiBotRank[HandEvaluator.hiRankMask[j] ^ j]
              | HandEvaluator.hiRankMask[i];
        }
        /* trips and three singletons */
        if ((i = c & d) == 0) {
          i = h & s; /* bit of trips */
        }
        return HandEvaluator.THREE_OF_A_KIND
            | HandEvaluator.hiBotRank[i]
            | (HandEvaluator.hi2RanksMask[i ^ ranks]);

      case 5: /*
               * flush and/or straight,
               * or one pair and three kickers and
               * one non-playing singleton
               */
        if ((i = HandEvaluator.flushAndOrStraight6(ranks, c, d, h, s)) != 0) {
          return i;
        }
        i = c ^ d ^ h ^ s; /* the bits of the four singletons */
        return HandEvaluator.PAIR
            | HandEvaluator.hiBotRank[ranks ^ i]
            | HandEvaluator.hi3RanksMask[i];

      case 6: /* flush and/or straight or no pair */
        if ((i = HandEvaluator.flushAndOrStraight6(ranks, c, d, h, s)) != 0) {
          return i;
        }
        return /* NO_PAIR | */ HandEvaluator.hi5RanksMask[ranks];
    } /* end switch */

    return 0; /* never reached, but avoids compiler warning */
  }