private int getRandomChunkNumber() throws NoFreeChunkException {

		try {
			this.rwlock.readLock().lock();

			int chunkCount = this.getNumberOfChunks();

			// try to start from the beginning
			if (!doNotHaveToLoadChunk(0))
				return 0;

			// if there is only one source (=us) then pick the next free chunk
			if (this.getSources().size() == 1) {
				int freeRangeStart = 0;
				for (int i = 0; i < chunkCount
						&& this.getAlreadyDownloadedChunks().get(i); i++) {
					freeRangeStart = i;
				}

				return freeRangeStart;
			}

			// return a random unset chunk
			// do 50 attempts to find a chunk that needs to get loaded and that
			// is currently not in load
			for (int i = 0; i < 50; i++) {
				int chunkNo = BitSetUtils.getRandomUnsetBit(this
						.getAlreadyDownloadedChunks(), chunkCount);
				boolean ok = true;
				for (RunningFileDownload rd : this.getRunningDownloads()) {
					if (rd.getChunkNumber() == chunkNo)
						ok = false;
				}

				if (ok == true) {
					return chunkNo;
				}
			}

			// will happen with very very very small chance
			throw new NoFreeChunkException();

		} finally {
			this.rwlock.readLock().unlock();
		}
	}