bool UserRegistration::handleSetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::InBandRegistrationPayload> payload) {
	if (CONFIG_STRING(m_config, "service.protocol") == "irc") {
		Swift::GetResponder<Swift::InBandRegistrationPayload>::sendError(from, id, ErrorPayload::BadRequest, ErrorPayload::Modify);
		return true;
	}

	std::string barejid = from.toBare().toString();

// 	AbstractUser *user = m_component->userManager()->getUserByJID(barejid);
	if (!CONFIG_BOOL(m_config,"registration.enable_public_registration")) {
		std::list<std::string> const &x = CONFIG_LIST(m_config,"service.allowed_servers");
		if (std::find(x.begin(), x.end(), from.getDomain()) == x.end()) {
// 			Log("UserRegistration", "This user has no permissions to register an account");
			Swift::SetResponder<Swift::InBandRegistrationPayload>::sendError(from, id, ErrorPayload::BadRequest, ErrorPayload::Modify);
			return true;
		}
	}

	UserInfo res;
	bool registered = m_storageBackend->getUser(barejid, res);

	std::string encoding;
	std::string language;

	Form::ref form = payload->getForm();
	if (form) {
		const std::vector<FormField::ref> fields = form->getFields();
		for (std::vector<FormField::ref>::const_iterator it = fields.begin(); it != fields.end(); it++) {
			TextSingleFormField::ref textSingle = boost::dynamic_pointer_cast<TextSingleFormField>(*it);
			if (textSingle) {
				if (textSingle->getName() == "username") {
					payload->setUsername(textSingle->getValue());
				}
				else if (textSingle->getName() == "encoding") {
					encoding = textSingle->getValue();
				}
				continue;
			}

			TextPrivateFormField::ref textPrivate = boost::dynamic_pointer_cast<TextPrivateFormField>(*it);
			if (textPrivate) {
				if (textPrivate->getName() == "password") {
					payload->setPassword(textPrivate->getValue());
				}
				continue;
			}

			ListSingleFormField::ref listSingle = boost::dynamic_pointer_cast<ListSingleFormField>(*it);
			if (listSingle) {
				if (listSingle->getName() == "language") {
					language = listSingle->getValue();
				}
				continue;
			}

			BooleanFormField::ref boolean = boost::dynamic_pointer_cast<BooleanFormField>(*it);
			if (boolean) {
				if (boolean->getName() == "unregister") {
					if (boolean->getValue()) {
						payload->setRemove(true);
					}
				}
				continue;
			}
		}
	}

	if (payload->isRemove()) {
		unregisterUser(barejid);
		Swift::SetResponder<Swift::InBandRegistrationPayload>::sendResponse(from, id, InBandRegistrationPayload::ref());
		return true;
	}

	if (!payload->getUsername() || !payload->getPassword()) {
		Swift::SetResponder<Swift::InBandRegistrationPayload>::sendError(from, id, ErrorPayload::NotAcceptable, ErrorPayload::Modify);
		return true;
	}

	// Register or change password
	if (payload->getUsername()->empty() ||
		(payload->getPassword()->empty() && CONFIG_STRING(m_config, "service.protocol") != "twitter" && CONFIG_STRING(m_config, "service.protocol") != "bonjour")
// 		|| localization.getLanguages().find(language) == localization.getLanguages().end()
	)
	{
		Swift::SetResponder<Swift::InBandRegistrationPayload>::sendError(from, id, ErrorPayload::NotAcceptable, ErrorPayload::Modify);
		return true;
	}

	if (CONFIG_STRING(m_config, "service.protocol") == "xmpp") {
		// User tries to register himself.
		if ((Swift::JID(*payload->getUsername()).toBare() == from.toBare())) {
			Swift::SetResponder<Swift::InBandRegistrationPayload>::sendError(from, id, ErrorPayload::NotAcceptable, ErrorPayload::Modify);
			return true;
		}

		// User tries to register someone who's already registered.
		UserInfo user_row;
		bool registered = m_storageBackend->getUser(Swift::JID(*payload->getUsername()).toBare().toString(), user_row);
		if (registered) {
			Swift::SetResponder<Swift::InBandRegistrationPayload>::sendError(from, id, ErrorPayload::NotAcceptable, ErrorPayload::Modify);
			return true;
		}
	}

	std::string username = *payload->getUsername();
// 	m_component->protocol()->prepareUsername(username);

	std::string newUsername(username);
	if (!CONFIG_STRING(m_config, "registration.username_mask").empty()) {
		newUsername = CONFIG_STRING(m_config, "registration.username_mask");
// 		replace(newUsername, "$username", username.c_str());
	}

// 	if (!m_component->protocol()->isValidUsername(newUsername)) {
// 		Log("UserRegistration", "This is not valid username: "******"registration.reg_allowed_usernames").empty() &&
// 		!g_regex_match_simple(CONFIG_STRING(m_config, "registration.reg_allowed_usernames"), newUsername.c_str(),(GRegexCompileFlags) (G_REGEX_CASELESS | G_REGEX_EXTENDED), (GRegexMatchFlags) 0)) {
// 		Log("UserRegistration", "This is not valid username: "******"UserRegistration", "changing user password: "******", " << username);
		res.jid = barejid;
		res.password = *payload->getPassword();
		res.language = language;
		res.encoding = encoding;
		m_storageBackend->setUser(res);
		onUserUpdated(res);
	}

	Swift::SetResponder<Swift::InBandRegistrationPayload>::sendResponse(from, id, InBandRegistrationPayload::ref());
	return true;
}
bool GlooxRegisterHandler::handleIq(const Tag *iqTag) {
	Log("GlooxRegisterHandler", iqTag->findAttribute("from") << ": iq:register received (" << iqTag->findAttribute("type") << ")");

	JID from(iqTag->findAttribute("from"));

	if (CONFIG().protocol == "irc") {
		sendError(400, "bad-request", iqTag);
		return false;
	}
	
	AbstractUser *user = Transport::instance()->userManager()->getUserByJID(from.bare());
	if (!Transport::instance()->getConfiguration().enable_public_registration) {
		std::list<std::string> const &x = Transport::instance()->getConfiguration().allowedServers;
		if (std::find(x.begin(), x.end(), from.server()) == x.end()) {
			Log("GlooxRegisterHandler", "This user has no permissions to register an account");
			sendError(400, "bad-request", iqTag);
			return false;
		}
	}

	const char *_language = user ? user->getLang() : Transport::instance()->getConfiguration().language.c_str();

	// send registration form
	if (iqTag->findAttribute("type") == "get") {
		Tag *reply = new Tag( "iq" );
		reply->addAttribute( "id", iqTag->findAttribute("id") );
		reply->addAttribute( "type", "result" );
		reply->addAttribute( "to", iqTag->findAttribute("from") );
		reply->addAttribute( "from", Transport::instance()->jid() );
		Tag *query = new Tag( "query" );
		query->addAttribute( "xmlns", "jabber:iq:register" );
		UserRow res = Transport::instance()->sql()->getUserByJid(from.bare());

		std::string instructions = CONFIG().reg_instructions.empty() ? PROTOCOL()->text("instructions") : CONFIG().reg_instructions;
		std::string usernameField = CONFIG().reg_username_field.empty() ? PROTOCOL()->text("username") : CONFIG().reg_username_field;

		if (res.id == -1) {
			Log("GlooxRegisterHandler", "* sending registration form; user is not registered");
			query->addChild( new Tag("instructions", tr(_language, instructions)) );
			query->addChild( new Tag("username") );
			if (CONFIG().protocol != "twitter" && CONFIG().protocol != "bonjour")
				query->addChild( new Tag("password") );
		}
		else {
			Log("GlooxRegisterHandler", "* sending registration form; user is registered");
			query->addChild( new Tag("instructions", tr(_language, instructions)) );
			query->addChild( new Tag("registered") );
			query->addChild( new Tag("username", res.uin));
			if (CONFIG().protocol != "twitter" && CONFIG().protocol != "bonjour")
				query->addChild( new Tag("password"));
		}

		Tag *x = new Tag("x");
		x->addAttribute("xmlns", "jabber:x:data");
		x->addAttribute("type", "form");
		x->addChild( new Tag("title", tr(_language, _("Registration"))));
		x->addChild( new Tag("instructions", tr(_language, instructions)) );

		Tag *field = new Tag("field");
		field->addAttribute("type", "hidden");
		field->addAttribute("var", "FORM_TYPE");
		field->addChild( new Tag("value", "jabber:iq:register") );
		x->addChild(field);

		field = new Tag("field");
		field->addAttribute("type", "text-single");
		field->addAttribute("var", "username");
		field->addAttribute("label", tr(_language, usernameField));
		field->addChild( new Tag("required") );
		if (res.id!=-1)
			field->addChild( new Tag("value", res.uin) );
		x->addChild(field);

		if (CONFIG().protocol != "twitter" && CONFIG().protocol != "bonjour") {
			field = new Tag("field");
			field->addAttribute("type", "text-private");
			field->addAttribute("var", "password");
			field->addAttribute("label", tr(_language, _("Password")));
			x->addChild(field);
		}

		field = new Tag("field");
		field->addAttribute("type", "list-single");
		field->addAttribute("var", "language");
		field->addAttribute("label", tr(_language, _("Language")));
		if (res.id!=-1)
			field->addChild( new Tag("value", res.language) );
		else
			field->addChild( new Tag("value", Transport::instance()->getConfiguration().language) );
		x->addChild(field);

		std::map <std::string, std::string> languages = localization.getLanguages();
		for (std::map <std::string, std::string>::iterator it = languages.begin(); it != languages.end(); it++) {
			Tag *option = new Tag("option");
			option->addAttribute("label", (*it).second);
			option->addChild( new Tag("value", (*it).first) );
			field->addChild(option);
		}

		field = new Tag("field");
		field->addAttribute("type", "text-single");
		field->addAttribute("var", "encoding");
		field->addAttribute("label", tr(_language, _("Encoding")));
		if (res.id!=-1)
			field->addChild( new Tag("value", res.encoding) );
		else
			field->addChild( new Tag("value", Transport::instance()->getConfiguration().encoding) );
		x->addChild(field);

		if (res.id != -1) {
			field = new Tag("field");
			field->addAttribute("type", "boolean");
			field->addAttribute("var", "unregister");
			field->addAttribute("label", tr(_language, _("Remove your registration")));
			field->addChild( new Tag("value", "0") );
			x->addChild(field);
		}

		query->addChild(x);
		reply->addChild(query);
		Transport::instance()->send( reply );
		return true;
	}
	else if (iqTag->findAttribute("type") == "set") {
		bool remove = false;
		Tag *query;
		Tag *usernametag;
		Tag *passwordtag;
		Tag *languagetag;
		Tag *encodingtag;
		std::string username("");
		std::string password("");
		std::string language("");
		std::string encoding("");

		UserRow res = Transport::instance()->sql()->getUserByJid(from.bare());
		
		query = iqTag->findChild( "query" );
		if (!query) return true;

		Tag *xdata = query->findChild("x", "xmlns", "jabber:x:data");
		if (xdata) {
			if (query->hasChild( "remove" ))
				remove = true;
			for (std::list<Tag*>::const_iterator it = xdata->children().begin(); it != xdata->children().end(); ++it) {
				std::string key = (*it)->findAttribute("var");
				if (key.empty()) continue;

				Tag *v = (*it)->findChild("value");
				if (!v) continue;

				if (key == "username")
					username = v->cdata();
				else if (key == "password")
					password = v->cdata();
				else if (key == "language")
					language = v->cdata();
				else if (key == "encoding")
					encoding = v->cdata();
				else if (key == "unregister")
					remove = atoi(v->cdata().c_str());
			}
		}
		else {
			if (query->hasChild( "remove" ))
				remove = true;
			else {
				usernametag = query->findChild("username");
				passwordtag = query->findChild("password");
				languagetag = query->findChild("language");
				encodingtag = query->findChild("encoding");

				if (languagetag)
					language = languagetag->cdata();
				else
					language = Transport::instance()->getConfiguration().language;

				if (encodingtag)
					encoding = encodingtag->cdata();
				else
					encoding = Transport::instance()->getConfiguration().encoding;

				if (usernametag==NULL || (passwordtag==NULL && CONFIG().protocol != "twitter" && CONFIG().protocol != "bonjour")) {
					sendError(406, "not-acceptable", iqTag);
					return false;
				}
				else {
					username = usernametag->cdata();
					if (passwordtag)
						password = passwordtag->cdata();
					if (username.empty() || (password.empty() && CONFIG().protocol != "twitter" && CONFIG().protocol != "bonjour")) {
						sendError(406, "not-acceptable", iqTag);
						return false;
					}
				}
			}
		}

		if (Transport::instance()->getConfiguration().protocol == "xmpp") {
			// User tries to register himself.
			if ((JID(username).bare() == from.bare())) {
				sendError(406, "not-acceptable", iqTag);
				return false;
			}

			// User tries to register someone who's already registered.
			UserRow user_row = Transport::instance()->sql()->getUserByJid(JID(username).bare());
			if (user_row.id != -1) {
				sendError(406, "not-acceptable", iqTag);
				return false;
			}
		}

		if (remove) {
			unregisterUser(from.bare());

			Tag *reply = new Tag("iq");
			reply->addAttribute( "type", "result" );
			reply->addAttribute( "from", Transport::instance()->jid() );
			reply->addAttribute( "to", iqTag->findAttribute("from") );
			reply->addAttribute( "id", iqTag->findAttribute("id") );
			Transport::instance()->send( reply );

			return true;
		}

		// Register or change password

		std::string jid = from.bare();

		if (username.empty() || (password.empty() && CONFIG().protocol != "twitter" && CONFIG().protocol != "bonjour") || localization.getLanguages().find(language) == localization.getLanguages().end()) {
			sendError(406, "not-acceptable", iqTag);
			return false;
		}

		Transport::instance()->protocol()->prepareUsername(username);

		std::string newUsername(username);
		if (!CONFIG().username_mask.empty()) {
			newUsername = CONFIG().username_mask;
			replace(newUsername, "$username", username.c_str());
		}

		if (!Transport::instance()->protocol()->isValidUsername(newUsername)) {
			Log("GlooxRegisterHandler", "This is not valid username: "******"bad-request", iqTag);
			return false;
		}

#if GLIB_CHECK_VERSION(2,14,0)
		if (!CONFIG().reg_allowed_usernames.empty() &&
			!g_regex_match_simple(CONFIG().reg_allowed_usernames.c_str(), newUsername.c_str(),(GRegexCompileFlags) (G_REGEX_CASELESS | G_REGEX_EXTENDED), (GRegexMatchFlags) 0)) {
			Log("GlooxRegisterHandler", "This is not valid username: "******"bad-request", iqTag);
			return false;
		}
#endif
		if (res.id == -1) {
			res.jid = from.bare();
			res.uin = username;
			res.password = password;
			res.language = language;
			res.encoding = encoding;
			res.vip = 0;

			registerUser(res);
		}
		else {
			// change passwordhttp://soumar.jabbim.cz/phpmyadmin/index.php
			Log("GlooxRegisterHandler", "changing user password: "******", " << username);
			res.jid = from.bare();
			res.password = password;
			res.language = language;
			res.encoding = encoding;
			Transport::instance()->sql()->updateUser(res);
		}

		Tag *reply = new Tag( "iq" );
		reply->addAttribute( "id", iqTag->findAttribute("id") );
		reply->addAttribute( "type", "result" );
		reply->addAttribute( "to", iqTag->findAttribute("from") );
		reply->addAttribute( "from", Transport::instance()->jid() );
		Transport::instance()->send( reply );

		return true;
	}
	return false;
}