diff -r df8130a4a03b src/core/application.cpp
--- a/src/core/application.cpp	Fri Feb 06 20:58:23 2015 +0100
+++ b/src/core/application.cpp	Mon Feb 09 16:19:21 2015 -0500
@@ -25,7 +25,7 @@
 #include "gui/mainwindow.h"
 #include <cassert>
 
-class Application::PrivData
+QPrivData(Application)
 {
 	public:
 		MainWindow *mainWindow;
@@ -37,7 +37,6 @@
 Application::Application(int &argc, char **argv)
 : QApplication(argc, argv)
 {
-	d = new PrivData();
 	d->mainWindow = NULL;
 	d->running = true;
 }
@@ -45,7 +44,6 @@
 
 Application::~Application()
 {
-	delete d;
 }
 
 void Application::deinit()
diff -r df8130a4a03b src/core/application.h
--- a/src/core/application.h	Fri Feb 06 20:58:23 2015 +0100
+++ b/src/core/application.h	Mon Feb 09 16:19:21 2015 -0500
@@ -24,6 +24,7 @@
 #define id5E252D92_36B9_40C2_964DBFD7D0E99622
 
 #include "global.h"
+#include "dpointer.h"
 
 #include <QApplication>
 
@@ -31,7 +32,7 @@
 
 class MainWindow;
 
-/**
+/**
  * @ingroup group_pluginapi
  * @brief Program central hub of information.
  *
@@ -94,8 +95,7 @@
 		void stopRunning();
 
 	private:
-		class PrivData;
-		PrivData *d;
+		Pimpl<Application> d;
 
 		static Application *staticInstance;
 
diff -r df8130a4a03b src/core/configuration/serverpasswordsummary.cpp
--- a/src/core/configuration/serverpasswordsummary.cpp	Fri Feb 06 20:58:23 2015 +0100
+++ b/src/core/configuration/serverpasswordsummary.cpp	Mon Feb 09 16:19:21 2015 -0500
@@ -27,7 +27,7 @@
 const QString ServerPasswordType::CONNECT = "Connect";
 const QString ServerPasswordType::INGAME = "InGame";
 
-class ServerPasswordSummary::PrivData
+QPrivData(ServerPasswordSummary)
 {
 	public:
 		ServerSummary serverSummary;
@@ -42,19 +42,16 @@
 
 ServerPasswordSummary::ServerPasswordSummary()
 {
-	d = new PrivData();
 }
 
 ServerPasswordSummary::ServerPasswordSummary(const Server *server, const QString &type)
 {
-	d = new PrivData();
 	d->serverSummary = ServerSummary(server);
 	d->type = type;
 }
 
 ServerPasswordSummary::~ServerPasswordSummary()
 {
-	delete d;
 }
 
 ServerPasswordSummary ServerPasswordSummary::deserializeQVariant(const QVariant& v)
diff -r df8130a4a03b src/core/configuration/serverpasswordsummary.h
--- a/src/core/configuration/serverpasswordsummary.h	Fri Feb 06 20:58:23 2015 +0100
+++ b/src/core/configuration/serverpasswordsummary.h	Mon Feb 09 16:19:21 2015 -0500
@@ -20,8 +20,8 @@
 //------------------------------------------------------------------------------
 // Copyright (C) 2014 "Zalewa" <zalewapl@gmail.com>
 //------------------------------------------------------------------------------
-#ifndef idA2EA6505_8AD6_40F7_AD19A3DFD8DBC961
-#define idA2EA6505_8AD6_40F7_AD19A3DFD8DBC961
+#ifndef idA2EA6505_8AD6_40F7_AD19A3DFD8DBC961
+#define idA2EA6505_8AD6_40F7_AD19A3DFD8DBC961
 
 #include "dpointer.h"
 #include <QString>
@@ -36,7 +36,7 @@
 		static const QString CONNECT;
 		static const QString INGAME;
 };
-
+
 class ServerPasswordSummary
 {
 	public:
@@ -98,9 +98,7 @@
 		const QString &typeWithCompatibility() const;
 
 	private:
-		class PrivData;
-		PrivData *d;
+		Pimpl<ServerPasswordSummary> d;
+};
 
-};
-
-#endif
+#endif
diff -r df8130a4a03b src/core/connectionhandler.cpp
--- a/src/core/connectionhandler.cpp	Fri Feb 06 20:58:23 2015 +0100
+++ b/src/core/connectionhandler.cpp	Mon Feb 09 16:19:21 2015 -0500
@@ -1,229 +1,227 @@
-//------------------------------------------------------------------------------
-// connectionhandler.cpp
-//------------------------------------------------------------------------------
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-// 02110-1301, USA.
-//
-//------------------------------------------------------------------------------
-// Copyright (C) 2012 Braden Obrzut <admin@maniacsvault.net>
-//                    "Zalewa" <zalewapl@gmail.com>
-//------------------------------------------------------------------------------
-#include "connectionhandler.h"
-
-#include "joincommandlinebuilder.h"
-#include "log.h"
-#include "strings.h"
-#include "configuration/doomseekerconfig.h"
-#include "gui/configuration/doomseekerconfigurationdialog.h"
-#include "plugins/engineplugin.h"
-#include "plugins/pluginloader.h"
-#include "refresher/canrefreshserver.h"
-#include "refresher/refresher.h"
-#include "serverapi/gameclientrunner.h"
-#include "serverapi/message.h"
-#include "serverapi/server.h"
-#include "apprunner.h"
-#include "gamedemo.h"
-#include <QDesktopServices>
-#include <QMessageBox>
-#include <QUrl>
-
-class ConnectionHandler::PrivData
-{
-	public:
-		bool handleResponse;
-		ServerPtr server;
-		QWidget *parentWidget;
-};
-
-ConnectionHandler::ConnectionHandler(ServerPtr server, QWidget *parentWidget,
-	bool handleResponse)
-: QObject(parentWidget)
-{
-	d = new PrivData();
-	d->handleResponse = handleResponse;
-	d->server = server;
-	d->parentWidget = parentWidget;
-	connect(d->server.data(), SIGNAL(updated(ServerPtr, int)),
-		this, SLOT(checkResponse(ServerPtr, int)));
-}
-
-ConnectionHandler::~ConnectionHandler()
-{
-	delete d;
-}
-
-void ConnectionHandler::checkResponse(const ServerPtr &server, int response)
-{
-	if(response != Server::RESPONSE_GOOD)
-	{
-		if(d->handleResponse)
-		{
-			switch(response)
-			{
-				case Server::RESPONSE_TIMEOUT:
-					QMessageBox::critical(d->parentWidget, tr("Doomseeker - join server"), tr("Connection to server timed out."));
-					break;
-				default:
-					QMessageBox::critical(d->parentWidget, tr("Doomseeker - join server"), tr("An error occured while trying to connect to server."));
-					break;
-			}
-		}
-
-		finish(response);
-		return;
-	}
-
-	run();
-}
-
-ConnectionHandler *ConnectionHandler::connectByUrl(const QUrl &url)
-{
-	gLog << QString("Attempting to connect to server: %1").arg(url.toString());
-
-	// Locate plugin by scheme
-	const EnginePlugin *handler = NULL;
-	// For compatibility with IDE's zds://.../<two character> scheme
-	bool zdsScheme = url.scheme().compare("zds", Qt::CaseInsensitive) == 0;
-	for(unsigned int i = 0;i < gPlugins->numPlugins();++i)
-	{
-		const EnginePlugin *plugin = gPlugins->plugin(i)->info();
-		if(plugin->data()->scheme.compare(url.scheme(), Qt::CaseInsensitive) == 0 ||
-			(zdsScheme && plugin->data()->scheme.left(2).compare(url.path().mid(1), Qt::CaseInsensitive) == 0))
-		{
-			handler = plugin;
-			break;
-		}
-	}
-	if(handler == NULL)
-	{
-		gLog << "Scheme not recognized starting normally.";
-		return NULL;
-	}
-
-	unsigned short port = url.port(handler->data()->defaultServerPort);
-	QString address;
-	// We can get the port through QUrl so we'll just create a temporary variable here.
-	unsigned short tmp;
-	Strings::translateServerAddress(url.host(), address, tmp, QString("localhost:10666"));
-
-	// Create the server object
-	ServerPtr server = handler->server(QHostAddress(address), port);
-	ConnectionHandler *connectionHandler = new ConnectionHandler(server, NULL, true);
-	gRefresher->registerServer(server.data());
-
-	return connectionHandler;
-}
-
-void ConnectionHandler::finish(int response)
-{
-	d->server->disconnect(this);
-	emit finished(response);
-}
-
-void ConnectionHandler::buildJoinCommandLine()
-{
-	JoinCommandLineBuilder *builder = new JoinCommandLineBuilder(d->server,
-		gConfig.doomseeker.bRecordDemo ? GameDemo::Managed : GameDemo::NoDemo,
-		d->parentWidget);
-	this->connect(builder, SIGNAL(commandLineBuildFinished()), SLOT(onCommandLineBuildFinished()));
-	builder->obtainJoinCommandLine();
-}
-
-void ConnectionHandler::onCommandLineBuildFinished()
-{
-	JoinCommandLineBuilder *builder = static_cast<JoinCommandLineBuilder*>(sender());
-	CommandLineInfo builtCli = builder->builtCommandLine();
-	if (builtCli.isValid())
-	{
-		runCommandLine(builtCli);
-	}
-	else
-	{
-		if (!builder->error().isEmpty())
-		{
-			QMessageBox::critical(d->parentWidget, tr("Doomseeker - join game"), builder->error());
-		}
+//------------------------------------------------------------------------------
+// connectionhandler.cpp
+//------------------------------------------------------------------------------
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+// 02110-1301, USA.
+//
+//------------------------------------------------------------------------------
+// Copyright (C) 2012 Braden Obrzut <admin@maniacsvault.net>
+//                    "Zalewa" <zalewapl@gmail.com>
+//------------------------------------------------------------------------------
+#include "connectionhandler.h"
+
+#include "joincommandlinebuilder.h"
+#include "log.h"
+#include "strings.h"
+#include "configuration/doomseekerconfig.h"
+#include "gui/configuration/doomseekerconfigurationdialog.h"
+#include "plugins/engineplugin.h"
+#include "plugins/pluginloader.h"
+#include "refresher/canrefreshserver.h"
+#include "refresher/refresher.h"
+#include "serverapi/gameclientrunner.h"
+#include "serverapi/message.h"
+#include "serverapi/server.h"
+#include "apprunner.h"
+#include "gamedemo.h"
+#include <QDesktopServices>
+#include <QMessageBox>
+#include <QUrl>
+
+QPrivData(ConnectionHandler)
+{
+	public:
+		bool handleResponse;
+		ServerPtr server;
+		QWidget *parentWidget;
+};
+
+ConnectionHandler::ConnectionHandler(ServerPtr server, QWidget *parentWidget,
+	bool handleResponse)
+: QObject(parentWidget)
+{
+	d->handleResponse = handleResponse;
+	d->server = server;
+	d->parentWidget = parentWidget;
+	connect(d->server.data(), SIGNAL(updated(ServerPtr, int)),
+		this, SLOT(checkResponse(ServerPtr, int)));
+}
+
+ConnectionHandler::~ConnectionHandler()
+{
+}
+
+void ConnectionHandler::checkResponse(const ServerPtr &server, int response)
+{
+	if(response != Server::RESPONSE_GOOD)
+	{
+		if(d->handleResponse)
+		{
+			switch(response)
+			{
+				case Server::RESPONSE_TIMEOUT:
+					QMessageBox::critical(d->parentWidget, tr("Doomseeker - join server"), tr("Connection to server timed out."));
+					break;
+				default:
+					QMessageBox::critical(d->parentWidget, tr("Doomseeker - join server"), tr("An error occured while trying to connect to server."));
+					break;
+			}
+		}
+
+		finish(response);
+		return;
+	}
+
+	run();
+}
+
+ConnectionHandler *ConnectionHandler::connectByUrl(const QUrl &url)
+{
+	gLog << QString("Attempting to connect to server: %1").arg(url.toString());
+
+	// Locate plugin by scheme
+	const EnginePlugin *handler = NULL;
+	// For compatibility with IDE's zds://.../<two character> scheme
+	bool zdsScheme = url.scheme().compare("zds", Qt::CaseInsensitive) == 0;
+	for(unsigned int i = 0;i < gPlugins->numPlugins();++i)
+	{
+		const EnginePlugin *plugin = gPlugins->plugin(i)->info();
+		if(plugin->data()->scheme.compare(url.scheme(), Qt::CaseInsensitive) == 0 ||
+			(zdsScheme && plugin->data()->scheme.left(2).compare(url.path().mid(1), Qt::CaseInsensitive) == 0))
+		{
+			handler = plugin;
+			break;
+		}
+	}
+	if(handler == NULL)
+	{
+		gLog << "Scheme not recognized starting normally.";
+		return NULL;
+	}
+
+	unsigned short port = url.port(handler->data()->defaultServerPort);
+	QString address;
+	// We can get the port through QUrl so we'll just create a temporary variable here.
+	unsigned short tmp;
+	Strings::translateServerAddress(url.host(), address, tmp, QString("localhost:10666"));
+
+	// Create the server object
+	ServerPtr server = handler->server(QHostAddress(address), port);
+	ConnectionHandler *connectionHandler = new ConnectionHandler(server, NULL, true);
+	gRefresher->registerServer(server.data());
+
+	return connectionHandler;
+}
+
+void ConnectionHandler::finish(int response)
+{
+	d->server->disconnect(this);
+	emit finished(response);
+}
+
+void ConnectionHandler::buildJoinCommandLine()
+{
+	JoinCommandLineBuilder *builder = new JoinCommandLineBuilder(d->server,
+		gConfig.doomseeker.bRecordDemo ? GameDemo::Managed : GameDemo::NoDemo,
+		d->parentWidget);
+	this->connect(builder, SIGNAL(commandLineBuildFinished()), SLOT(onCommandLineBuildFinished()));
+	builder->obtainJoinCommandLine();
+}
+
+void ConnectionHandler::onCommandLineBuildFinished()
+{
+	JoinCommandLineBuilder *builder = static_cast<JoinCommandLineBuilder*>(sender());
+	CommandLineInfo builtCli = builder->builtCommandLine();
+	if (builtCli.isValid())
+	{
+		runCommandLine(builtCli);
+	}
+	else
+	{
+		if (!builder->error().isEmpty())
+		{
+			QMessageBox::critical(d->parentWidget, tr("Doomseeker - join game"), builder->error());
+		}
 		if (builder->isConfigurationError())
 		{
 			DoomseekerConfigurationDialog::openConfiguration(d->server->plugin());
-		}
-	}
-	builder->deleteLater();
-	finish(Server::RESPONSE_GOOD);
-}
-
-void ConnectionHandler::runCommandLine(const CommandLineInfo &cli)
-{
-	Message message = AppRunner::runExecutable(cli);
-	if (message.isError())
-	{
-		gLog << tr("Error while launching executable for server \"%1\", game \"%2\": %3")
-			.arg(d->server->name()).arg(d->server->engineName()).arg(message.contents());
-		QMessageBox::critical(d->parentWidget, tr("Doomseeker - launch executable"), message.contents());
-	}
-}
-
-void ConnectionHandler::refreshToJoin()
-{
-	// If the data we have is old we should refresh first to check if we can
-	// still properly join the server.
-	CanRefreshServer refreshCheck(d->server.data());
-	if(refreshCheck.shouldRefresh() && gConfig.doomseeker.bQueryBeforeLaunch)
-	{
-		gRefresher->registerServer(d->server.data());
-	}
-	else
-	{
-		checkResponse(d->server, Server::RESPONSE_GOOD);
-	}
-}
-
-void ConnectionHandler::run()
-{
-	buildJoinCommandLine();
-}
-
-// -------------------------- URL Handler -------------------------------------
-
-PluginUrlHandler *PluginUrlHandler::instance = NULL;
-
-void PluginUrlHandler::registerAll()
-{
-	for(unsigned int i = 0;i < gPlugins->numPlugins();++i)
-		registerScheme(gPlugins->plugin(i)->info()->data()->scheme);
-
-	// IDE compatibility
-	registerScheme("zds");
-}
-
-void PluginUrlHandler::registerScheme(const QString &scheme)
-{
-	if(!instance)
-		instance = new PluginUrlHandler();
-
-	QDesktopServices::setUrlHandler(scheme, instance, "handleUrl");
-}
-
-void PluginUrlHandler::handleUrl(const QUrl &url)
-{
-	if(QMessageBox::question(NULL, tr("Connect to server"),
-		tr("Do you want to connect to the server at %1?").arg(url.toString()),
-		QMessageBox::Yes|QMessageBox::No, QMessageBox::No) == QMessageBox::Yes)
-	{
-		ConnectionHandler::connectByUrl(url);
-	}
-}
+		}
+	}
+	builder->deleteLater();
+	finish(Server::RESPONSE_GOOD);
+}
+
+void ConnectionHandler::runCommandLine(const CommandLineInfo &cli)
+{
+	Message message = AppRunner::runExecutable(cli);
+	if (message.isError())
+	{
+		gLog << tr("Error while launching executable for server \"%1\", game \"%2\": %3")
+			.arg(d->server->name()).arg(d->server->engineName()).arg(message.contents());
+		QMessageBox::critical(d->parentWidget, tr("Doomseeker - launch executable"), message.contents());
+	}
+}
+
+void ConnectionHandler::refreshToJoin()
+{
+	// If the data we have is old we should refresh first to check if we can
+	// still properly join the server.
+	CanRefreshServer refreshCheck(d->server.data());
+	if(refreshCheck.shouldRefresh() && gConfig.doomseeker.bQueryBeforeLaunch)
+	{
+		gRefresher->registerServer(d->server.data());
+	}
+	else
+	{
+		checkResponse(d->server, Server::RESPONSE_GOOD);
+	}
+}
+
+void ConnectionHandler::run()
+{
+	buildJoinCommandLine();
+}
+
+// -------------------------- URL Handler -------------------------------------
+
+PluginUrlHandler *PluginUrlHandler::instance = NULL;
+
+void PluginUrlHandler::registerAll()
+{
+	for(unsigned int i = 0;i < gPlugins->numPlugins();++i)
+		registerScheme(gPlugins->plugin(i)->info()->data()->scheme);
+
+	// IDE compatibility
+	registerScheme("zds");
+}
+
+void PluginUrlHandler::registerScheme(const QString &scheme)
+{
+	if(!instance)
+		instance = new PluginUrlHandler();
+
+	QDesktopServices::setUrlHandler(scheme, instance, "handleUrl");
+}
+
+void PluginUrlHandler::handleUrl(const QUrl &url)
+{
+	if(QMessageBox::question(NULL, tr("Connect to server"),
+		tr("Do you want to connect to the server at %1?").arg(url.toString()),
+		QMessageBox::Yes|QMessageBox::No, QMessageBox::No) == QMessageBox::Yes)
+	{
+		ConnectionHandler::connectByUrl(url);
+	}
+}
diff -r df8130a4a03b src/core/connectionhandler.h
--- a/src/core/connectionhandler.h	Fri Feb 06 20:58:23 2015 +0100
+++ b/src/core/connectionhandler.h	Mon Feb 09 16:19:21 2015 -0500
@@ -26,6 +26,7 @@
 #define __CONNECTIONHANDLER_H__
 
 #include "serverapi/serverptr.h"
+#include "dpointer.h"
 #include <QObject>
 
 class CommandLineInfo;
@@ -76,8 +77,7 @@
 		void finished(int response);
 
 	private:
-		class PrivData;
-		PrivData *d;
+		Pimpl<ConnectionHandler> d;
 
 		void buildJoinCommandLine();
 		void runCommandLine(const CommandLineInfo &cli);
diff -r df8130a4a03b src/core/datapaths.cpp
--- a/src/core/datapaths.cpp	Fri Feb 06 20:58:23 2015 +0100
+++ b/src/core/datapaths.cpp	Mon Feb 09 16:19:21 2015 -0500
@@ -28,7 +28,7 @@
 #include <cassert>
 #include <cstdlib>
 
-class DataPaths::PrivData
+QPrivData(DataPaths)
 {
 	public:
 		bool bIsPortableModeOn;
@@ -57,7 +57,6 @@
 
 DataPaths::DataPaths(bool bPortableModeOn)
 {
-	d = new PrivData();
 	d->bIsPortableModeOn = bPortableModeOn;
 
 	d->programsDirectoryName = PROGRAMS_APPDATA_DIR_NAME;
@@ -68,7 +67,6 @@
 
 DataPaths::~DataPaths()
 {
-	delete d;
 }
 
 QStringList DataPaths::canWrite() const
diff -r df8130a4a03b src/core/datapaths.h
--- a/src/core/datapaths.h	Fri Feb 06 20:58:23 2015 +0100
+++ b/src/core/datapaths.h	Mon Feb 09 16:19:21 2015 -0500
@@ -24,13 +24,14 @@
 #define __DATAPATHS_H__
 
 #include "global.h"
+#include "dpointer.h"
 #include <QDir>
 #include <QString>
 #include <QStringList>
 
 #define gDefaultDataPaths (DataPaths::defaultInstance())
 
-/**
+/**
  * @ingroup group_pluginapi
  * @brief Represents directories used by Doomseeker to store data.
  *
@@ -49,10 +50,10 @@
 			Preferred
 		};
 
-		static const QString PROGRAMS_APPDATA_DIR_NAME;
+		static const QString PROGRAMS_APPDATA_DIR_NAME;
 		static const QString PROGRAMS_APPDATASUPPORT_DIR_NAME;
 		static const QString DEMOS_DIR_NAME;
-		static const QString CHATLOGS_DIR_NAME;
+		static const QString CHATLOGS_DIR_NAME;
 		static const QString TRANSLATIONS_DIR_NAME;
 		static const QString UPDATE_PACKAGES_DIR_NAME;
 		static const QString UPDATE_PACKAGE_FILENAME_PREFIX;
@@ -147,18 +148,18 @@
 		 *	is determined by calling the systemAppDataDirectory() method and
 		 *	appending string returned by programDirName() getter.
 		 */
-		QString programsDataDirectoryPath() const;
-
+		QString programsDataDirectoryPath() const;
+
 		/**
 		 * @brief Defaults to PROGRAMS_APPDATA_DIR_NAME.
 		 */
-		const QString &programDirName() const;
-
-		/**
-		 *  @brief Allows switching from Preferences to Application Support on OS X.
-		 *
-		 *  Same as programsDataDirectoryPath() on other systems or in portable mode.
-		 */
+		const QString &programDirName() const;
+
+		/**
+		 *  @brief Allows switching from Preferences to Application Support on OS X.
+		 *
+		 *  Same as programsDataDirectoryPath() on other systems or in portable mode.
+		 */
 		QString programsDataSupportDirectoryPath() const;
 
 		bool isPortableModeOn() const;
@@ -209,8 +210,7 @@
 		bool tryCreateDirectory(const QDir& rootDir, const QString& dirToCreate) const;
 
 	private:
-		class PrivData;
-		PrivData *d;
+		Pimpl<DataPaths> d;
 
 		static DataPaths *staticDefaultInstance;
 };
