std::string DiscoInfoSerializer::serializePayload(boost::shared_ptr<DiscoInfo> discoInfo)  const {
	XMLElement queryElement("query", "http://jabber.org/protocol/disco#info");
	if (!discoInfo->getNode().empty()) {
		queryElement.setAttribute("node", discoInfo->getNode());
	}
	foreach(const DiscoInfo::Identity& identity, discoInfo->getIdentities()) {
		boost::shared_ptr<XMLElement> identityElement(new XMLElement("identity"));
		if (!identity.getLanguage().empty()) {
			identityElement->setAttribute("xml:lang", identity.getLanguage());
		}
		identityElement->setAttribute("category", identity.getCategory());
		identityElement->setAttribute("name", identity.getName());
		identityElement->setAttribute("type", identity.getType());
		queryElement.addNode(identityElement);
	}
	foreach(const std::string& feature, discoInfo->getFeatures()) {
		boost::shared_ptr<XMLElement> featureElement(new XMLElement("feature"));
		featureElement->setAttribute("var", feature);
		queryElement.addNode(featureElement);
	}
	foreach(const Form::ref extension, discoInfo->getExtensions()) {
		queryElement.addNode(boost::make_shared<XMLRawTextNode>(FormSerializer().serialize(extension)));
	}
	return queryElement.serialize();
}
std::string StreamInitiationSerializer::serializePayload(boost::shared_ptr<StreamInitiation> streamInitiation)	const {
	assert(streamInitiation->getIsFileTransfer());

	XMLElement siElement("si", "http://jabber.org/protocol/si");
	if (!streamInitiation->getID().empty()) {
		siElement.setAttribute("id", streamInitiation->getID());
	}
	siElement.setAttribute("profile", FILE_TRANSFER_NS);

	if (streamInitiation->getFileInfo()) {
		StreamInitiationFileInfo file = *streamInitiation->getFileInfo();
		boost::shared_ptr<XMLElement> fileElement(new XMLElement("file", "http://jabber.org/protocol/si/profile/file-transfer"));
		fileElement->setAttribute("name", file.getName());
		if (file.getSize() != 0) {
			fileElement->setAttribute("size", boost::lexical_cast<std::string>(file.getSize()));
		}
		if (!file.getDescription().empty()) {
			boost::shared_ptr<XMLElement> descElement(new XMLElement("desc"));
			descElement->addNode(boost::make_shared<XMLTextNode>(file.getDescription()));
			fileElement->addNode(descElement);
		}
		siElement.addNode(fileElement);
	}

	boost::shared_ptr<XMLElement> featureElement(new XMLElement("feature", FEATURE_NEG_NS));
	if (streamInitiation->getProvidedMethods().size() > 0) {
		Form::ref form(new Form(Form::FormType));
		ListSingleFormField::ref field = ListSingleFormField::create();
		field->setName("stream-method");
		foreach(const std::string& method, streamInitiation->getProvidedMethods()) {
			field->addOption(FormField::Option("", method));
		}
		form->addField(field);
		featureElement->addNode(boost::make_shared<XMLRawTextNode>(FormSerializer().serialize(form)));
	}
std::string SearchPayloadSerializer::serializePayload(boost::shared_ptr<SearchPayload> searchPayload)	const {
    XMLElement searchElement("query", "jabber:iq:search");

    if (searchPayload->getInstructions()) {
        searchElement.addNode(XMLElement::ref(new XMLElement("instructions", "", *searchPayload->getInstructions())));
    }

    if (searchPayload->getNick()) {
        searchElement.addNode(XMLElement::ref(new XMLElement("nick", "", *searchPayload->getNick())));
    }

    if (searchPayload->getFirst()) {
        searchElement.addNode(XMLElement::ref(new XMLElement("first", "", *searchPayload->getFirst())));
    }

    if (searchPayload->getLast()) {
        searchElement.addNode(XMLElement::ref(new XMLElement("last", "", *searchPayload->getLast())));
    }

    if (searchPayload->getEMail()) {
        searchElement.addNode(XMLElement::ref(new XMLElement("email", "", *searchPayload->getEMail())));
    }

    foreach(const SearchPayload::Item& item, searchPayload->getItems()) {
        XMLElement::ref itemElement(new XMLElement("item"));
        itemElement->setAttribute("jid", item.jid);
        itemElement->addNode(XMLElement::ref(new XMLElement("first", "", item.first)));
        itemElement->addNode(XMLElement::ref(new XMLElement("last", "", item.last)));
        itemElement->addNode(XMLElement::ref(new XMLElement("nick", "", item.nick)));
        itemElement->addNode(XMLElement::ref(new XMLElement("email", "", item.email)));

        searchElement.addNode(itemElement);
    }

    if (Form::ref form = searchPayload->getForm()) {
        searchElement.addNode(boost::make_shared<XMLRawTextNode>(FormSerializer().serialize(form)));
    }

    return searchElement.serialize();
}
std::string InBandRegistrationPayloadSerializer::serializePayload(boost::shared_ptr<InBandRegistrationPayload> registration)	const {
	XMLElement registerElement("query", "jabber:iq:register");

	if (registration->isRegistered()) {
		registerElement.addNode(XMLElement::ref(new XMLElement("registered")));
	}

	if (registration->isRemove()) {
		registerElement.addNode(XMLElement::ref(new XMLElement("remove")));
	}

	if (registration->getInstructions()) {
		registerElement.addNode(XMLElement::ref(new XMLElement("instructions", "", *registration->getInstructions())));
	}


	if (registration->getUsername()) {
		registerElement.addNode(XMLElement::ref(new XMLElement("username", "", *registration->getUsername())));
	}

	if (registration->getNick()) {
		registerElement.addNode(XMLElement::ref(new XMLElement("nick", "", *registration->getNick())));
	}

	if (registration->getPassword()) {
		registerElement.addNode(XMLElement::ref(new XMLElement("password", "", *registration->getPassword())));
	}

	if (registration->getName()) {
		registerElement.addNode(XMLElement::ref(new XMLElement("name", "", *registration->getName())));
	}

	if (registration->getFirst()) {
		registerElement.addNode(XMLElement::ref(new XMLElement("first", "", *registration->getFirst())));
	}

	if (registration->getLast()) {
		registerElement.addNode(XMLElement::ref(new XMLElement("last", "", *registration->getLast())));
	}

	if (registration->getEMail()) {
		registerElement.addNode(XMLElement::ref(new XMLElement("email", "", *registration->getEMail())));
	}

	if (registration->getAddress()) {
		registerElement.addNode(XMLElement::ref(new XMLElement("address", "", *registration->getAddress())));
	}

	if (registration->getCity()) {
		registerElement.addNode(XMLElement::ref(new XMLElement("city", "", *registration->getCity())));
	}

	if (registration->getState()) {
		registerElement.addNode(XMLElement::ref(new XMLElement("state", "", *registration->getState())));
	}

	if (registration->getZip()) {
		registerElement.addNode(XMLElement::ref(new XMLElement("zip", "", *registration->getZip())));
	}

	if (registration->getPhone()) {
		registerElement.addNode(XMLElement::ref(new XMLElement("phone", "", *registration->getPhone())));
	}

	if (registration->getURL()) {
		registerElement.addNode(XMLElement::ref(new XMLElement("url", "", *registration->getURL())));
	}

	if (registration->getDate()) {
		registerElement.addNode(XMLElement::ref(new XMLElement("date", "", *registration->getDate())));
	}

	if (registration->getMisc()) {
		registerElement.addNode(XMLElement::ref(new XMLElement("misc", "", *registration->getMisc())));
	}

	if (registration->getText()) {
		registerElement.addNode(XMLElement::ref(new XMLElement("text", "", *registration->getText())));
	}

	if (registration->getKey()) {
		registerElement.addNode(XMLElement::ref(new XMLElement("key", "", *registration->getKey())));
	}

	if (Form::ref form = registration->getForm()) {
		registerElement.addNode(boost::make_shared<XMLRawTextNode>(FormSerializer().serialize(form)));
	}

	return registerElement.serialize();
}