protected synchronized TCPSegment _handleIncomingSegment( TCPSegment s ) throws IOException {
		boolean sendSyn = false;
		
		this.outgoingSocketAddressPair = s.getInverseAddressPair();
		
		if( s.isSyn() && !firstSynReceived ) {
			firstSynReceived = true;
			// syn => we are the server (and need to syn+ack back), syn+ack => we are the client 
			sendSyn = !s.isAck();
			receivedIncomingSequence = s.sequenceNumber;
		}
		
		if( s.ackNumber > acknowledgedOutgoingSequence ) {
			acknowledgedOutgoingSequence = s.ackNumber;
		}
		
		if( s.sequenceNumber != receivedIncomingSequence ) {
			// Then we missed some data and will ignore everything until we get
			// the one we are expecting!
			return null;
		}
		
		if( s.hasData() ) {
			incomingDataSink.write( s.buffer, s.dataOffset, s.dataSize );
		}
		if( s.isFin() ) {
			incomingDataSink.close();
		}
		
		boolean sendAck = (s.getSequenceDelta() != 0);
		receivedIncomingSequence = s.sequenceNumber + s.getSequenceDelta();
		
		notifyAll();
		
		if( sendAck || sendSyn ) {
			int ackFlags = TCPFlags.ACK;
			if( sendSyn ) ackFlags |= TCPFlags.SYN;
			
			TCPSegment res = TCPSegment.create(
				outgoingSocketAddressPair,
				currentOutgoingSequence, receivedIncomingSequence,
				// TODO: What should maxWindowSize be?
				// Can it be different for input/output?
				ackFlags, maxWindowSize,
				ByteUtil.EMPTY_BTYE_ARRAY, 0, 0
			);
			currentOutgoingSequence += res.getSequenceDelta();
			return res;
		} else {
			return null;
		}
	}