public void ackRecieved(UtpTimestampedPacketDTO pair) {
		int seqNrToAck = pair.utpPacket().getAckNumber() & 0xFFFF;
//		log.debug("Recieved ACK " + pair.utpPacket().toString());
		timeStampNow = timeStamper.timeStamp();
		lastAckRecieved = timeStampNow;
		int advertisedWindo = pair.utpPacket().getWindowSize() & 0xFFFFFFFF;
		updateAdvertisedWindowSize(advertisedWindo);
		statisticLogger.ackRecieved(seqNrToAck);
		int packetSizeJustAcked = buffer.markPacketAcked(seqNrToAck, timeStampNow, 
				UtpAlgConfiguration.AUTO_ACK_SMALLER_THAN_ACK_NUMBER);
		if (packetSizeJustAcked > 0) {
			updateRtt(timeStampNow, seqNrToAck);
			updateWindow(pair.utpPacket(), timeStampNow, packetSizeJustAcked, pair.utpTimeStamp());
		} 
		// TODO: With libutp, sometimes null pointer exception -> investigate. 
//			log.debug("utpPacket With Ext: " + pair.utpPacket().toString());
		SelectiveAckHeaderExtension selectiveAckExtension = findSelectiveAckExtension(pair.utpPacket());
		if (selectiveAckExtension != null) {
			
			// if a new packed is acked by selectiveAck, we will 
			// only update this one. if more than one is acked newly,
			// ignore it, because it will corrupt our measurements
			boolean windowAlreadyUpdated = false;
			
			// For each byte in the selective Ack header extension
			byte[] bitMask = selectiveAckExtension.getBitMask();
			for (int i = 0; i < bitMask.length; i++) {
				// each bit in the extension, from 2 to 9, because least significant
				// bit is ACK+2, most significant bit is ack+9 -> loop [2,9]
				for (int j = 2; j < 10; j++) {
					if (SelectiveAckHeaderExtension.isBitMarked(bitMask[i], j)) {
						// j-th bit of i-th byte + seqNrToAck equals our selective-Ack-number.
						// example: 
						// ack:5, sack: 8 -> i = 0, j =3 -> 0*8+3+5 = 8. 
						// bitpattern in this case would be 00000010, bit_index 1 from right side, added 2 to it equals 3
						// thats why we start with j=2. most significant bit is index 7, j would be 9 then. 
						int sackSeqNr = i*8 + j + seqNrToAck;
						// sackSeqNr can overflow too !!
						if (sackSeqNr > UnsignedTypesUtil.MAX_USHORT) {
							sackSeqNr -= UnsignedTypesUtil.MAX_USHORT;
						}
						statisticLogger.sAck(sackSeqNr);
						// dont ack smaller seq numbers in case of Selective ack !!!!!
						packetSizeJustAcked = buffer.markPacketAcked(sackSeqNr, timeStampNow, false);
						if (packetSizeJustAcked > 0 && !windowAlreadyUpdated) {
							windowAlreadyUpdated = true;
							updateRtt(timeStampNow, sackSeqNr);
							updateWindow(pair.utpPacket(), timeStampNow, packetSizeJustAcked, pair.utpTimeStamp());
						} 
					}
				}
			}
		}
		statisticLogger.next();
		
	}