protected int request(IRequest request) throws NotInRoomException
	{
		// Check that it's not already completed
		if(request.isCompleted())
		{
			// Warn and return
			if(JeTT.isDebugging())
				System.err.format("Ignoring completed request (%s)\n", request.toString());
			return -1;
		}
		
		// Are we in a room?
		if(request.requiresRoom() && this.getSession().getRoomHash() == null)
			throw new NotInRoomException();
		
		// Apply session data
		request.applySession(this.getSession());
		
		// Add request
		int msgid = this.requestTracker.addPendingRequest(request);
		
		// Generate message
		String message = request.getMessage();
		
		// Append prefix
		message = String.format("~m~%d~m~%s", message.length(), message);
		
		// Send
		if(!this.send(message))
		{
			// Warn, 'complete', return
			if(JeTT.isDebugging())
				System.err.format("Request failed; IO error (%s)\n", message);
			this.requestTracker.completeRequest(msgid);
			return -1;
		}
		
		// Debug
		if(JeTT.isDebugging())
			System.out.println("< " + message);
		
		// Return
		return msgid;
	}