diff -r df8130a4a03b src/core/datastreamoperatorwrapper.cpp
--- a/src/core/datastreamoperatorwrapper.cpp	Fri Feb 06 20:58:23 2015 +0100
+++ b/src/core/datastreamoperatorwrapper.cpp	Mon Feb 09 16:19:21 2015 -0500
@@ -1,24 +1,24 @@
-//------------------------------------------------------------------------------
-// datastreamoperatorwrapper.h
-//------------------------------------------------------------------------------
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-// 02110-1301, USA.
-//
-//------------------------------------------------------------------------------
-// Copyright (C) 2012 "Zalewa" <zalewapl@gmail.com>
+//------------------------------------------------------------------------------
+// datastreamoperatorwrapper.h
+//------------------------------------------------------------------------------
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+// 02110-1301, USA.
+//
+//------------------------------------------------------------------------------
+// Copyright (C) 2012 "Zalewa" <zalewapl@gmail.com>
 //------------------------------------------------------------------------------
 #include "datastreamoperatorwrapper.h"
 
@@ -29,34 +29,32 @@
 type tmp; \
 (*d->s) >> tmp; \
 return tmp;
-
-class DataStreamOperatorWrapper::PrivData
-{
-	public:
-		QDataStream *s;
-};
-
-DataStreamOperatorWrapper::DataStreamOperatorWrapper(QDataStream* stream)
-{
-	assert(stream != NULL);
-	d = new PrivData();
-	d->s = stream;
-}
-
-DataStreamOperatorWrapper::~DataStreamOperatorWrapper()
-{
-	delete d;
-}
 
