From bbf8a5fcb47d649bdcee1b2122eaa76f2c914ef7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be>
Date: Sat, 4 Dec 2010 13:43:57 +0100
Subject: Added EchoPayload parserialement.


diff --git a/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/.gitignore b/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/.gitignore
index 81f2be3..91c939b 100644
--- a/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/.gitignore
+++ b/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/.gitignore
@@ -1,3 +1,4 @@
 EchoBot?
 *.cpp.xml
+*.h.xml
 EchoComponent
diff --git a/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/EchoBot1.cpp b/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/EchoBot1.cpp
index e545801..f5268ef 100644
--- a/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/EchoBot1.cpp
+++ b/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/EchoBot1.cpp
@@ -4,7 +4,7 @@
  * See Documentation/Licenses/GPLv3.txt for more information.
  */
 
-#include "Swiften/Swiften.h"
+#include <Swiften/Swiften.h>
 
 using namespace Swift;
 
diff --git a/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/EchoBot2.cpp b/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/EchoBot2.cpp
index 810307c..99efdf9 100644
--- a/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/EchoBot2.cpp
+++ b/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/EchoBot2.cpp
@@ -7,7 +7,7 @@
 #include <iostream>
 #include <boost/bind.hpp>
 
-#include "Swiften/Swiften.h"
+#include <Swiften/Swiften.h>
 
 using namespace Swift;
 using namespace boost;
diff --git a/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/EchoBot3.cpp b/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/EchoBot3.cpp
index bca00af..3404c2a 100644
--- a/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/EchoBot3.cpp
+++ b/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/EchoBot3.cpp
@@ -7,7 +7,7 @@
 #include <iostream>
 #include <boost/bind.hpp>
 
-#include "Swiften/Swiften.h"
+#include <Swiften/Swiften.h>
 
 using namespace Swift;
 using namespace boost;
diff --git a/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/EchoBot4.cpp b/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/EchoBot4.cpp
index 9b2277b..0309768 100644
--- a/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/EchoBot4.cpp
+++ b/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/EchoBot4.cpp
@@ -8,7 +8,7 @@
 #include <iostream>
 #include <boost/bind.hpp>
 
-#include "Swiften/Swiften.h"
+#include <Swiften/Swiften.h>
 
 using namespace Swift;
 using namespace boost;
diff --git a/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/EchoBot5.cpp b/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/EchoBot5.cpp
index 47cbe1f..4c09e1b 100644
--- a/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/EchoBot5.cpp
+++ b/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/EchoBot5.cpp
@@ -8,7 +8,7 @@
 #include <iostream>
 #include <boost/bind.hpp>
 
-#include "Swiften/Swiften.h"
+#include <Swiften/Swiften.h>
 
 using namespace Swift;
 using namespace boost;
