public synchronized void init() throws InterruptedException, IOException {
		if (this.isInitialized()) {
			throw new IllegalStateException("Torrent was already initialized!");
		}

		int nPieces = (int) (Math.ceil(
				(double)this.getSize() / this.pieceLength));
		this.pieces = new Piece[nPieces];
		this.completedPieces = new BitSet(nPieces);
		// *** ADDED BY CHIKO
		this.fakeCompletedPieces = new BitSet(nPieces);
		// *** ADDED BY CHIKO

		this.piecesHashes.clear();

		ExecutorService executor = Executors.newFixedThreadPool(
			getHashingThreadsCount());
		List<Future<Piece>> results = new LinkedList<Future<Piece>>();

		logger.debug("Analyzing local data for {} with {} threads...",
			this.getName(), getHashingThreadsCount());
		for (int idx=0; idx<this.pieces.length; idx++) {
			byte[] hash = new byte[Torrent.PIECE_HASH_SIZE];
			this.piecesHashes.get(hash);

			// The last piece may be shorter than the torrent's global piece
			// length. Let's make sure we get the right piece length in any
			// situation.
			long off = ((long)idx) * this.pieceLength;
			long len = Math.min(
				(long)(this.bucket.size() - off),
				this.pieceLength);

			this.pieces[idx] = new Piece(this.bucket, idx, off, (int)len, hash,
				this.isSeeder());

			Callable<Piece> hasher = new Piece.CallableHasher(this.pieces[idx]);
			results.add(executor.submit(hasher));
		}

		// Request orderly executor shutdown and wait for hashing tasks to
		// complete.
		executor.shutdown();
		while (!executor.isTerminated()) {
			if (this.stop) {
				throw new InterruptedException("Torrent data analysis " +
					"interrupted.");
			}

			Thread.sleep(10);
		}

		try {
			for (Future<Piece> task : results) {
				Piece piece = task.get();
				if (this.pieces[piece.getIndex()].isValid()) {
					this.completedPieces.set(piece.getIndex());
					// *** ADDED BY CHIKO
					this.fakeCompletedPieces.set(piece.getIndex());
					// *** ADDED BY CHIKO
					this.left -= piece.size();
				}
			}
		} catch (ExecutionException e) {
			throw new IOException("Error while hashing a torrent piece!", e);
		}

		logger.debug("{}: {}/{} bytes [{}/{}].",
			new Object[] {
				this.getName(),
				(this.getSize() - this.left),
				this.getSize(),
				this.completedPieces.cardinality(),
				this.pieces.length
			});
		this.initialized = true;
	}