-QDataStream* DataStreamOperatorWrapper::dataStream()
-{
-	return d->s;
-}
-
-const QDataStream* DataStreamOperatorWrapper::dataStream() const
-{
-	return d->s;
-}
+QPrivData(DataStreamOperatorWrapper)
+{
+	public:
+		QDataStream *s;
+};
+
+DataStreamOperatorWrapper::DataStreamOperatorWrapper(QDataStream* stream)
+{
+	assert(stream != NULL);
+	d->s = stream;
+}
+
+DataStreamOperatorWrapper::~DataStreamOperatorWrapper()
+{
+}
+
+QDataStream* DataStreamOperatorWrapper::dataStream()
+{
+	return d->s;
+}
+
+const QDataStream* DataStreamOperatorWrapper::dataStream() const
+{
+	return d->s;
+}
 
 qint8 DataStreamOperatorWrapper::readQInt8()
 {
diff -r df8130a4a03b src/core/datastreamoperatorwrapper.h
--- a/src/core/datastreamoperatorwrapper.h	Fri Feb 06 20:58:23 2015 +0100
+++ b/src/core/datastreamoperatorwrapper.h	Mon Feb 09 16:19:21 2015 -0500
@@ -1,24 +1,24 @@
-//------------------------------------------------------------------------------
-// datastreamoperatorwrapper.h
-//------------------------------------------------------------------------------
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-// 02110-1301, USA.
-//
-//------------------------------------------------------------------------------
-// Copyright (C) 2012 "Zalewa" <zalewapl@gmail.com>
+//------------------------------------------------------------------------------
+// datastreamoperatorwrapper.h
+//------------------------------------------------------------------------------
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+// 02110-1301, USA.
+//
+//------------------------------------------------------------------------------
+// Copyright (C) 2012 "Zalewa" <zalewapl@gmail.com>
 //------------------------------------------------------------------------------
 #ifndef DOOMSEEKER_DATASTREAMOPERATORWRAPPER_H
 #define DOOMSEEKER_DATASTREAMOPERATORWRAPPER_H
@@ -26,8 +26,9 @@
 #include <QDataStream>
 
 #include "global.h"
+#include "dpointer.h"
 
-/**
+/**
  * @ingroup group_pluginapi
  * @brief Wraps around QDataStream stream operators to provide cleaner
  *        reading interface.
@@ -112,9 +113,8 @@
 		 */
 		int skipRawData(int len);
 
-	private:
-		class PrivData;
-		PrivData *d;
+	private:
+		Pimpl<DataStreamOperatorWrapper> d;
 };
 
 #endif
diff -r df8130a4a03b src/core/dpointer.h
--- a/src/core/dpointer.h	Fri Feb 06 20:58:23 2015 +0100
+++ b/src/core/dpointer.h	Mon Feb 09 16:19:21 2015 -0500
@@ -20,9 +20,41 @@
 //------------------------------------------------------------------------------
 // Copyright (C) 2014 "Zalewa" <zalewapl@gmail.com>
 //------------------------------------------------------------------------------
