private Object waitForResponse (byte responseID) {
			if (connection.getEndPoint().getUpdateThread() == Thread.currentThread())
				throw new IllegalStateException("Cannot wait for an RMI response on the connection's update thread.");

			long endTime = System.currentTimeMillis() + timeoutMillis;

			while (true) {
				long remaining = endTime - System.currentTimeMillis();
				InvokeMethodResult invokeMethodResult;
				synchronized (this) {
					invokeMethodResult = responseTable[responseID];
				}
				if (invokeMethodResult != null) {
					lastResponseID = null;
					return invokeMethodResult.result;
				} else {
					if (remaining <= 0) throw new TimeoutException("Response timed out.");

					lock.lock();
					try {
						responseCondition.await(remaining, TimeUnit.MILLISECONDS);
					} catch (InterruptedException e) {
						Thread.currentThread().interrupt();
						throw new KryoNetException(e);
					} finally {
						lock.unlock();
					}
				}
			}
		}