public static ReceivablePacket unserialize(ByteBuffer byteBuffer) {
		int position = byteBuffer.position();
		
		if(byteBuffer.remaining() > AbstractPacket.PACKET_LENGTH_SIZE) {
			int length = byteBuffer.getShort() - AbstractPacket.PACKET_LENGTH_SIZE;
			
			if(length <= 0) return null;
								
			if(byteBuffer.remaining() >= length) {
				ReceivablePacket packet = null;
				
				int packetID = byteBuffer.get() & 0xFF;
				
				switch(packetID) {
					case 0x01: { packet = new FindEnemyPacket(); break; }
					case 0x02: { packet = new ShipsPacket(); break; }
					case 0x03: { packet = new ShotRequestPacket(); break; }
					default: {						
						byteBuffer.position(byteBuffer.position() + length - AbstractPacket.PACKET_ID_SIZE);												
						logger.warn("Unknown packet ID: " + packetID);
					}
				}
				
				if(packet != null) {
					packet.setData(byteBuffer);
					
					if(!packet.read()) {
						byteBuffer.position(byteBuffer.position() + length - AbstractPacket.PACKET_ID_SIZE);
						logger.warn("Cannot read packet ID: " + packet.getPacketID());
					}				
				}
								
				return packet;
			}
			
			byteBuffer.position(position);
		}
		
		return null;
	}