-#ifndef id91044119_93C0_4719_829DE83410DDE660
-#define id91044119_93C0_4719_829DE83410DDE660
-
+#ifndef id91044119_93C0_4719_829DE83410DDE660
+#define id91044119_93C0_4719_829DE83410DDE660
+
+#include <QScopedPointer>
+
+// Specialize me!
+template<class T> class PrivData;
+#define QPrivData(cls) template<> class PrivData<cls>
+
+// RAII wrapper for d-pointer. The pointer acts like a value and can be copied
+// via copy constructor or assignment, but one will need to declare their own
+// copy constructor/assignment operator manually since the defaults will
+// require that the PrivData structure be visible at point of use. The good
+// news is that d = other.d is perfectly adequate.
+template<class T>
+class Pimpl : public QScopedPointer<PrivData<T> >
+{
+public:
+	Pimpl() : QScopedPointer<PrivData<T> >(new PrivData<T>)
+	{
+	}
+
+	Pimpl(const Pimpl &other) : QScopedPointer<PrivData<T> >(new PrivData<T>)
+	{
+		*(this->data()) = *(other.data());
+	}
+
+	const Pimpl &operator=(const Pimpl &other)
+	{
+		if(this->data() != other.data())
+			*(this->data()) = *(other.data());
+		return *this;
+	}
+};
+
 #define COPYABLE_D_POINTERED_DECLARE(type) \
 	type(const type &other); \
 	type& operator=(const type &other);
@@ -30,32 +62,24 @@
 #define COPYABLE_D_POINTERED_DEFINE(type) \
 	type::type(const type &other) \
 	{ \
-		d = new PrivData(); \
-		*d = *other.d; \
+		d = other.d; \
 	} \
 	\
 	type& type::operator=(const type &other) \
 	{ \
-		if (this != &other) \
-		{ \
-			*d = *other.d; \
-		} \
+		d = other.d; \
 		return *this; \
 	}
 
 #define COPYABLE_D_POINTERED_INNER_DEFINE(type, constructorname) \
 	type::constructorname(const type &other) \
 	{ \
-		d = new PrivData(); \
-		*d = *other.d; \
+		d = other.d; \
 	} \
 	\
 	type& type::operator=(const type &other) \
 	{ \
-		if (this != &other) \
-		{ \
-			*d = *other.d; \
-		} \
+		d = other.d; \
 		return *this; \
 	}
 
diff -r df8130a4a03b src/core/gui/dockBuddiesList.cpp
--- a/src/core/gui/dockBuddiesList.cpp	Fri Feb 06 20:58:23 2015 +0100
+++ b/src/core/gui/dockBuddiesList.cpp	Mon Feb 09 16:19:21 2015 -0500
@@ -34,7 +34,7 @@
 #include <QRegExp>
 #include <QStandardItemModel>
 
-class DockBuddiesList::BuddyLocationInfo
+class BuddyLocationInfo
 {
 public:
 	BuddyLocationInfo(const Player &buddy, ServerPtr location);
@@ -47,14 +47,13 @@
 	bool operator==(const BuddyLocationInfo &other) const;
 
 private:
-	class PrivData;
-	PrivData *d;
+	Pimpl<BuddyLocationInfo> d;
 };
 
-class DockBuddiesList::PrivData : public Ui::DockBuddiesList
+QPrivData(DockBuddiesList) : public Ui::DockBuddiesList
 {
 public:
-	QList< ::DockBuddiesList::BuddyLocationInfo> buddies;
+	QList<BuddyLocationInfo> buddies;
 	QStandardItemModel *buddiesTableModel;
 	PatternList pBuddies;
 };
@@ -62,7 +61,6 @@
 DockBuddiesList::DockBuddiesList(QWidget *parent)
 : QDockWidget(parent), masterClient(NULL), save(false)
 {
-	d = new PrivData;
 	d->setupUi(this);
 	this->toggleViewAction()->setIcon(QIcon(":/icons/buddies.png"));
 
@@ -99,10 +97,7 @@
 	// See if we made any modification since modifying the setting will cause a
 	// write cycle.
 	if(!save)
-	{
-		delete d;
 		return;
-	}
 
 	gConfig.doomseeker.buddiesList.clear();
 	foreach (QRegExp pattern, d->pBuddies)
@@ -114,8 +109,6 @@
 
 		gConfig.doomseeker.buddiesList << buddyInfo;
 	}
-
-	delete d;
 }
 
 void DockBuddiesList::addBuddy()
