public static long rankHand(ArrayList<Card> hand){
		if (hand.size() != HAND_SIZE){
			throw new GameException("Hand should be 5 cards : " + hand);
		}

		long rank = -1;
		long[] pairSet;
		long highCard;
		ArrayList<Long> excludes = new ArrayList<Long>();

		sortHand(hand);

		if ( isStraightFlush(hand) ){
			highCard = straightHigh(hand);
			rank = 10000000000000l * highCard;
			return rank;
		}
		if ( ( rank = hasMultiple(hand, -1, QUAD) ) > 0 ){
			excludes.add(rank);
			rank = 1000000000000l * rank + highCard(hand, excludes);
			return rank;
		}
		pairSet = isFullHouse(hand);
		if ( pairSet[0] > 0 ){
			rank = 100000000000l * pairSet[0] + pairSet[1];
			return rank;
		}
		if ( isFlush(hand) ){
			highCard = highCard(hand, excludes);
			excludes.add(highCard);
			rank = (10000000000l * highCard) + kickerValues(hand, excludes, HAND_SIZE - 1);
			return rank;
		}
		if ( isStraight(hand) ){
			rank = 1000000000l * straightHigh(hand);
			return rank;
		}
		if ( ( rank = hasMultiple(hand, -1, TRIPLE) ) > 0 ){
			excludes.add(rank);
			rank *= 100000000l;
			return rank + kickerValues(hand, excludes, HAND_SIZE - 3);
		}
		pairSet = isTwoPair(hand);
		if ( pairSet[0] > 0 ){
			excludes.add(pairSet[0]);
			excludes.add(pairSet[1]);
			rank =  (10000000l * pairSet[0]) + (pairSet[1] * SPREAD) + highCard(hand, excludes);
			return rank;
		}
		if ( ( rank = hasMultiple(hand, -1, PAIR) ) > 0 ){
			excludes.add(rank);
			rank *= 1000000l;
			return rank + kickerValues(hand, excludes, HAND_SIZE - 2);
		}
		else {
			rank = kickerValues(hand, excludes, HAND_SIZE);
			return rank;
		}
	}