@Override
	public synchronized void handlePeerReady(SharingPeer peer) {
		ArrayList<Piece> choice = new ArrayList<Piece>(
				SharedTorrent.RAREST_PIECE_JITTER);

		BitSet interesting = peer.getAvailablePieces();
		interesting.andNot(this.completedPieces);
		interesting.andNot(this.requestedPieces);

		logger.trace("Peer " + peer + " is ready and has " +
				interesting.cardinality() + " interesting piece(s).");
		logger.trace("Peer has " + peer.getAvailablePieces().cardinality() +
				" piece(s), we have " + this.completedPieces.cardinality() +
				" piece(s) and " + this.requestedPieces.cardinality() +
				" outstanding request(s): " + this.requestedPieces + ".");

		// Bail out immediately if the peer has no interesting pieces
		if (interesting.cardinality() == 0) {
			return;
		}

		// Extract the RAREST_PIECE_JITTER rarest pieces from the interesting
		// pieces of this peer.
		for (Piece piece : this.rarest) {
			if (interesting.get(piece.getIndex())) {
				choice.add(piece);
				if (choice.size() == RAREST_PIECE_JITTER) {
					break;
				}
			}
		}

		Piece chosen = choice.get(this.random.nextInt(
					Math.min(choice.size(),
						SharedTorrent.RAREST_PIECE_JITTER)));
		this.requestedPieces.set(chosen.getIndex());
		logger.trace("Requesting " + chosen + " from " + peer +
				", we now have " + this.requestedPieces.cardinality() +
				" outstanding request(s): " + this.requestedPieces + ".");
		peer.downloadPiece(chosen);
	}