@@ -282,13 +275,12 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
-class AddBuddyDlg::PrivData : public Ui::AddBuddyDlg
+QPrivData(AddBuddyDlg) : public Ui::AddBuddyDlg
 {
 };
 
 AddBuddyDlg::AddBuddyDlg(QWidget *parent) : QDialog(parent)
 {
-	d = new PrivData;
 	d->setupUi(this);
 
 	connect(d->buttonBox, SIGNAL( clicked(QAbstractButton *) ), this, SLOT( buttonBoxClicked(QAbstractButton *) ));
@@ -296,7 +288,6 @@
 
 AddBuddyDlg::~AddBuddyDlg()
 {
-	delete d;
 }
 
 void AddBuddyDlg::buttonBoxClicked(QAbstractButton *button)
@@ -330,38 +321,36 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
-class DockBuddiesList::BuddyLocationInfo::PrivData
+QPrivData(BuddyLocationInfo)
 {
 	public:
 		Player buddy;
 		ServerPtr server;
 };
 
-COPYABLE_D_POINTERED_INNER_DEFINE(DockBuddiesList::BuddyLocationInfo, BuddyLocationInfo);
+COPYABLE_D_POINTERED_DEFINE(BuddyLocationInfo);
 
-DockBuddiesList::BuddyLocationInfo::BuddyLocationInfo(const Player &buddy, ServerPtr location)
+BuddyLocationInfo::BuddyLocationInfo(const Player &buddy, ServerPtr location)
 {
-	d = new PrivData();
 	d->buddy = buddy;
 	d->server = location;
 }
 
-DockBuddiesList::BuddyLocationInfo::~BuddyLocationInfo()
+BuddyLocationInfo::~BuddyLocationInfo()
 {
-	delete d;
 }
 
-const Player &DockBuddiesList::BuddyLocationInfo::buddy() const
+const Player &BuddyLocationInfo::buddy() const
 {
 	return d->buddy;
 }
 
-ServerPtr DockBuddiesList::BuddyLocationInfo::location() const
+ServerPtr BuddyLocationInfo::location() const
 {
 	return d->server;
 }
 
-bool DockBuddiesList::BuddyLocationInfo::operator==(const BuddyLocationInfo &other) const
+bool BuddyLocationInfo::operator==(const BuddyLocationInfo &other) const
 {
 	return d->buddy == other.d->buddy
 		&& d->server->address() == other.d->server->address()
diff -r df8130a4a03b src/core/gui/dockBuddiesList.h
--- a/src/core/gui/dockBuddiesList.h	Fri Feb 06 20:58:23 2015 +0100
+++ b/src/core/gui/dockBuddiesList.h	Mon Feb 09 16:19:21 2015 -0500
@@ -26,6 +26,7 @@
 
 #include "serverapi/buddyinfo.h"
 #include "serverapi/serverptr.h"
+#include "dpointer.h"
 
 #include <QDialog>
 #include <QDockWidget>
@@ -61,17 +62,13 @@
 		void joinServer(const ServerPtr &server);
 		void scanCompleted();
 
-	protected:
-		class BuddyLocationInfo;
-
 	protected slots:
 		void deleteBuddy();
 		void followBuddy(const QModelIndex &index);
 		void patternsListContextMenu(const QPoint &pos) const;
 
 	private:
-		class PrivData;
-		PrivData *d;
+		Pimpl<DockBuddiesList> d;
 
 		const MasterManager *masterClient;
 		bool save;
@@ -92,8 +89,7 @@
 		void buttonBoxClicked(QAbstractButton *button);
 
 	private:
-		class PrivData;
-		PrivData *d;
+		Pimpl<AddBuddyDlg> d;
 };
 
 #endif /* __DOCKBUDDIESLIST_H__ */
diff -r df8130a4a03b src/core/ini/inisection.cpp
--- a/src/core/ini/inisection.cpp	Fri Feb 06 20:58:23 2015 +0100
+++ b/src/core/ini/inisection.cpp	Mon Feb 09 16:19:21 2015 -0500
@@ -26,7 +26,7 @@
 #include <cassert>
 #include <QDebug>
 
-class IniSection::PrivData
+QPrivData(IniSection)
 {
 	public:
 		QString name;
@@ -41,20 +41,17 @@
 
 IniSection::IniSection()
 {
-	d = new PrivData();
 	d->pIni = NULL;
 }
 
 IniSection::IniSection(Ini* pIni, const QString& sectionName)
 {
-	d = new PrivData();
 	d->pIni = pIni;
 	d->name = sectionName;
 }
 
 IniSection::~IniSection()
 {
-	delete d;
 }
 
 IniVariable IniSection::createSetting(const QString& name, const QVariant& data)
diff -r df8130a4a03b src/core/ini/inisection.h
--- a/src/core/ini/inisection.h	Fri Feb 06 20:58:23 2015 +0100
+++ b/src/core/ini/inisection.h	Mon Feb 09 16:19:21 2015 -0500
@@ -179,8 +179,7 @@
 		QVariant value(const QString& key, QVariant defaultValue) const;
 
 	private:
-		class PrivData;
-		PrivData *d;
+		Pimpl<IniSection> d;
 
 		/**
 		 * @brief Removes specified key in this section.
diff -r df8130a4a03b src/core/ini/inivariable.cpp
--- a/src/core/ini/inivariable.cpp	Fri Feb 06 20:58:23 2015 +0100
+++ b/src/core/ini/inivariable.cpp	Mon Feb 09 16:19:21 2015 -0500
@@ -26,7 +26,7 @@
 
 #include <cassert>
 
-class IniVariable::PrivData
+QPrivData(IniVariable)
 {
 	public:
 		/**
@@ -45,19 +45,16 @@
 
 IniVariable::IniVariable()
 {
-	d = new PrivData();
 }
 
 IniVariable::IniVariable(const IniSection &section, const QString& key)
 {
-	d = new PrivData();
 	d->section = section;
 	d->key = key;
 }
 
 IniVariable::~IniVariable()
 {
-	delete d;
 }
 
 IniVariable::operator bool() const
diff -r df8130a4a03b src/core/ini/inivariable.h
--- a/src/core/ini/inivariable.h	Fri Feb 06 20:58:23 2015 +0100
+++ b/src/core/ini/inivariable.h	Mon Feb 09 16:19:21 2015 -0500
@@ -133,8 +133,7 @@
 		friend class TestReadINIVariable;
 		friend class TestReadINIList;
 
-		class PrivData;
-		PrivData *d;
+		Pimpl<IniVariable> d;
 };
 
 #endif
diff -r df8130a4a03b src/core/ip2c/ip2cparser.cpp
--- a/src/core/ip2c/ip2cparser.cpp	Fri Feb 06 20:58:23 2015 +0100
+++ b/src/core/ip2c/ip2cparser.cpp	Mon Feb 09 16:19:21 2015 -0500
@@ -309,7 +309,7 @@
 	// Trim the header
 	textDatabase = textDatabase.right(textDatabase.size() - indexOfNewLine);
 
-	Scanner sc = Scanner(textDatabase.constData(), textDatabase.count());
+	Scanner sc(textDatabase.constData(), textDatabase.count());
 	countries.clear();
 	while(sc.tokensLeft())
 	{
diff -r df8130a4a03b src/core/irc/entities/ircnetworkentity.cpp
--- a/src/core/irc/entities/ircnetworkentity.cpp	Fri Feb 06 20:58:23 2015 +0100
+++ b/src/core/irc/entities/ircnetworkentity.cpp	Mon Feb 09 16:19:21 2015 -0500
@@ -21,12 +21,12 @@
 // Copyright (C) 2010 "Zalewa" <zalewapl@gmail.com>
 //------------------------------------------------------------------------------
 #include "ircnetworkentity.h"
-
-#include "irc/chatnetworknamer.h"
-#include "patternlist.h"
-#include <QVariantMap>
 
-class IRCNetworkEntity::PrivData
+#include "irc/chatnetworknamer.h"
+#include "patternlist.h"
+#include <QVariantMap>
+
+QPrivData(IRCNetworkEntity)
 {
 	public:
 		QString address;
@@ -34,7 +34,7 @@
 		QStringList autojoinCommands;
 		bool bAutojoinNetwork;
 		QString description;
-		PatternList ignoredUsers;
+		PatternList ignoredUsers;
 		QString nickservCommand;
 		QString nickservPassword;
 		QString password;
@@ -45,65 +45,63 @@
 
 IRCNetworkEntity::IRCNetworkEntity()
 {
-	d = new PrivData();
-	d->bAutojoinNetwork = false;
-	d->port = 6667;
-	d->nickservCommand = "/msg nickserv identify %1";
+	d->bAutojoinNetwork = false;
+	d->port = 6667;
+	d->nickservCommand = "/msg nickserv identify %1";
 }
 
 IRCNetworkEntity::~IRCNetworkEntity()
 {
-	delete d;
 }
 
-const QString &IRCNetworkEntity::address() const
-{
-	return d->address;
-}
+const QString &IRCNetworkEntity::address() const
+{
+	return d->address;
+}
 
-const QStringList &IRCNetworkEntity::autojoinChannels() const
-{
-	return d->autojoinChannels;
-}
+const QStringList &IRCNetworkEntity::autojoinChannels() const
+{
+	return d->autojoinChannels;
+}
 
 QStringList &IRCNetworkEntity::autojoinChannels()
 {
 	return d->autojoinChannels;
 }
 
-const QStringList &IRCNetworkEntity::autojoinCommands() const
-{
-	return d->autojoinCommands;
-}
+const QStringList &IRCNetworkEntity::autojoinCommands() const
+{
+	return d->autojoinCommands;
+}
 
 QStringList &IRCNetworkEntity::autojoinCommands()
 {
 	return d->autojoinCommands;
 }
 
-bool IRCNetworkEntity::isAutojoinNetwork() const
-{
-	return d->bAutojoinNetwork;;
+bool IRCNetworkEntity::isAutojoinNetwork() const
+{
+	return d->bAutojoinNetwork;;
 }
 
 bool IRCNetworkEntity::isValid() const
 {
 	return !address().isEmpty() && port() != 0;
-}
+}
 
-const QString &IRCNetworkEntity::description() const
-{
-	return d->description;
-}
+const QString &IRCNetworkEntity::description() const
+{
+	return d->description;
+}
 
-const QString &IRCNetworkEntity::nickservCommand() const
-{
-	return d->nickservCommand;
-}
+const QString &IRCNetworkEntity::nickservCommand() const
+{
+	return d->nickservCommand;
+}
 
-const QString &IRCNetworkEntity::nickservPassword() const
-{
-	return d->nickservPassword;
+const QString &IRCNetworkEntity::nickservPassword() const
+{
+	return d->nickservPassword;
 }
 
 bool IRCNetworkEntity::operator<(const IRCNetworkEntity& other) const
@@ -114,103 +112,103 @@
 bool IRCNetworkEntity::operator==(const IRCNetworkEntity& other) const
 {
 	return address() == other.address() && port() == other.port();
-}
+}
 
-const QString &IRCNetworkEntity::password() const
-{
-	return d->password;
-}
+const QString &IRCNetworkEntity::password() const
+{
+	return d->password;
+}
 
-unsigned short IRCNetworkEntity::port() const
-{
-	return d->port;
-}
+unsigned short IRCNetworkEntity::port() const
+{
+	return d->port;
+}
 
 
-void IRCNetworkEntity::setAddress(const QString &v)
-{
-	d->address = v;
-}
+void IRCNetworkEntity::setAddress(const QString &v)
+{
+	d->address = v;
+}
 
-void IRCNetworkEntity::setAutojoinChannels(const QStringList &v)
-{
-	d->autojoinChannels = v;
-}
+void IRCNetworkEntity::setAutojoinChannels(const QStringList &v)
+{
+	d->autojoinChannels = v;
+}
 
-void IRCNetworkEntity::setAutojoinCommands(const QStringList &v)
-{
-	d->autojoinCommands = v;
-}
+void IRCNetworkEntity::setAutojoinCommands(const QStringList &v)
+{
+	d->autojoinCommands = v;
+}
 
-void IRCNetworkEntity::setAutojoinNetwork(bool v)
-{
-	d->bAutojoinNetwork = v;
-}
+void IRCNetworkEntity::setAutojoinNetwork(bool v)
+{
+	d->bAutojoinNetwork = v;
+}
 
-void IRCNetworkEntity::setDescription(const QString &v)
-{
-	d->description = ChatNetworkNamer::convertToValidName(v);
-}
+void IRCNetworkEntity::setDescription(const QString &v)
+{
+	d->description = ChatNetworkNamer::convertToValidName(v);
+}
 
-void IRCNetworkEntity::setNickservCommand(const QString &v)
-{
-	d->nickservCommand = v;
-}
+void IRCNetworkEntity::setNickservCommand(const QString &v)
+{
+	d->nickservCommand = v;
+}
 
-void IRCNetworkEntity::setNickservPassword(const QString &v)
-{
-	d->nickservPassword = v;
-}
+void IRCNetworkEntity::setNickservPassword(const QString &v)
+{
+	d->nickservPassword = v;
+}
 
-void IRCNetworkEntity::setPassword(const QString &v)
-{
-	d->password = v;
-}
+void IRCNetworkEntity::setPassword(const QString &v)
+{
+	d->password = v;
+}
 
-void IRCNetworkEntity::setPort(unsigned short v)
-{
-	d->port = v;
-}
+void IRCNetworkEntity::setPort(unsigned short v)
+{
+	d->port = v;
+}
 
-const PatternList &IRCNetworkEntity::ignoredUsers() const
-{
-	return d->ignoredUsers;
-}
-
-void IRCNetworkEntity::setIgnoredUsers(const PatternList &val)
-{
-	d->ignoredUsers = val;
-}
-
-IRCNetworkEntity IRCNetworkEntity::deserializeQVariant(const QVariant &var)
-{
-	QVariantMap map = var.toMap();
-	IRCNetworkEntity result;
-	result.setAddress(map["address"].toString());
-	result.setAutojoinChannels(map["autoJoinChannels"].toStringList());
-	result.setAutojoinCommands(map["autoJoinCommands"].toStringList());
-	result.setAutojoinNetwork(map["autoJoinNetwork"].toBool());
-	result.setDescription(map["description"].toString());
-	result.setIgnoredUsers(PatternList::deserializeQVariant(map["ignoredUsers"]));
-	result.setNickservCommand(map["nickservCommand"].toString());
-	result.setNickservPassword(map["nickservPassword"].toString());
-	result.setPassword(map["password"].toString());
-	result.setPort(map["port"].toInt());
-	return result;
-}
+const PatternList &IRCNetworkEntity::ignoredUsers() const
+{
+	return d->ignoredUsers;
+}
 
-QVariant IRCNetworkEntity::serializeQVariant() const
-{
-	QVariantMap map;
-	map["address"] = address();
-	map["autoJoinChannels"] = autojoinChannels();
-	map["autoJoinCommands"] = autojoinCommands();
-	map["autoJoinNetwork"] = isAutojoinNetwork();
-	map["description"] = description();
-	map["ignoredUsers"] = ignoredUsers().serializeQVariant();
-	map["nickservCommand"] = nickservCommand();
-	map["nickservPassword"] = nickservPassword();
-	map["password"] = password();
-	map["port"] = port();
-	return map;
-}
+void IRCNetworkEntity::setIgnoredUsers(const PatternList &val)
+{
+	d->ignoredUsers = val;
+}
+
+IRCNetworkEntity IRCNetworkEntity::deserializeQVariant(const QVariant &var)
+{
+	QVariantMap map = var.toMap();
+	IRCNetworkEntity result;
+	result.setAddress(map["address"].toString());
+	result.setAutojoinChannels(map["autoJoinChannels"].toStringList());
+	result.setAutojoinCommands(map["autoJoinCommands"].toStringList());
+	result.setAutojoinNetwork(map["autoJoinNetwork"].toBool());
+	result.setDescription(map["description"].toString());
+	result.setIgnoredUsers(PatternList::deserializeQVariant(map["ignoredUsers"]));
+	result.setNickservCommand(map["nickservCommand"].toString());
+	result.setNickservPassword(map["nickservPassword"].toString());
+	result.setPassword(map["password"].toString());
+	result.setPort(map["port"].toInt());
+	return result;
+}
+
+QVariant IRCNetworkEntity::serializeQVariant() const
+{
+	QVariantMap map;
+	map["address"] = address();
+	map["autoJoinChannels"] = autojoinChannels();
+	map["autoJoinCommands"] = autojoinCommands();
+	map["autoJoinNetwork"] = isAutojoinNetwork();
+	map["description"] = description();
+	map["ignoredUsers"] = ignoredUsers().serializeQVariant();
+	map["nickservCommand"] = nickservCommand();
+	map["nickservPassword"] = nickservPassword();
+	map["password"] = password();
+	map["port"] = port();
+	return map;
+}
diff -r df8130a4a03b src/core/irc/entities/ircnetworkentity.h
--- a/src/core/irc/entities/ircnetworkentity.h	Fri Feb 06 20:58:23 2015 +0100
+++ b/src/core/irc/entities/ircnetworkentity.h	Mon Feb 09 16:19:21 2015 -0500
@@ -120,8 +120,7 @@
 		void setPort(unsigned short v);
 
 	private:
-		class PrivData;
-		PrivData *d;
+		Pimpl<IRCNetworkEntity> d;
 };
 
 #endif
diff -r df8130a4a03b src/core/joincommandlinebuilder.cpp
--- a/src/core/joincommandlinebuilder.cpp	Fri Feb 06 20:58:23 2015 +0100
+++ b/src/core/joincommandlinebuilder.cpp	Mon Feb 09 16:19:21 2015 -0500
@@ -42,7 +42,7 @@
 #include <QMessageBox>
 #include <cassert>
 
-class JoinCommandLineBuilder::PrivData
+QPrivData(JoinCommandLineBuilder)
 {
 	public:
 		CommandLineInfo cli;
@@ -60,7 +60,6 @@
 JoinCommandLineBuilder::JoinCommandLineBuilder(ServerPtr server,
 	GameDemo demo, QWidget *parentWidget)
 {
-	d = new PrivData();
 	d->configurationError = false;
 	d->demo = demo;
 	d->demoName = GameDemo::mkDemoFullPath(demo, *server->plugin());
@@ -71,7 +70,6 @@
 
 JoinCommandLineBuilder::~JoinCommandLineBuilder()
 {
-	delete d;
 }
 
 QStringList JoinCommandLineBuilder::allDownloadableWads(const JoinError &joinError)
diff -r df8130a4a03b src/core/joincommandlinebuilder.h
--- a/src/core/joincommandlinebuilder.h	Fri Feb 06 20:58:23 2015 +0100
+++ b/src/core/joincommandlinebuilder.h	Mon Feb 09 16:19:21 2015 -0500
@@ -20,14 +20,15 @@
 //------------------------------------------------------------------------------
 // Copyright (C) 2014 "Zalewa" <zalewapl@gmail.com>
 //------------------------------------------------------------------------------
-#ifndef id3D55B51B_0F01_4FAB_8D44E1593B00E437
-#define id3D55B51B_0F01_4FAB_8D44E1593B00E437
+#ifndef id3D55B51B_0F01_4FAB_8D44E1593B00E437
+#define id3D55B51B_0F01_4FAB_8D44E1593B00E437
 
 #include "serverapi/serverptr.h"
+#include "dpointer.h"
 #include <QObject>
 
 class CommandLineInfo;
-class GameDemo;
+class GameDemo;
 class JoinError;
 class Server;
 class ServerConnectParams;
@@ -45,44 +46,43 @@
 		JoinCommandLineBuilder(ServerPtr server, GameDemo demo, QWidget *parentWidget);
 		~JoinCommandLineBuilder();
 
-		const CommandLineInfo &builtCommandLine() const;
+		const CommandLineInfo &builtCommandLine() const;
 		static bool checkWadseekerValidity(QWidget *parent=NULL);
 		bool isConfigurationError() const;
 		const QString &error() const;
-		/**
-		 * @brief Runs asynchronously and emits
-		 * commandLineBuildFinished() when done.
-		 */
+		/**
+		 * @brief Runs asynchronously and emits
+		 * commandLineBuildFinished() when done.
+		 */
 		void obtainJoinCommandLine();
-		ServerPtr server() const;
+		ServerPtr server() const;
 
-	signals:
-		void commandLineBuildFinished();
-
+	signals:
+		void commandLineBuildFinished();
+
 	private:
 		enum MissingWadsProceed
 		{
 			Ignore,
 			Cancel,
-			Seeking
+			Seeking
 		};
 
-		class PrivData;
-		PrivData *d;
+		Pimpl<JoinCommandLineBuilder> d;
 
 		QStringList allDownloadableWads(const JoinError &joinError);
 		bool buildServerConnectParams(ServerConnectParams &params);
 		bool checkServerStatus();
 		int displayMissingWadsMessage(const QStringList &downloadableWads, const QString &message);
-		void failBuild();
+		void failBuild();
 		void handleError(const JoinError &error);
 		MissingWadsProceed handleMissingWads(const JoinError &error);
 		QString mkDemoName();
 		bool tryToInstallGame();
-
-	private slots:
-		void onWadseekerDone(int result);
-};
-
-#endif
 
+	private slots:
+		void onWadseekerDone(int result);
+};
+
+#endif
+
diff -r df8130a4a03b src/core/log.cpp
--- a/src/core/log.cpp	Fri Feb 06 20:58:23 2015 +0100
+++ b/src/core/log.cpp	Mon Feb 09 16:19:21 2015 -0500
@@ -26,7 +26,7 @@
 #include <QMutexLocker>
 #include <cstdio>
 