diff --git a/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/EchoBot6.cpp b/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/EchoBot6.cpp
new file mode 100644
index 0000000..4c96f6b
--- /dev/null
+++ b/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/EchoBot6.cpp
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+//...
+#include <iostream>
+#include <boost/bind.hpp>
+
+#include <Swiften/Swiften.h>
+
+using namespace Swift;
+using namespace boost;
+//...
+#include "EchoPayload.h"
+#include "EchoPayloadParserFactory.h"
+#include "EchoPayloadSerializer.h"
+
+class EchoBot {
+	public:
+		EchoBot(EventLoop* eventLoop, NetworkFactories* networkFactories) {
+			//...
+			client = new Client(eventLoop, networkFactories, JID("echobot@wonderland.lit"), "mypass");
+			client->onConnected.connect(bind(&EchoBot::handleConnected, this));
+			client->onMessageReceived.connect(
+					bind(&EchoBot::handleMessageReceived, this, _1));
+			client->onPresenceReceived.connect(
+					bind(&EchoBot::handlePresenceReceived, this, _1));
+			tracer = new ClientXMLTracer(client);
+
+			softwareVersionResponder = new SoftwareVersionResponder(client->getIQRouter());
+			softwareVersionResponder->setVersion("EchoBot", "1.0");
+			softwareVersionResponder->start();
+			//...
+			client->addPayloadParserFactory(&echoPayloadParserFactory);
+			client->addPayloadSerializer(&echoPayloadSerializer);
+			//...
+			client->connect();
+			//...
+		}
+
+		~EchoBot() {
+			client->removePayloadSerializer(&echoPayloadSerializer);
+			client->removePayloadParserFactory(&echoPayloadParserFactory);
+			//...
+			softwareVersionResponder->stop();
+			delete softwareVersionResponder;
+			delete tracer;
+			delete client;
+			//...
+		}
+		//...
+	
+	private:
+		void handlePresenceReceived(Presence::ref presence) {
+			// Automatically approve subscription requests
+			if (presence->getType() == Presence::Subscribe) {
+				Presence::ref response = Presence::create();
+				response->setTo(presence->getFrom());
+				response->setType(Presence::Subscribed);
+				client->sendPresence(response);
+			}
+		}
+
+		void handleConnected() {
+			// Request the roster
+			GetRosterRequest::ref rosterRequest = 
+					GetRosterRequest::create(client->getIQRouter());
+			rosterRequest->onResponse.connect(
+					bind(&EchoBot::handleRosterReceived, this, _2));
+			rosterRequest->send();
+		}
+
+		void handleRosterReceived(ErrorPayload::ref error) {
+			if (error) {
+				std::cerr << "Error receiving roster. Continuing anyway.";
+			}
+			// Send initial available presence
+			client->sendPresence(Presence::create("Send me a message"));
+		}
+
+		//...
+		void handleMessageReceived(Message::ref message) {
+			//...
+			// Echo back the incoming message
+			message->setTo(message->getFrom());
+			message->setFrom(JID());
+			//...
+			if (!message->getPayload<EchoPayload>()) {
+				boost::shared_ptr<EchoPayload> echoPayload(new EchoPayload());
+				echoPayload->setMessage("This is an echoed message");
+				message->addPayload(echoPayload);
+				client->sendMessage(message);
+			}
+		}
+		//...
+
+		//...
+	private:
+		//...
+		Client* client;
+		ClientXMLTracer* tracer;
+		SoftwareVersionResponder* softwareVersionResponder;
+		//...
+		EchoPayloadParserFactory echoPayloadParserFactory;
+		EchoPayloadSerializer echoPayloadSerializer;
+};
+//...
+
+int main(int, char**) {
+	SimpleEventLoop eventLoop;
+	BoostNetworkFactories networkFactories(&eventLoop);
+
+	EchoBot bot(&eventLoop, &networkFactories);
+
+	eventLoop.run();
+	return 0;
+}
+//...
diff --git a/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/EchoComponent.cpp b/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/EchoComponent.cpp
index 0a856f9..a4155be 100644
--- a/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/EchoComponent.cpp
+++ b/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/EchoComponent.cpp
@@ -7,7 +7,7 @@
 #include <iostream>
 #include <boost/bind.hpp>
 
-#include "Swiften/Swiften.h"
+#include <Swiften/Swiften.h>
 
 using namespace Swift;
 using namespace boost;
