private ArrayList<Card> pickNRandomDifferentCards(int nCards) {
    if (nCards > 5) {
      throw new IllegalArgumentException("Don't yet know how to generate more than 5 random cards");
    }

    TreeSet<Rank> ranks = new TreeSet<Rank>();

    ArrayList<Card> cards = new ArrayList<Card>();

    while (ranks.size() != nCards) {
      Rank randomRank = Rank.getRandomRank();

      if (ranks.contains(randomRank)) {
        continue;
      }
      ranks.add(randomRank);

      if (ranks.size() == 5) {
        Iterator<Rank> iRank = ranks.iterator();
        boolean straight = true;
        Rank previousRank = iRank.next();
        while (iRank.hasNext()) {
          Rank nextRank = iRank.next();
          // annoying edge case of 2-3-4-5-A

          if (previousRank.addToRank(1) != nextRank) {
            if (!(previousRank == Rank.FIVE && nextRank == Rank.ACE)) {
              straight = false;
              break;
            }
          }
          previousRank = nextRank;
        }
        // make sure we don't accidentally crate a straight
        if (straight) {
          ranks.remove(randomRank);
          continue;
        }
      }
    }

    TreeSet<Suit> suits = new TreeSet<Suit>();

    for (Rank randomRank : ranks) {
      Suit randomSuit = Suit.getRandomSuit();
      // make sure that there are more than one suit
      while (suits.size() == 1 && suits.contains(randomSuit)) {
        randomSuit = Suit.getRandomSuit();
      }
      suits.add(randomSuit);

      Card card = Card.from(randomRank, randomSuit);
      cards.add(card);
    }

    return cards;
  }
  private IHand generateRandomFullHouse(StandardDeckFactory deckFactory) {

    SortedHand randomHand = new SortedHand();

    Rank randomTrips = Rank.getRandomRank();
    Rank randomPair = null;
    while ((randomPair = Rank.getRandomRank()) == randomTrips) {}

    IDeck deck = deckFactory.build();
    ImmutableSortedSet.Builder<Card> builder =
        ImmutableSortedSet.orderedBy(new Card.RankThenSuitComparer());

    builder.add(deck.pickRandom(randomTrips));
    builder.add(deck.pickRandom(randomTrips));
    builder.add(deck.pickRandom(randomTrips));
    builder.add(deck.pickRandom(randomPair));
    builder.add(deck.pickRandom(randomPair));

    return new SortedHand(builder.build());
  }
  private IHand generateRandomStraight() {

    Rank randomRank = Rank.getRandomRank(Rank.TEN);

    ImmutableSortedSet.Builder<Card> builder =
        ImmutableSortedSet.orderedBy(new Card.RankThenSuitComparer());

    builder.add(Card.from(randomRank, Suit.getRandomSuit()));
    builder.add(Card.from(randomRank.addToRank(1), Suit.getRandomSuit()));
    builder.add(Card.from(randomRank.addToRank(2), Suit.getRandomSuit()));
    builder.add(Card.from(randomRank.addToRank(3), Suit.SPADES));
    builder.add(Card.from(randomRank.addToRank(4), Suit.HEARTS));

    return new SortedHand(builder.build());
  }
  private IHand generateRandomFourOfAKind(StandardDeckFactory deckFactory) {

    SortedHand randomHand = new SortedHand();

    Rank randomRank = Rank.getRandomRank();

    IDeck deck = deckFactory.build();
    ImmutableSortedSet.Builder<Card> builder =
        ImmutableSortedSet.orderedBy(new Card.RankThenSuitComparer());

    builder.add(deck.pickRandom(randomRank));
    builder.add(deck.pickRandom(randomRank));
    builder.add(deck.pickRandom(randomRank));
    builder.add(deck.pickRandom(randomRank));
    builder.add(deck.dealTopCard());

    return new SortedHand(builder.build());
  }