-class Log::PrivData
+QPrivData(Log)
 {
 	public:
 		QString logContent;
@@ -39,14 +39,12 @@
 
 Log::Log()
 {
-	d = new PrivData();
 	d->timestamps = true;
 	d->printToStdout = true;
 }
 
 Log::~Log()
 {
-	delete d;
 }
 
 void Log::addEntry(const QString& string)
diff -r df8130a4a03b src/core/log.h
--- a/src/core/log.h	Fri Feb 06 20:58:23 2015 +0100
+++ b/src/core/log.h	Mon Feb 09 16:19:21 2015 -0500
@@ -29,7 +29,7 @@
 #include <QMutex>
 #include <QObject>
 
-/**
+/**
  * @ingroup group_pluginapi
  * @brief Log manager.
  */
@@ -102,8 +102,8 @@
 		void newEntry(const QString& entry);
 
 	private:
-		class PrivData;
-		PrivData *d;
-
};
+		Pimpl<Log> d;
+
+};
 
 #endif
diff -r df8130a4a03b src/core/lookuphost.cpp
--- a/src/core/lookuphost.cpp	Fri Feb 06 20:58:23 2015 +0100
+++ b/src/core/lookuphost.cpp	Mon Feb 09 16:19:21 2015 -0500
@@ -30,7 +30,7 @@
 
 LookupHost *LookupHost::inst = NULL;
 