diff --git a/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/EchoPayload.h b/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/EchoPayload.h
new file mode 100644
index 0000000..1354ebf
--- /dev/null
+++ b/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/EchoPayload.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+//...
+#pragma once
+
+#include <Swiften/Swiften.h>
+
+using namespace Swift;
+//...
+class EchoPayload : public Payload {
+	public:
+		EchoPayload() {}
+
+		const String& getMessage() const {
+			return message;
+		}
+
+		void setMessage(const String& message) {
+			this->message = message;
+		}
+
+	private:
+		String message;
+};
diff --git a/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/EchoPayloadParserFactory.h b/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/EchoPayloadParserFactory.h
new file mode 100644
index 0000000..3af616c
--- /dev/null
+++ b/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/EchoPayloadParserFactory.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Swiften.h>
+#include "EchoPayload.h"
+
+using namespace Swift;
+
+class EchoPayloadParser : public GenericPayloadParser<EchoPayload> {
+	public:
+		EchoPayloadParser() : currentDepth(0) {}
+
+		void handleStartElement(
+				const String& /* element */, const String& /* ns */, const AttributeMap&) {
+			currentDepth++;
+		}
+
+		void handleEndElement(const String& /* element */, const String& /* ns */) {
+			currentDepth--;
+			if (currentDepth == 0) {
+				getPayloadInternal()->setMessage(currentText);
+			}
+		}
+
+		void handleCharacterData(const String& data) {
+			currentText += data;
+		}
+
+	private:
+		int currentDepth;
+		String currentText;
+};
+
+class EchoPayloadParserFactory : public GenericPayloadParserFactory<EchoPayloadParser> {
+	public:
+		EchoPayloadParserFactory() :
+			GenericPayloadParserFactory<EchoPayloadParser>("echo", "http://swift.im/echo") {}
+};
diff --git a/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/EchoPayloadSerializer.h b/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/EchoPayloadSerializer.h
new file mode 100644
index 0000000..1b18be4
--- /dev/null
+++ b/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/EchoPayloadSerializer.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Swiften.h>
+#include "EchoPayload.h"
+
+using namespace Swift;
+
+class EchoPayloadSerializer : public GenericPayloadSerializer<EchoPayload> {
+	public:
+		String serializePayload(boost::shared_ptr<EchoPayload> payload) const {
+			XMLElement element("echo", "http://swift.im/protocol/echo");
+			element.addNode(XMLTextNode::ref(new XMLTextNode(payload->getMessage())));
+			return element.serialize();
+		}
+};
diff --git a/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/SConscript b/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/SConscript
index 2ccfb7e..1e410cf 100644
--- a/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/SConscript
+++ b/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/SConscript
@@ -4,6 +4,6 @@ example_env = env.Clone()
 example_env.MergeFlags(example_env["SWIFTEN_FLAGS"])
 example_env.MergeFlags(example_env["SWIFTEN_DEP_FLAGS"])
 
-for i in range(1,6) :
+for i in range(1,7) :
 	example_env.Program("EchoBot" + str(i), ["EchoBot" + str(i) + ".cpp"])
 example_env.Program("EchoComponent", "EchoComponent.cpp")
diff --git a/Documentation/SwiftenDevelopersGuide/SConscript b/Documentation/SwiftenDevelopersGuide/SConscript
index dc00ab4..54a3ad2 100644
--- a/Documentation/SwiftenDevelopersGuide/SConscript
+++ b/Documentation/SwiftenDevelopersGuide/SConscript
@@ -84,8 +84,11 @@ def generateDocBookCode(env, target, source) :
 if "doc" in ARGUMENTS :
 	env.DocBook("Swiften Developers Guide.xml")
 
-for i in range(1, 6) :
-	source = "Examples/EchoBot/EchoBot" + str(i) + ".cpp"
+sources = []
+for i in range(1, 7) :
+	sources.append("Examples/EchoBot/EchoBot" + str(i) + ".cpp")
+sources += ["Examples/EchoBot/" + i for i in ["EchoPayloadParserFactory.h", "EchoPayloadSerializer.h", "EchoPayload.h"]]
+for source in sources :
 	env.Command(source + ".xml", source, Action(generateDocBookCode, cmdstr = "$GENCOMSTR"))
 
 SConscript(dirs = ["Examples"])
diff --git a/Documentation/SwiftenDevelopersGuide/Swiften Developers Guide.xml b/Documentation/SwiftenDevelopersGuide/Swiften Developers Guide.xml
index 52af24e..ea4ccd4 100644
--- a/Documentation/SwiftenDevelopersGuide/Swiften Developers Guide.xml	
+++ b/Documentation/SwiftenDevelopersGuide/Swiften Developers Guide.xml	
@@ -301,7 +301,78 @@
         <literal>RosterPayload</literal>.
       </para>
 
