public final void handleIncomingData() {
		try {
			// Read the incoming data.
			if (getSocketChannel().read(inData) == -1) {
				disconnect();
				return;
			}

			// Handle the received data.
			inData.flip();
			while (inData.hasRemaining()) {

				// Handle login if we need to.
				if (getStage() != Stage.LOGGED_IN) {
					handleLogin();
					break;
				}

				// Decode the packet opcode.
				if (packetOpcode == -1) {
					packetOpcode = inData.get() & 0xff;
					packetOpcode = packetOpcode - getDecryptor().getNextValue() & 0xff;
				}

				// Decode the packet length.
				if (packetLength == -1) {
					packetLength = Misc.packetLengths[packetOpcode];
					if (packetLength == -1) {
						if (!inData.hasRemaining()) {
							inData.flip();
							inData.compact();
							break;
						}
						packetLength = inData.get() & 0xff;
					}
				}

				// Decode the packet payload.
				if (inData.remaining() >= packetLength) {
					handlePacket();

					// Reset for the next packet.
					packetOpcode = -1;
					packetLength = -1;
				} else {
					inData.flip();
					inData.compact();
					break;
				}
			}

			// Clear everything for the next read.
			inData.clear();
		} catch (Exception ex) {
			ex.printStackTrace();
			disconnect();
		}
	}