public final Socket initConnectToMe(String user, String direction) throws Exception {
		if (!isConnected()) {
			throw new BotException(BotException.NOT_CONNECTED_TO_HUB);
		}
		if (!UserExist(user)) {
			throw new BotException(BotException.USRNAME_NOT_FOUND);
		}

		direction = direction.toLowerCase();
		direction = direction.substring(0, 1).toUpperCase() + direction.substring(1);

		Socket newsocket = null;
		User u = um.getUser(user);

		//connect to client
		String buffer = "$ConnectToMe " + user + " " + _botIP + ":" + _listenPort + "|";
		log.println("From bot: " + buffer);
		SendCommand(buffer);
		try {
			newsocket = socketServer.accept();
		} catch (SocketTimeoutException soce) {
			soce.printStackTrace();
			throw new SocketTimeoutException("Connection to client " + user + " timed out.");
		}

		String remoteClientIP = newsocket.getInetAddress().getHostAddress();
		log.println("00>>Connected to remote Client:: " + remoteClientIP);
		u.setUserIP(remoteClientIP);

		buffer = ReadCommand(newsocket); //Reading $MyNick remote_nick| OR $MaxedOut //remote_user == user
		log.println(buffer);
		if (buffer.equals("$MaxedOut|")) {
			throw new BotException(BotException.NO_FREE_SLOTS);
		}
		String remote_nick = parseRawCmd(buffer)[1];
		if (!remote_nick.equalsIgnoreCase(user)) {
			log.println("Remote client wrong username. Expected: " + user + ", but got: " + remote_nick);
			throw new BotException(BotException.REMOTE_CLIENT_SENT_WRONG_USRNAME);
		}

		buffer = ReadCommand(newsocket); //Reading $Lock EXTENDEDPROTOCOLABCABCABCABCABCABC Pk=DCPLUSPLUS0.698ABCABC|
		log.println(buffer);
		String lock = parseRawCmd(buffer)[1];
		String key = lock2key(lock);

		if (!lock.startsWith("EXTENDEDPROTOCOL")) {
			log.println("Using non-Extended protocol. What kind of old client is this. You can expect errors now.");

			buffer = "$Key " + key + "|";
			log.println("From bot: " + buffer);
			SendCommand(buffer, newsocket);

			// We are now required to send a lock to the remote client. I am
			// simply resending the same lock it returned, back to it.
			buffer = lock;
			log.println("From bot: " + buffer);
			SendCommand(buffer, newsocket);

			buffer = ReadCommand(newsocket); // Read the key sent by the
			// remote client. I am not
			// verifying the key,
			// hence I am now simply moving on to the next step without
			// parsing
			// buffer.
			log.println(buffer);

			buffer = "$MyNick " + _botname + "|";
			log.println("From bot: " + buffer);
			SendCommand(buffer, newsocket);

			buffer = ReadCommand(newsocket); // Reading $Direction.
			log.println(buffer);
			String read_direction = buffer.substring(buffer.indexOf(' ') + 1, buffer.indexOf(' ', buffer.indexOf(' ') + 1));
			if (read_direction.equalsIgnoreCase(direction)) {
				// In this case the remote client to wants to do the same thing as this client, i.e.
				// both wants to download or upload.
				log.println("WARNING! Remote client for " + user + " too wants to " + direction + " from me. This situation is not handled.");
			}
		} else {
			log.println("Using Extended protocol.");

			int N1 = 0x7FFF - 2;
			buffer = "$MyNick " + _botname + "|$Lock EXTENDEDPROTOCOLABCABCABCABCABCABC Pk=DCPLUSPLUS0.698ABCABC|$Supports " + _clientproto_supports
					+ "|$Direction " + direction + " " + N1 + "|$Key " + key + "|";
			log.println("From bot: " + buffer);
			SendCommand(buffer, newsocket);

			buffer = ReadCommand(newsocket);// Reading $Supports S|
			log.println(buffer);
			String remote_supports = parseCmdArgs(buffer);
			u.setSupports(remote_supports);

			buffer = ReadCommand(newsocket);// Reading $Direction Upload N2|
			log.println(buffer);
			String params[] = parseRawCmd(buffer);
			int N2 = Integer.parseInt(params[2]);
			if (params[1].equalsIgnoreCase(direction)) {
				log.println("Huh! Remote client for  " + user + " too wants to " + direction + " from me. This situation is not handled.");
			}

			buffer = ReadCommand(newsocket);// Reading $Key ........A .....0.0. 0. 0. 0. 0. 0.|
			log.println(buffer);

			if (N1 < N2)
				log.println("N1 is < N2 dunno what to do now. Anyway continuing as if it never happened.");
		}

		onConnect2Client();
		return newsocket;
	}