public final void connect(String hostname, int port) throws Exception {

		String buffer;

		_port = port;

		if (this.isConnected()) {
			throw new IOException("Already connected");
		}
		// connect to server
		socket = new Socket(hostname, port);
		input = socket.getInputStream();
		output = socket.getOutputStream();
		//breader = new BufferedReader(new InputStreamReader(socket.getInputStream()));

		_ip = socket.getInetAddress();

		buffer = ReadCommand();
		log.println(buffer);
		String lock = parseRawCmd(buffer)[1];

		if (lock.startsWith("EXTENDEDPROTOCOL")) {
			buffer = "$Supports " + _hubproto_supports + "|";
			log.println("From bot: " + buffer);
			SendCommand(buffer);
		}

		String key = lock2key(lock);
		buffer = "$Key " + key + "|";
		log.println("From bot: " + buffer);
		SendCommand(buffer);

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

		buffer = ReadCommand();
		log.println(buffer);

		while (buffer.startsWith("$Hello") != true) {
			if (buffer.startsWith("$ValidateDenide"))
				throw new BotException(BotException.VALIDATE_DENIED);
			if (buffer.startsWith("$BadPass"))
				throw new BotException(BotException.BAD_PASSWORD);

			if (buffer.startsWith("$GetPass")) {
				buffer = "$MyPass " + _password + "|";
				log.println("From bot: $MyPass xxxx|");
				SendCommand(buffer);
			}
			if (buffer.startsWith("$HubName ")) {
				_hubname = buffer.substring(9, buffer.length() - 1);
			}
			if (buffer.startsWith("$Supports ")) {
				_hubSupports = parseCmdArgs(buffer);
			}

			buffer = ReadCommand();
			log.println(buffer);
		}

		buffer = "$Version " + _protoVersion + "|";
		log.println("From bot: " + buffer);
		SendCommand(buffer);

		buffer = "$GetNickList|";
		log.println("From bot: " + buffer);
		SendCommand(buffer);

		buffer = "$MyINFO $ALL " + _botname + " " + _description + "$ $" + _conn_type + "$" + _email + "$" + _sharesize + "$|";
		log.println("From bot: " + buffer);
		SendCommand(buffer);

		um = new UserManager(this);
		/*
		while (!(buffer = ReadCommand()).startsWith("$NickList ")) {
			log.println(buffer);
			if (!buffer.startsWith("$NickList ")) {
				log.println("Expected $NickList but got something else. Reading on...");
			}
		}
		log.println(buffer);
		um.addUsers(buffer.substring(10, buffer.length() - 1));
		*/
		
		ThreadRechercheUser tru = new ThreadRechercheUser(this, log);
		tru.start();
		
		log.println("Recherche des utilisateur ...");
		Thread.sleep(_userSearchDuration * 1000);
		
		tru.stop();
		um.initUsers(tru.getDescriptionsList());
		/*
		 * do { buffer = ReadCommand(); log.println(buffer); } while (buffer.startsWith("$NickList ") == false); buffer = ReadCommand();
		 */

		// Creating Listen port for clients to contact this.
		socketServer = new ServerSocket(_listenPort);
		socketServer.setSoTimeout(60000); // Wait for 60s before timing out.

		_inputThread = new InputThread(this, input);
		_inputThread.start();
		onConnect();
	}