-      <remark>TODO</remark>
+      <para>
+        If you want to extend Swiften with your own XMPP extension, you will first
+        need to create a payload for this extension. For example, suppose we want to
+        reate an extension for use in our Echo bot that contains a special textual
+        message, and add this to all our outgoing messages,
+        we create the <literal>EchoPayload</literal> illustrated in
+        <xref linkend="Example-EchoPayload"/>. We can then append or retrieve this
+        payload from the stanzas using <literal>Stanza::getPayload()</literal> and 
+        <literal>Stanza::addPayload()</literal>. For example, the version of our
+        bot in <xref linkend="Example-EchoBot6"/> checks whether an incoming 
+        message contains the <literal>EchoPayload</literal>, and if not, 
+        echoes back the message, and adds an extension to the message with a 
+        descriptive text.
+      </para>
+      
+      <example id="Example-EchoPayload">
+        <title>Extending Swiften with a new payload: <literal>EchoPayload</literal></title>
+        <include xmlns="http://www.w3.org/2001/XInclude" href="Examples/EchoBot/EchoPayload.h.xml" xpointer="xpointer(//programlisting|//calloutlist)"/>
+      </example>
+      
+      <example id="Example-EchoBot6">
+        <title>Adding a custom extension: Using a custom element, and registering a parser (factory) and serializer for the element.</title>
+        <include xmlns="http://www.w3.org/2001/XInclude" href="Examples/EchoBot/EchoBot6.cpp.xml" xpointer="xpointer(//programlisting|//calloutlist)"/>
+      </example>
+
+      <para>
+        However, having the element is not enough; Swiften also needs to know how to
+        extract this payload from the incoming stanzas, and know how to send it on
+        outgoing stanzas. In order to do this, Swiften uses XML parsers and serializers
+        for the payload. We therefore need to create a parser and serializer for our
+        new payload, and register it with <literal>Client</literal>. Serializers are
+        implemented as subclasses from <literal>PayloadSerializer</literal>, and provide
+        the basic methods <literal>canSerialize()</literal> and 
+        <literal>serialize()</literal>.  The serializer
+        is registered using <literal>Client::addPayloadSerializer()</literal> 
+        (and unregistered using <literal>Client::removePayloadSerializer()</literal>).
+        Parsers consist of 2 parts: a subclass of <literal>PayloadParser</literal>, which
+        parses incoming XML in an event-driven way and builds up the payload, and
+        a subclass of <literal>PayloadParserFactory</literal>, which is responsible
+        for detecting whether a given parser can parse an incoming element, and 
+        creates a parser. The parser factory is registered with the client using
+        <literal>Client::addPayloadParserFactory()</literal> (and unregistered
+        using <literal>Client::removePayloadParserFactory()</literal>).
+      </para>
+
+      <para>
+        Although you can subclass the base classes for parsers and serializers
+        directly, Swiften comes with utility classes that contain common
+        functionality for parsers and serializers. For example, for our EchoBot,
+        the parser and serializer using these utility classes is shown in 
+        <xref linkend="Example-EchoPayloadParser"/> and 
+        <xref linkend="Example-EchoPayloadSerializer"/> respectively. Registration
+        of the parser and serializer is shown in the constructor of our EchoBot in
+        <xref linkend="Example-EchoBot6"/>. 
+      </para>
+      
+      <example id="Example-EchoPayloadParser">
+        <title>The parser and parser factory for <literal>EchoPayload</literal></title>
+        <include xmlns="http://www.w3.org/2001/XInclude" href="Examples/EchoBot/EchoPayloadParserFactory.h.xml" xpointer="xpointer(//programlisting|//calloutlist)"/>
+      </example>
+            
+      <example id="Example-EchoPayloadSerializer">
+        <title>The serializer for <literal>EchoPayload</literal></title>
+        <include xmlns="http://www.w3.org/2001/XInclude" href="Examples/EchoBot/EchoPayloadSerializer.h.xml" xpointer="xpointer(//programlisting|//calloutlist)"/>
+      </example>
+
+      <para>
+        If you want to create your own parser and serializers, you can look at the
+        built-in parsers and serializers in the Swiften library, located in
+        <literal>Swiften/Parser/PayloadParsers</literal> and <literal>Swiften/Serializer/PayloadSerializers</literal>.
+      </para>
+      
     </sect1>
 
     <sect1 id="Section-CustomQueries">
