private SharingPeer getOrCreatePeer(byte[] peerId, String ip, int port) {
		Peer search = new Peer(ip, port,
				(peerId != null ? ByteBuffer.wrap(peerId) : (ByteBuffer)null));
		SharingPeer peer = null;

		synchronized (this.peers) {
			peer = this.peers.get(search.hasPeerId()
						? search.getHexPeerId()
						: search.getHostIdentifier());

			if (peer != null) {
				return peer;
			}

			if (search.hasPeerId()) {
				peer = this.peers.get(search.getHostIdentifier());
				if (peer != null) {
					// Set peer ID for previously known peer.
					peer.setPeerId(search.getPeerId());

					this.peers.remove(peer.getHostIdentifier());
					this.peers.putIfAbsent(peer.getHexPeerId(), peer);
					return peer;
				}
			}

			peer = new SharingPeer(ip, port, search.getPeerId(), this.torrent);
			
			this.peers.putIfAbsent(peer.hasPeerId()
					? peer.getHexPeerId()
					: peer.getHostIdentifier(),
				peer);
			logger.trace("Created new peer " + peer + ".");
		}

		return peer;
	}