private void repositionHand(Player p) {
		PlayerCardsRange curCardRanges = playerIndices[p.getPlayerId()];
		List<Card> hand = p.getHand();
		List<CardEntity> moved = new ArrayList<CardEntity>(hand.size());
		int delta;
		cardsWriteLock.lock();
		try {
			CardRange[] sublists = { curCardRanges.getHandRange(), drawDeckEntitiesRange, discardPileEntitiesRange };
			for (int i = 0; i < sublists.length && moved.size() < hand.size(); i++) {
				CardRange bounds = sublists[i];
				ListIterator<CardEntity> iter = cards.listIterator(bounds.getStart() + bounds.getLength());
				for (int j = bounds.getLength() - 1; j >= 0 && moved.size() < hand.size(); j--) {
					CardEntity ent = iter.previous();
					if (hand.contains(ent.getValue())) {
						iter.remove();
						moved.add(ent);
						bounds.lengthen(-1);
					}
				}
			}
			assert moved.size() == hand.size();
			delta = moved.size() - curCardRanges.getHandRange().getLength();
			Collections.sort(moved, new Comparator<CardEntity>() {
				@Override
				public int compare(CardEntity ent1, CardEntity ent2) {
					return ent1.getValue().getRank().compareTo(ent2.getValue().getRank());
				}
			});

			curCardRanges.getHandRange().lengthen(delta);
			cards.addAll(curCardRanges.getHandRange().getStart(), moved);
		} finally {
			cardsWriteLock.unlock();
		}

		double rot = getRotation(p);
		int i = 0;
		cardsReadLock.lock();
		try {
			final int SEQUENCE_OFFSET = ((GuiPlayer) p).isThinking() ? (curCardRanges.getHandRange().getLength() <= 1 ? 0 : Math.min(HAND_SEQUENCE_MARGIN + cardImages.getCardWidth(), (WIDTH - cardImages.getCardWidth()) / (curCardRanges.getHandRange().getLength() - 1))) : HAND_SEQUENCE_OFFSET;
			int left = -(cardImages.getCardWidth() + SEQUENCE_OFFSET * (hand.size() - 1)) / 2;
			for (i = 0; i < curCardRanges.getHandRange().getLength(); i++) {
				CardEntity c = cards.get(curCardRanges.getHandRange().getStart() + i);
				c.mark(transform(rot, new Point(i * SEQUENCE_OFFSET + left, DISTANCE_FROM_CENTER + cardImages.getCardHeight() + 1)), rot, 1);
				c.reset();
				c.setShow(p.getPlayerId() == model.getLocalPlayerNumber());
			}
		} finally {
			cardsReadLock.unlock();
		}
	}