diff --git a/Swiften/Parser/GenericPayloadParser.h b/Swiften/Parser/GenericPayloadParser.h
index 0c0f8c3..a1720e8 100644
--- a/Swiften/Parser/GenericPayloadParser.h
+++ b/Swiften/Parser/GenericPayloadParser.h
@@ -4,8 +4,7 @@
  * See Documentation/Licenses/GPLv3.txt for more information.
  */
 
-#ifndef GENERICPAYLOADPARSER_H
-#define GENERICPAYLOADPARSER_H
+#pragma once
 
 #include <boost/shared_ptr.hpp>
 
@@ -15,6 +14,12 @@ namespace Swift {
 	class String;
 	class FormParser;
 
+	/**
+	 * A generic payload parser for payloads of the given type.
+	 *
+	 * This class provides getPayloadInternal() for retrieving the actual
+	 * payload.
+	 */
 	template<typename PAYLOAD_TYPE>
 	class GenericPayloadParser : public PayloadParser {
 		public:
@@ -34,5 +39,3 @@ namespace Swift {
 			boost::shared_ptr<PAYLOAD_TYPE> payload_;
 	};
 }
-
-#endif
diff --git a/Swiften/Parser/GenericPayloadParserFactory.h b/Swiften/Parser/GenericPayloadParserFactory.h
index 05b996a..a636dd7 100644
--- a/Swiften/Parser/GenericPayloadParserFactory.h
+++ b/Swiften/Parser/GenericPayloadParserFactory.h
@@ -11,9 +11,15 @@
 
 namespace Swift {
 
+	/**
+	 * A generic class for PayloadParserFactories that parse a specific payload (given as the template parameter of the class).
+	 */
 	template<typename PARSER_TYPE>
 	class GenericPayloadParserFactory : public PayloadParserFactory {
 		public:
+			/**
+			 * Construct a parser factory that can parse the given top-level tag in the given namespace.
+			 */
 			GenericPayloadParserFactory(const String& tag, const String& xmlns = "") : tag_(tag), xmlns_(xmlns) {}
 
 			virtual bool canParse(const String& element, const String& ns, const AttributeMap&) const {
diff --git a/Swiften/Parser/PayloadParser.h b/Swiften/Parser/PayloadParser.h
index 8a0fc35..a5a9025 100644
--- a/Swiften/Parser/PayloadParser.h
+++ b/Swiften/Parser/PayloadParser.h
@@ -4,8 +4,7 @@
  * See Documentation/Licenses/GPLv3.txt for more information.
  */
 
-#ifndef SWIFTEN_PAYLOADPARSER_H
-#define SWIFTEN_PAYLOADPARSER_H
+#pragma once
 
 #include <boost/shared_ptr.hpp>
 #include "Swiften/Parser/AttributeMap.h"
@@ -15,16 +14,36 @@
 namespace Swift {
 	class String;
 
+	/**
+	 * A parser for XMPP stanza payloads.
+	 *
+	 * The parser is event driven: handleStartElement, handleEndElement, and handleCharacterData will be called
+	 * when the parser detects start and end of XML elements, or character data.
+	 * After the data for the given top-level element is processed, getPayload() will be called to retrieve the
+	 * payload.
+	 */
 	class PayloadParser {
 		public:
 			virtual ~PayloadParser();
 
+			/**
+			 * Handle the start of an XML element.
+			 */
 			virtual void handleStartElement(const String& element, const String& ns, const AttributeMap& attributes) = 0;
+
+			/**
+			 * Handle the end of an XML element.
+			 */
 			virtual void handleEndElement(const String& element, const String& ns) = 0;
+
+			/**
+			 * Handle character data.
+			 */
 			virtual void handleCharacterData(const String& data) = 0;
 
-			virtual boost::shared_ptr<Payload> getPayload() const = 0;
+			/**
+			 * Retrieve a pointer to the payload.
+			 */
+			virtual Payload::ref getPayload() const = 0;
 	};
 }
-
-#endif
diff --git a/Swiften/Parser/PayloadParserFactory.h b/Swiften/Parser/PayloadParserFactory.h
index d97595b..3d647c6 100644
--- a/Swiften/Parser/PayloadParserFactory.h
+++ b/Swiften/Parser/PayloadParserFactory.h
@@ -4,8 +4,7 @@
  * See Documentation/Licenses/GPLv3.txt for more information.
  */
 
-#ifndef SWIFTEN_PAYLOADPARSERFACTORY_H
-#define SWIFTEN_PAYLOADPARSERFACTORY_H
+#pragma once
 
 #include "Swiften/Parser/AttributeMap.h"
 
@@ -13,13 +12,21 @@ namespace Swift {
 	class String;
 	class PayloadParser;
 
+	/**
+	 * A factory for PayloadParsers.
+	 */
 	class PayloadParserFactory {
 		public:
 			virtual ~PayloadParserFactory();
 
+			/**
+			 * Checks whether this factory can parse the given top-level element in the given namespace (with the given attributes).
+			 */
 			virtual bool canParse(const String& element, const String& ns, const AttributeMap& attributes) const = 0;
+
+			/**
+			 * Creates a new payload parser.
+			 */
 			virtual PayloadParser* createPayloadParser() = 0;
 	};
 }
-
-#endif
diff --git a/Swiften/SConscript b/Swiften/SConscript
index 9827171..afab713 100644
--- a/Swiften/SConscript
+++ b/Swiften/SConscript
@@ -293,7 +293,7 @@ if env["SCONS_STAGE"] == "build" :
 	# Generate the Swiften header
 	swiften_header = "#pragma once\n"
 	top_path = env.Dir("..").abspath
-	public_dirs = ["Avatars", "Base", "Chat", "Client", "Component", "Disco", "Entity", "Elements", "JID", "MUC", "Network", "Presence", "Queries", "Roster", "StringCodecs", "TLS", "VCards"]
+	public_dirs = ["Avatars", "Base", "Chat", "Client", "Component", "Disco", "Entity", "Elements", "JID", "MUC", "Network", "Parser", "Presence", "Queries", "Roster", "Serializer", "StringCodecs", "TLS", "VCards"]
 	for public_dir in public_dirs :
 		for root, dirs, files in os.walk(env.Dir(public_dir).abspath) :
 			if root.endswith("UnitTest") :
@@ -303,7 +303,7 @@ if env["SCONS_STAGE"] == "build" :
 			for file in files :
 				if not file.endswith(".h") :
 					continue
-				if file.startswith("CAres") :
+				if file.startswith("CAres") or file.startswith("LibXML") or file.startswith("Expat") :
 					continue
 				swiften_header += "#include \"" + os.path.relpath(os.path.join(root, file), top_path) + "\"\n"
 	for file in ["EventLoop/SimpleEventLoop.h"] :
diff --git a/Swiften/Serializer/GenericPayloadSerializer.h b/Swiften/Serializer/GenericPayloadSerializer.h
index b1cb9c4..b415256 100644
--- a/Swiften/Serializer/GenericPayloadSerializer.h
+++ b/Swiften/Serializer/GenericPayloadSerializer.h
@@ -4,8 +4,7 @@
  * See Documentation/Licenses/GPLv3.txt for more information.
  */
 
-#ifndef SWIFTEN_GenericPayloadSerializer_H
-#define SWIFTEN_GenericPayloadSerializer_H
+#pragma once
 
 #include <boost/shared_ptr.hpp>
 
@@ -27,5 +26,3 @@ namespace Swift {
 			virtual String serializePayload(boost::shared_ptr<PAYLOAD_TYPE>) const = 0;
 	};
 }
-
-#endif
-- 
cgit v0.10.2-6-g49f6