-class LookupHost::PrivData
+QPrivData(LookupHost)
 {
 public:
 	/**
@@ -48,14 +48,12 @@
 
 LookupHost::LookupHost()
 {
-	d = new PrivData();
 	d->accepting = true;
 	d->runningLookups = 0;
 }
 
 LookupHost::~LookupHost()
 {
-	delete d;
 }
 
 void LookupHost::lookupHost(const QString &name, QObject *receiver, const char *receiverSlot)
@@ -133,7 +131,7 @@
 	QMutexLocker locker(&LookupHost::instance()->d->lock);
 	if (LookupHost::instance()->d->accepting)
 	{
-		if (LookupHost::instance()->d->runningLookups < LookupHost::PrivData::MAX_LOOKUPS)
+		if (LookupHost::instance()->d->runningLookups < PrivData<LookupHost>::MAX_LOOKUPS)
 		{
 			++LookupHost::instance()->d->runningLookups;
 			QHostInfo::lookupHost(hostName, this, SLOT(hostFoundReceived(QHostInfo)));
diff -r df8130a4a03b src/core/lookuphost.h
--- a/src/core/lookuphost.h	Fri Feb 06 20:58:23 2015 +0100
+++ b/src/core/lookuphost.h	Mon Feb 09 16:19:21 2015 -0500
@@ -23,6 +23,8 @@
 #ifndef id98fdc6b8_d51c_4a3b_a61e_91ddc4105daf
 #define id98fdc6b8_d51c_4a3b_a61e_91ddc4105daf
 
+#include "dpointer.h"
+
 #include <QObject>
 #include <QString>
 #include <QThread>
@@ -68,8 +70,7 @@
 	static void lookupHost(const QString &name, QObject *receiver, const char *receiverSlot);
 
 private:
-	class PrivData;
-	PrivData *d;
+	Pimpl<LookupHost> d;
 
 	static LookupHost *instance();
 	static LookupHost *inst;
diff -r df8130a4a03b src/core/pathfinder/pathfinder.cpp
--- a/src/core/pathfinder/pathfinder.cpp	Fri Feb 06 20:58:23 2015 +0100
+++ b/src/core/pathfinder/pathfinder.cpp	Mon Feb 09 16:19:21 2015 -0500
@@ -32,7 +32,7 @@
 #include <QFileInfo>
 #include <cstdlib>
 
-class PathFinderResult::PrivData
+QPrivData(PathFinderResult)
 {
 	public:
 		QStringList foundFiles;
@@ -45,12 +45,10 @@
 
 PathFinderResult::PathFinderResult()
 {
-	d = new PrivData();
 }
 
 PathFinderResult::~PathFinderResult()
 {
-	delete d;
 }
 
 QStringList& PathFinderResult::foundFiles()
@@ -75,7 +73,7 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
-class PathFinder::PrivData
+QPrivData(PathFinder)
 {
 	public:
 		QList<FileSearchPath> searchPaths;
@@ -87,14 +85,12 @@
 
 PathFinder::PathFinder()
 {
-	d = new PrivData();
 	d->searchPaths = gConfig.doomseeker.wadPaths;
 	d->searchPaths << gConfig.wadseeker.targetDirectory;
 }
 
 PathFinder::PathFinder(const QStringList& paths)
 {
-	d = new PrivData();
 	foreach (const QString& path, paths)
 	{
 		d->searchPaths << path;
@@ -103,7 +99,6 @@
 
 PathFinder::~PathFinder()
 {
-	delete d;
 }
 
 void PathFinder::addPrioritySearchDir(const QString& dir)
diff -r df8130a4a03b src/core/pathfinder/pathfinder.h
--- a/src/core/pathfinder/pathfinder.h	Fri Feb 06 20:58:23 2015 +0100
+++ b/src/core/pathfinder/pathfinder.h	Mon Feb 09 16:19:21 2015 -0500
@@ -57,8 +57,7 @@
 		const QStringList& missingFiles() const;
 
 	private:
-		class PrivData;
-		PrivData *d;
+		Pimpl<PathFinderResult> d;
 };
 
 /**
@@ -116,8 +115,7 @@
 		PathFinderResult findFiles(const QStringList& files) const;
 
 	private:
-		class PrivData;
-		PrivData *d;
+		Pimpl<PathFinder> d;
 };
 
 #endif
diff -r df8130a4a03b src/core/pathfinder/wadpathfinder.cpp
--- a/src/core/pathfinder/wadpathfinder.cpp	Fri Feb 06 20:58:23 2015 +0100
+++ b/src/core/pathfinder/wadpathfinder.cpp	Mon Feb 09 16:19:21 2015 -0500
@@ -26,7 +26,7 @@
 #include "pathfinder/filealias.h"
 #include "pathfinder/pathfinder.h"
 
-class WadFindResult::PrivData
+QPrivData(WadFindResult)
 {
 	public:
 		QString alias;
@@ -37,12 +37,10 @@
 
 WadFindResult::WadFindResult()
 {
-	d = new PrivData();
 }
 
 WadFindResult::~WadFindResult()
 {
-	delete d;
 }
 
 const QString &WadFindResult::alias() const
@@ -75,7 +73,7 @@
 	d->path = val;
 }
 ///////////////////////////////////////////////////////////////////////////////
-class WadPathFinder::PrivData
+QPrivData(WadPathFinder)
 {
 	public:
 		QList<FileAlias> aliases;
@@ -84,14 +82,12 @@
 
 WadPathFinder::WadPathFinder(const PathFinder &pathFinder)
 {
-	d = new PrivData();
 	d->aliases = gConfig.doomseeker.wadAliases();
 	d->pathFinder = pathFinder;
 }
 
 WadPathFinder::~WadPathFinder()
 {
-	delete d;
 }
 
 QStringList WadPathFinder::aliases(const QString &name) const
diff -r df8130a4a03b src/core/pathfinder/wadpathfinder.h
--- a/src/core/pathfinder/wadpathfinder.h	Fri Feb 06 20:58:23 2015 +0100
+++ b/src/core/pathfinder/wadpathfinder.h	Mon Feb 09 16:19:21 2015 -0500
@@ -20,8 +20,8 @@
 //------------------------------------------------------------------------------
 // Copyright (C) 2014 "Zalewa" <zalewapl@gmail.com>
 //------------------------------------------------------------------------------
-#ifndef idCA954A5A_EF00_4F51_9C9782634F191143
-#define idCA954A5A_EF00_4F51_9C9782634F191143
+#ifndef idCA954A5A_EF00_4F51_9C9782634F191143
+#define idCA954A5A_EF00_4F51_9C9782634F191143
 
 #include "dpointer.h"
 #include <QString>
@@ -46,8 +46,7 @@
 		void setPath(const QString &val);
 
 	private:
-		class PrivData;
-		PrivData *d;
+		Pimpl<WadFindResult> d;
 };
 
 /**
@@ -62,10 +61,9 @@
 		WadFindResult find(const QString &name);
 
 	private:
-		class PrivData;
-		PrivData *d;
+		Pimpl<WadPathFinder> d;
 
 		QStringList aliases(const QString &name) const;
-};
-
-#endif
+};
+
+#endif
diff -r df8130a4a03b src/core/scanner.cpp
--- a/src/core/scanner.cpp	Fri Feb 06 20:58:23 2015 +0100
+++ b/src/core/scanner.cpp	Mon Feb 09 16:19:21 2015 -0500
@@ -27,10 +27,10 @@
 
 #include "scanner.h"
 
-class Scanner::PrivData
+QPrivData(Scanner)
 {
 	public:
-		ParserState		nextState, prevState, state;
+		Scanner::ParserState nextState, prevState, state;
 
 		char*			data;
 		unsigned int	length;
@@ -84,7 +84,6 @@
 
 Scanner::Scanner(const char* data, int length)
 {
-	d = new PrivData();
 	d->line = 1;
 	d->lineStart = 0;
 	d->logicalPosition = 0;
@@ -104,7 +103,6 @@
 Scanner::~Scanner()
 {
 	delete[] d->data;
-	delete d;
 }
 
 // Here's my answer to the preprocessor screwing up line numbers. What we do is
@@ -771,7 +769,7 @@
 	return str;
 }
 ////////////////////////////////////////////////////////////////////////////////
-class Scanner::ParserState::PrivData
+QPrivData(Scanner::ParserState)
 {
 	public:
 		QString str;
@@ -788,12 +786,10 @@
 
 Scanner::ParserState::ParserState()
 {
-	d = new PrivData();
 }
 
 Scanner::ParserState::~ParserState()
 {
-	delete d;
 }
 
 const QString &Scanner::ParserState::str() const
diff -r df8130a4a03b src/core/scanner.h
--- a/src/core/scanner.h	Fri Feb 06 20:58:23 2015 +0100
+++ b/src/core/scanner.h	Mon Feb 09 16:19:21 2015 -0500
@@ -73,6 +73,9 @@
  */
 class MAIN_EXPORT Scanner
 {
+	private:
+		Scanner(const Scanner &other);
+
 	public:
 		class ParserState
 		{
@@ -106,8 +109,7 @@
 				void setScanPos(unsigned int v);
 
 			private:
-				class PrivData;
-				PrivData *d;
+				Pimpl<ParserState> d;
 		};
 
 		enum MessageLevel
@@ -176,8 +178,7 @@
 		void incrementLine();
 
 	private:
-		class PrivData;
-		PrivData *d;
+		Pimpl<Scanner> d;
 
 		static void (*messageHandler)(MessageLevel, const char*, va_list);
 };
diff -r df8130a4a03b src/core/serverapi/gamecreateparams.cpp
--- a/src/core/serverapi/gamecreateparams.cpp	Fri Feb 06 20:58:23 2015 +0100
+++ b/src/core/serverapi/gamecreateparams.cpp	Mon Feb 09 16:19:21 2015 -0500
@@ -26,7 +26,7 @@
 #include "gamedemo.h"
 #include <QFileInfo>
 
-class GameCreateParams::PrivData
+QPrivData(GameCreateParams)
 {
 	public:
 		bool broadcastToLan;
@@ -63,7 +63,6 @@
 
 GameCreateParams::GameCreateParams()
 {
-	d = new PrivData();
 	d->broadcastToLan = true;
 	d->broadcastToMaster = true;
 	d->randomMapRotation = false;
@@ -75,7 +74,6 @@
 
 GameCreateParams::~GameCreateParams()
 {
-	delete d;
 }
 
 const QString& GameCreateParams::connectPassword() const
diff -r df8130a4a03b src/core/serverapi/gamecreateparams.h
--- a/src/core/serverapi/gamecreateparams.h	Fri Feb 06 20:58:23 2015 +0100
+++ b/src/core/serverapi/gamecreateparams.h	Mon Feb 09 16:19:21 2015 -0500
@@ -20,8 +20,8 @@
 //------------------------------------------------------------------------------
 // Copyright (C) 2014 "Zalewa" <zalewapl@gmail.com>
 //------------------------------------------------------------------------------
-#ifndef idF7CFB784_3591_4B2C_B5529AE7FBCC2568
-#define idF7CFB784_3591_4B2C_B5529AE7FBCC2568
+#ifndef idF7CFB784_3591_4B2C_B5529AE7FBCC2568
+#define idF7CFB784_3591_4B2C_B5529AE7FBCC2568
 
 #include "global.h"
 #include <QList>
@@ -30,13 +30,13 @@
 
 class DMFlagsSection;
 class GameCVar;
-class GameDemo;
+class GameDemo;
 class GameMode;
 
-/**
+/**
  * @ingroup group_pluginapi
  * @brief Game parametrization data used when creating new games.
- */
+ */
 class MAIN_EXPORT GameCreateParams
 {
 	public:
@@ -67,32 +67,32 @@
 
 		/**
 		 * @brief Use if running in HostMode::Demo mode or recording a demo.
-		 *
-		 * Used either as a path to already existing demo that should
-		 * be played back, or as a path to a new demo that should be
-		 * recorded.
-		 *
-		 * When hostMode() is HostMode::Demo then this points to a
-		 * demo for playback.
-		 *
-		 * When hostMode() is HostMode::Offline and demoRecord() is
-		 * not GameDemo::NoDemo then this points to a new demo to
-		 * record.
-		 *
-		 * @see hostMode()
-		 * @see demoRecord()
+		 *
+		 * Used either as a path to already existing demo that should
+		 * be played back, or as a path to a new demo that should be
+		 * recorded.
+		 *
+		 * When hostMode() is HostMode::Demo then this points to a
+		 * demo for playback.
+		 *
+		 * When hostMode() is HostMode::Offline and demoRecord() is
+		 * not GameDemo::NoDemo then this points to a new demo to
+		 * record.
+		 *
+		 * @see hostMode()
+		 * @see demoRecord()
 		 */
 		const QString& demoPath() const;
-		/**
-		 * @brief Type of demo to record; applicable only in Offline game.
-		 *
-		 * If set to record a demo, then demoPath() must also be set.
-		 * Default is GameDemo::NoDemo.
-		 */
-		const GameDemo &demoRecord() const;
-		void setDemoRecord(const GameDemo &demo);
-
-
+		/**
+		 * @brief Type of demo to record; applicable only in Offline game.
+		 *
+		 * If set to record a demo, then demoPath() must also be set.
+		 * Default is GameDemo::NoDemo.
+		 */
+		const GameDemo &demoRecord() const;
+		void setDemoRecord(const GameDemo &demo);
+
+
 		QList<DMFlagsSection>& dmFlags();
 		const QList<DMFlagsSection>& dmFlags() const;
 		const QString& email() const;
@@ -106,17 +106,17 @@
 		bool isBroadcastToLan() const;
 		bool isBroadcastToMaster() const;
 		bool isRandomMapRotation() const;
-
+
 		/**
 		 * @brief Internal game password.
 		 */
 		const QString& ingamePassword() const;
 		const QString& iwadPath() const;
-
-		/**
-		 * @brief Name of IWAD, derived from iwadPath().
-		 */
-		QString iwadName() const;
+
+		/**
+		 * @brief Name of IWAD, derived from iwadPath().
+		 */
+		QString iwadName() const;
 
 		/**
 		 * @brief Level name as in E1M1 or MAP01.
@@ -141,11 +141,12 @@
 		unsigned short port() const;
 		QStringList& pwadsPaths();
 		const QStringList& pwadsPaths() const;
-
		/**
-		 * @brief Names of PWADs, derived from pwadsPaths().
-		 */
-		QStringList pwadsNames() const;
-
+
+		/**
+		 * @brief Names of PWADs, derived from pwadsPaths().
+		 */
+		QStringList pwadsNames() const;
+
 		/**
 		 * @brief Password required to connect to remote admin console.
 		 */
@@ -186,8 +187,7 @@
 		const QString& url() const;
 
 	private:
-		class PrivData;
-		PrivData* d;
-};
-
-#endif // header
+		Pimpl<GameCreateParams> d;
+};
+
+#endif // header
diff -r df8130a4a03b src/core/serverapi/serverstructs.cpp
--- a/src/core/serverapi/serverstructs.cpp	Fri Feb 06 20:58:23 2015 +0100
+++ b/src/core/serverapi/serverstructs.cpp	Mon Feb 09 16:19:21 2015 -0500
@@ -24,7 +24,7 @@
 
 #include <QVector>
 
-class DMFlag::PrivData
+QPrivData(DMFlag)
 {
 	public:
 		QString name;
@@ -33,13 +33,11 @@
 
 DMFlag::DMFlag()
 {
-	d = new PrivData();
 	d->value = 0;
 }
 
 DMFlag::DMFlag(QString name, unsigned value)
 {
-	d = new PrivData();
 	d->name = name;
 	d->value = value;
 }
@@ -48,7 +46,6 @@
 
 DMFlag::~DMFlag()
 {
-	delete d;
 }
 
 bool DMFlag::isValid() const
@@ -68,7 +65,7 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
-class DMFlagsSection::PrivData
+QPrivData(DMFlagsSection)
 {
 	public:
 		QString name;
@@ -79,18 +76,15 @@
 
 DMFlagsSection::DMFlagsSection()
 {
-	d = new PrivData();
 }
 
 DMFlagsSection::DMFlagsSection(const QString& name)
 {
-	d = new PrivData();
 	d->name = name;
 }
 
 DMFlagsSection::~DMFlagsSection()
 {
-	delete d;
 }
 
 void DMFlagsSection::add(const DMFlag& flag)
@@ -135,7 +129,7 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
-class GameCVar::PrivData
+QPrivData(GameCVar)
 {
 	public:
 		QString command;
@@ -147,19 +141,16 @@
 
 GameCVar::GameCVar()
 {
-	d = new PrivData();
 }
 
 GameCVar::GameCVar(const QString &name, const QString &command)
 {
-	d = new PrivData();
 	d->name = name;
 	d->command = command;
 }
 
 GameCVar::~GameCVar()
 {
-	delete d;
 }
 
 const QString &GameCVar::command() const
@@ -194,7 +185,7 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
-class GameMode::PrivData
+QPrivData(GameMode)
 {
 	public:
 		int index;
@@ -206,14 +197,12 @@
 
 GameMode::GameMode()
 {
-	d = new PrivData();
 	d->index = -1;
 	d->teamgame = false;
 }
 
 GameMode::GameMode(int index, const QString &name)
 {
-	d = new PrivData();
 	d->index = index;
 	d->name = name;
 	d->teamgame = false;
@@ -221,7 +210,6 @@
 
 GameMode::~GameMode()
 {
-	delete d;
 }
 
 GameMode GameMode::ffaGame(int index, const QString &name)
@@ -290,7 +278,7 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
-class PWad::PrivData
+QPrivData(PWad)
 {
 	public:
 		QString name;
@@ -301,14 +289,12 @@
 
 PWad::PWad(const QString &name, bool optional)
 {
-	d = new PrivData();
 	d->name = name;
 	d->optional = optional;
 }
 
 PWad::~PWad()
 {
-	delete d;
 }
 
 bool PWad::isOptional() const
diff -r df8130a4a03b src/core/serverapi/serverstructs.h
--- a/src/core/serverapi/serverstructs.h	Fri Feb 06 20:58:23 2015 +0100
+++ b/src/core/serverapi/serverstructs.h	Mon Feb 09 16:19:21 2015 -0500
@@ -73,8 +73,7 @@
 		unsigned value() const;
 
 	private:
-		class PrivData;
-		PrivData* d;
+		Pimpl<DMFlag> d;
 };
 
 /**
@@ -134,8 +133,7 @@
 		}
 
 	private:
-		class PrivData;
-		PrivData* d;
+		Pimpl<DMFlagsSection> d;
 };
 
 /**
@@ -190,8 +188,7 @@
 		int valueInt() const { return value().toInt(); }
 
 	private:
-		class PrivData;
-		PrivData* d;
+		Pimpl<GameCVar> d;
 };
 
 /**
@@ -300,8 +297,7 @@
 		bool isValid() const;
 
 	private:
-		class PrivData;
-		PrivData *d;
+		Pimpl<GameMode> d;
 
 		GameMode(int index, const QString &name);
 
@@ -333,8 +329,7 @@
 		const QString& name() const;
 
 	private:
-		class PrivData;
-		PrivData* d;
+		Pimpl<PWad> d;
 };
 
 #endif
diff -r df8130a4a03b src/core/urlopener.cpp
--- a/src/core/urlopener.cpp	Fri Feb 06 20:58:23 2015 +0100
+++ b/src/core/urlopener.cpp	Mon Feb 09 16:19:21 2015 -0500
@@ -26,7 +26,7 @@
 #include <QQueue>
 #include <QTimer>
 
-class UrlOpener::PrivData
+QPrivData(UrlOpener)
 {
 public:
 	QQueue<QUrl> queue;
@@ -36,7 +36,10 @@
 
 UrlOpener::UrlOpener()
 {
-	d = new PrivData();
+}
+
+UrlOpener::~UrlOpener()
+{
 }
 
 void UrlOpener::doOpen()
diff -r df8130a4a03b src/core/urlopener.h
--- a/src/core/urlopener.h	Fri Feb 06 20:58:23 2015 +0100
+++ b/src/core/urlopener.h	Mon Feb 09 16:19:21 2015 -0500
@@ -23,6 +23,8 @@
 #ifndef idAF497E8F_22A5_4630_ACB761050B5AF2BF
 #define idAF497E8F_22A5_4630_ACB761050B5AF2BF
 
+#include "dpointer.h"
+
 #include <QUrl>
 #include <QObject>
 
@@ -36,10 +38,10 @@
 	void open(const QUrl &url);
 
 private:
-	class PrivData;
-	PrivData *d;
+	Pimpl<UrlOpener> d;
 
 	UrlOpener();
+	~UrlOpener();
 
 	static UrlOpener *inst;
 
