changeset 76:858621081b95

Happy new year!
author David Demelier <markand@malikania.fr>
date Sun, 01 Jan 2017 13:35:37 +0100
parents 88d996df3eba
children 61ea80e925ab
files CMakeLists.txt client/CMakeLists.txt client/main.cpp cmake/MalikaniaOptions.cmake cmake/MalikaniaSystem.cmake cmake/MalikaniaVersion.cmake cmake/function/MalikaniaBuildAssets.cmake cmake/function/MalikaniaDefineExecutable.cmake cmake/function/MalikaniaDefineLibrary.cmake cmake/function/MalikaniaDefineTest.cmake cmake/function/MalikaniaSetg.cmake cmake/function/MalikaniaVeraCheck.cmake cmake/internal/sysconfig.hpp.in database/sqlite/CMakeLists.txt database/sqlite/script/init.sql database/sqlite/src/account.cpp docs/CMakeLists.txt extern/CMakeLists.txt extern/duktape/CMakeLists.txt extern/json/CMakeLists.txt libclient-js/CMakeLists.txt libclient-js/malikania/js_animation.cpp libclient-js/malikania/js_animation.hpp libclient-js/malikania/js_animator.cpp libclient-js/malikania/js_animator.hpp libclient-js/malikania/js_client_resources_loader.cpp libclient-js/malikania/js_client_resources_loader.hpp libclient-js/malikania/js_color.cpp libclient-js/malikania/js_color.hpp libclient-js/malikania/js_font.cpp libclient-js/malikania/js_font.hpp libclient-js/malikania/js_image.cpp libclient-js/malikania/js_image.hpp libclient-js/malikania/js_line.cpp libclient-js/malikania/js_line.hpp libclient-js/malikania/js_point.cpp libclient-js/malikania/js_point.hpp libclient-js/malikania/js_rectangle.cpp libclient-js/malikania/js_rectangle.hpp libclient-js/malikania/js_size.cpp libclient-js/malikania/js_size.hpp libclient-js/malikania/js_sprite.cpp libclient-js/malikania/js_sprite.hpp libclient-js/malikania/js_window.cpp libclient-js/malikania/js_window.hpp libclient/CMakeLists.txt libclient/malikania/animation.hpp libclient/malikania/animator.cpp libclient/malikania/animator.hpp libclient/malikania/backend/sdl/font_backend.cpp libclient/malikania/backend/sdl/font_backend.hpp libclient/malikania/backend/sdl/image_backend.cpp libclient/malikania/backend/sdl/image_backend.hpp libclient/malikania/backend/sdl/window_backend.cpp libclient/malikania/backend/sdl/window_backend.hpp libclient/malikania/button.cpp libclient/malikania/button.hpp libclient/malikania/client_resources_loader.cpp libclient/malikania/client_resources_loader.hpp libclient/malikania/color.cpp libclient/malikania/color.hpp libclient/malikania/font.cpp libclient/malikania/font.hpp libclient/malikania/frame.cpp libclient/malikania/frame.hpp libclient/malikania/image.cpp libclient/malikania/image.hpp libclient/malikania/key.hpp libclient/malikania/label.cpp libclient/malikania/label.hpp libclient/malikania/layout.hpp libclient/malikania/line.hpp libclient/malikania/mouse.hpp libclient/malikania/point.hpp libclient/malikania/rectangle.hpp libclient/malikania/size.hpp libclient/malikania/sprite.cpp libclient/malikania/sprite.hpp libclient/malikania/theme.cpp libclient/malikania/theme.hpp libclient/malikania/unique_layout.cpp libclient/malikania/unique_layout.hpp libclient/malikania/widget.cpp libclient/malikania/widget.hpp libclient/malikania/window.cpp libclient/malikania/window.hpp libcommon-js/CMakeLists.txt libcommon-js/malikania/duktape.hpp libcommon-js/malikania/js_elapsed_timer.cpp libcommon-js/malikania/js_elapsed_timer.hpp libcommon-js/malikania/js_resources_loader.cpp libcommon-js/malikania/js_resources_loader.hpp libcommon/CMakeLists.txt libcommon/malikania/backend/sdl/sdl_util.cpp libcommon/malikania/backend/sdl/sdl_util.hpp libcommon/malikania/game.hpp libcommon/malikania/id.hpp libcommon/malikania/net.hpp libcommon/malikania/resources_loader.cpp libcommon/malikania/resources_loader.hpp libcommon/malikania/resources_locator.cpp libcommon/malikania/resources_locator.hpp libcommon/malikania/util.cpp libcommon/malikania/util.hpp libserver/CMakeLists.txt libserver/malikania/account.hpp libserver/malikania/account_dao.cpp libserver/malikania/account_dao.hpp libserver/malikania/database.cpp libserver/malikania/database.hpp libserver/malikania/server.cpp libserver/malikania/server.hpp server/CMakeLists.txt server/main.cpp tests/CMakeLists.txt tests/libclient/CMakeLists.txt tests/libclient/color/CMakeLists.txt tests/libclient/color/main.cpp tests/libclient/js-color/CMakeLists.txt tests/libclient/js-color/main.cpp tests/libclient/js-line/CMakeLists.txt tests/libclient/js-line/main.cpp tests/libclient/js-point/CMakeLists.txt tests/libclient/js-point/main.cpp tests/libclient/js-rectangle/CMakeLists.txt tests/libclient/js-rectangle/main.cpp tests/libclient/js-size/CMakeLists.txt tests/libclient/js-size/main.cpp tests/libclient/line/CMakeLists.txt tests/libclient/line/main.cpp tests/libclient/point/CMakeLists.txt tests/libclient/point/main.cpp tests/libclient/rectangle/CMakeLists.txt tests/libclient/rectangle/main.cpp tests/libclient/size/CMakeLists.txt tests/libclient/size/main.cpp tests/libcommon/CMakeLists.txt tests/libcommon/js-elapsed-timer/CMakeLists.txt tests/libcommon/js-elapsed-timer/main.cpp tests/libcommon/util/CMakeLists.txt tests/libcommon/util/main.cpp tests/libserver/CMakeLists.txt tests/libserver/id/CMakeLists.txt tests/libserver/id/main.cpp tools/CMakeLists.txt tools/bcc/CMakeLists.txt tools/bcc/main.cpp
diffstat 147 files changed, 201 insertions(+), 3901 deletions(-) [+]
line wrap: on
line diff
--- a/CMakeLists.txt	Thu Dec 29 11:34:40 2016 +0100
+++ b/CMakeLists.txt	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/client/CMakeLists.txt	Thu Dec 29 11:34:40 2016 +0100
+++ b/client/CMakeLists.txt	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/client/main.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/client/main.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * main.cpp -- main client file
  *
- * Copyright (c) 2013-2016 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/cmake/MalikaniaOptions.cmake	Thu Dec 29 11:34:40 2016 +0100
+++ b/cmake/MalikaniaOptions.cmake	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/cmake/MalikaniaSystem.cmake	Thu Dec 29 11:34:40 2016 +0100
+++ b/cmake/MalikaniaSystem.cmake	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/cmake/MalikaniaVersion.cmake	Thu Dec 29 11:34:40 2016 +0100
+++ b/cmake/MalikaniaVersion.cmake	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/cmake/function/MalikaniaBuildAssets.cmake	Thu Dec 29 11:34:40 2016 +0100
+++ b/cmake/function/MalikaniaBuildAssets.cmake	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 #
 # MalikaniaBuildAssets.cmake -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/cmake/function/MalikaniaDefineExecutable.cmake	Thu Dec 29 11:34:40 2016 +0100
+++ b/cmake/function/MalikaniaDefineExecutable.cmake	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 #
 # MalikaniaDefineExecutable.cmake -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/cmake/function/MalikaniaDefineLibrary.cmake	Thu Dec 29 11:34:40 2016 +0100
+++ b/cmake/function/MalikaniaDefineLibrary.cmake	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 #
 # MalikaniaDefineLibrary.cmake -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/cmake/function/MalikaniaDefineTest.cmake	Thu Dec 29 11:34:40 2016 +0100
+++ b/cmake/function/MalikaniaDefineTest.cmake	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 #
 # MalikaniaDefineTest.cmake -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/cmake/function/MalikaniaSetg.cmake	Thu Dec 29 11:34:40 2016 +0100
+++ b/cmake/function/MalikaniaSetg.cmake	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 #
 # MalikaniaSetg.cmake -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/cmake/function/MalikaniaVeraCheck.cmake	Thu Dec 29 11:34:40 2016 +0100
+++ b/cmake/function/MalikaniaVeraCheck.cmake	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 #
 # MalikaniaVeraCheck.cmake -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/cmake/internal/sysconfig.hpp.in	Thu Dec 29 11:34:40 2016 +0100
+++ b/cmake/internal/sysconfig.hpp.in	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * sysconfig.hpp -- autogenerated configuration file
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/database/sqlite/CMakeLists.txt	Thu Dec 29 11:34:40 2016 +0100
+++ b/database/sqlite/CMakeLists.txt	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- CMake build system for sqlite
 #
-# Copyright (c) 2016 David Demelier <markand@malikania.fr>
+# Copyright (c) 2016-2017 David Demelier <markand@malikania.fr>
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/database/sqlite/script/init.sql	Thu Dec 29 11:34:40 2016 +0100
+++ b/database/sqlite/script/init.sql	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 --
 -- init.sql -- initialize sqlite database
 --
--- Copyright (c) 2013-2016 Malikania Authors
+-- Copyright (c) 2013-2017 Malikania Authors
 --
 -- Permission to use, copy, modify, and/or distribute this software for any
 -- purpose with or without fee is hereby granted, provided that the above
--- a/database/sqlite/src/account.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/database/sqlite/src/account.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * account.cpp -- account management
  *
- * Copyright (c) 2013-2016 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/docs/CMakeLists.txt	Thu Dec 29 11:34:40 2016 +0100
+++ b/docs/CMakeLists.txt	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/extern/CMakeLists.txt	Thu Dec 29 11:34:40 2016 +0100
+++ b/extern/CMakeLists.txt	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/extern/duktape/CMakeLists.txt	Thu Dec 29 11:34:40 2016 +0100
+++ b/extern/duktape/CMakeLists.txt	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- CMake build system for duktape
 #
-# Copyright (c) 2016 David Demelier <markand@malikania.fr>
+# Copyright (c) 2016-2017 David Demelier <markand@malikania.fr>
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/extern/json/CMakeLists.txt	Thu Dec 29 11:34:40 2016 +0100
+++ b/extern/json/CMakeLists.txt	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- CMake build system for nlohmann's json
 #
-# Copyright (c) 2016 David Demelier <markand@malikania.fr>
+# Copyright (c) 2016-2017 David Demelier <markand@malikania.fr>
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/libclient-js/CMakeLists.txt	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient-js/CMakeLists.txt	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/libclient-js/malikania/js_animation.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient-js/malikania/js_animation.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * js_animation.cpp -- animation description (JavaScript binding)
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient-js/malikania/js_animation.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient-js/malikania/js_animation.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * js_animation.hpp -- animation description (JavaScript binding)
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient-js/malikania/js_animator.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient-js/malikania/js_animator.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * js_animator.cpp -- animation drawing object (JavaScript binding)
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient-js/malikania/js_animator.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient-js/malikania/js_animator.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * js_animator.hpp -- animation drawing object (JavaScript binding)
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient-js/malikania/js_client_resources_loader.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient-js/malikania/js_client_resources_loader.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * js_client_resources_loader.cpp -- client resources loader (JavaScript binding)
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient-js/malikania/js_client_resources_loader.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient-js/malikania/js_client_resources_loader.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * js_client_resources_loader.hpp -- client resources loader (JavaScript binding)
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient-js/malikania/js_color.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient-js/malikania/js_color.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * js_color.cpp -- color description (JavaScript binding)
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient-js/malikania/js_color.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient-js/malikania/js_color.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * js_color.hpp -- color description (JavaScript binding)
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient-js/malikania/js_font.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient-js/malikania/js_font.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * js_font.cpp -- font object (JavaScript binding)
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient-js/malikania/js_font.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient-js/malikania/js_font.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * js_font.hpp -- font object (JavaScript binding)
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient-js/malikania/js_image.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient-js/malikania/js_image.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * js_image.cpp -- image object (JavaScript binding)
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient-js/malikania/js_image.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient-js/malikania/js_image.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * js_image.hpp -- image object (JavaScript binding)
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient-js/malikania/js_line.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient-js/malikania/js_line.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * js_line.cpp -- line description (JavaScript binding)
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient-js/malikania/js_line.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient-js/malikania/js_line.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * js_line.hpp -- line description (JavaScript binding)
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient-js/malikania/js_point.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient-js/malikania/js_point.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * js_point.cpp -- point description (JavaScript binding)
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient-js/malikania/js_point.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient-js/malikania/js_point.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * js_point.hpp -- point description (JavaScript binding)
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient-js/malikania/js_rectangle.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient-js/malikania/js_rectangle.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * js_rectangle.cpp -- rectangle description (JavaScript binding)
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient-js/malikania/js_rectangle.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient-js/malikania/js_rectangle.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * js_rectangle.hpp -- rectangle description (JavaScript binding)
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient-js/malikania/js_size.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient-js/malikania/js_size.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * js_size.cpp -- size description (JavaScript binding)
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient-js/malikania/js_size.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient-js/malikania/js_size.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * js_size.hpp -- size description (JavaScript binding)
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient-js/malikania/js_sprite.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient-js/malikania/js_sprite.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * js_sprite.cpp -- sprite object (JavaScript binding)
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient-js/malikania/js_sprite.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient-js/malikania/js_sprite.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * js_sprite.hpp -- sprite object (JavaScript binding)
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient-js/malikania/js_window.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient-js/malikania/js_window.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * js_window.cpp -- window management (JavaScript binding)
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient-js/malikania/js_window.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient-js/malikania/js_window.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * js_window.hpp -- window management (JavaScript binding)
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient/CMakeLists.txt	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient/CMakeLists.txt	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/libclient/malikania/animation.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient/malikania/animation.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * animation.hpp -- animation description
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient/malikania/animator.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient/malikania/animator.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * animator.cpp -- animation drawing object
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient/malikania/animator.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient/malikania/animator.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * animator.hpp -- animation drawing object
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient/malikania/backend/sdl/font_backend.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient/malikania/backend/sdl/font_backend.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * font_backend.cpp -- font object (SDL2 implementation)
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient/malikania/backend/sdl/font_backend.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient/malikania/backend/sdl/font_backend.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * font_backend.hpp -- font object (SDL2 implementation)
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient/malikania/backend/sdl/image_backend.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient/malikania/backend/sdl/image_backend.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * image_backend.cpp -- image object (SDL2 implementation)
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient/malikania/backend/sdl/image_backend.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient/malikania/backend/sdl/image_backend.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * image_backend.hpp -- image object (SDL2 implementation)
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient/malikania/backend/sdl/window_backend.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient/malikania/backend/sdl/window_backend.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * window_backend.cpp -- window object (SDL2 implementation)
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient/malikania/backend/sdl/window_backend.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient/malikania/backend/sdl/window_backend.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * window_backend.hpp -- window object (SDL2 implementation)
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient/malikania/button.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient/malikania/button.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * button.cpp -- GUI button element
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient/malikania/button.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient/malikania/button.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * button.hpp -- GUI button element
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient/malikania/client_resources_loader.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient/malikania/client_resources_loader.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * client_resources_loader.cpp -- load shared resources files for the client
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -24,10 +24,13 @@
 #include "client_resources_loader.hpp"
 #include "size.hpp"
 #include "sprite.hpp"
+#include "util.hpp"
 
 using boost::str;
 using boost::format;
 
+using mlk::util::json::invalid;
+
 namespace mlk {
 
 size client_resources_loader::require_size(const std::string& id,
@@ -99,7 +102,7 @@
     auto value = nlohmann::json::parse(locator().read(id));
 
     if (!value.is_object()) {
-        throw std::runtime_error(id + ": not a JSON object");
+        throw std::runtime_error("not a JSON object");
     }
 
     auto sprite = load_sprite(require_string(id, value, "sprite"));
@@ -108,7 +111,7 @@
     auto property = value["frames"];
 
     if (!property.is_array()) {
-        throw std::runtime_error(id + ": missing 'frames' property (array expected)");
+        throw invalid(id, nlohmann::json::value_t::array);
     }
 
     animation_frames frames;
--- a/libclient/malikania/client_resources_loader.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient/malikania/client_resources_loader.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * client_resources_loader.hpp -- load shared resources files for the client
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient/malikania/color.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient/malikania/color.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * color.cpp -- color description
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient/malikania/color.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient/malikania/color.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * color.hpp -- color description
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient/malikania/font.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient/malikania/font.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * font.cpp -- font object
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient/malikania/font.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient/malikania/font.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * font.hpp -- font object
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient/malikania/frame.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient/malikania/frame.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * frame.cpp -- top level GUI frame
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient/malikania/frame.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient/malikania/frame.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * frame.hpp -- top level GUI frame
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient/malikania/image.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient/malikania/image.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * image.cpp -- image object
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient/malikania/image.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient/malikania/image.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * image.hpp -- image object
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient/malikania/key.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient/malikania/key.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * key.hpp -- key definitions
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient/malikania/label.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient/malikania/label.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * label.cpp -- GUI label element
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient/malikania/label.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient/malikania/label.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * label.hpp -- GUI label element
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient/malikania/layout.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient/malikania/layout.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * layout.hpp -- generic layout manager inside a frame
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient/malikania/line.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient/malikania/line.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * line.hpp -- line description
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient/malikania/mouse.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient/malikania/mouse.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * mouse.hpp -- mouse definitions
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient/malikania/point.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient/malikania/point.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * point.hpp -- point description
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient/malikania/rectangle.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient/malikania/rectangle.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * rectangle.hpp -- rectangle description
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient/malikania/size.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient/malikania/size.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * size.hpp -- size description
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient/malikania/sprite.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient/malikania/sprite.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * sprite.cpp -- image sprite
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient/malikania/sprite.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient/malikania/sprite.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * sprite.hpp -- image sprite
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient/malikania/theme.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient/malikania/theme.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * theme.cpp -- theming support for gui elements
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient/malikania/theme.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient/malikania/theme.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * theme.hpp -- theming support for gui elements
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient/malikania/unique_layout.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient/malikania/unique_layout.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * unique_layout.cpp -- basic layout with one widget
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient/malikania/unique_layout.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient/malikania/unique_layout.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * unique_layout.hpp -- basic layout with one widget
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient/malikania/widget.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient/malikania/widget.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * widget.cpp -- basic abstract widget for GUI
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient/malikania/widget.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient/malikania/widget.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * widget.hpp -- basic abstract widget for GUI
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient/malikania/window.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient/malikania/window.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * window.cpp -- main window and basic drawing
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libclient/malikania/window.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libclient/malikania/window.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * window.hpp -- main window and basic drawing
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libcommon-js/CMakeLists.txt	Thu Dec 29 11:34:40 2016 +0100
+++ b/libcommon-js/CMakeLists.txt	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/libcommon-js/malikania/duktape.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libcommon-js/malikania/duktape.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * duktape.hpp -- Duktape extras
  *
- * Copyright (c) 2016 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2016-2017 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libcommon-js/malikania/js_elapsed_timer.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libcommon-js/malikania/js_elapsed_timer.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * js_elapsed_timer.cpp -- ElapsedTimer (JavaScript binding)
  *
- * Copyright (c) 2013-2016 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libcommon-js/malikania/js_elapsed_timer.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libcommon-js/malikania/js_elapsed_timer.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * js_elapsed_timer.hpp -- ElapsedTimer (JavaScript binding)
  *
- * Copyright (c) 2013-2016 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libcommon-js/malikania/js_resources_loader.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libcommon-js/malikania/js_resources_loader.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * js_resources_loader.cpp -- resources loader (JavaScript binding)
  *
- * Copyright (c) 2013-2016 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libcommon-js/malikania/js_resources_loader.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libcommon-js/malikania/js_resources_loader.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * js_resources_loader.hpp -- resources loader (JavaScript binding)
  *
- * Copyright (c) 2013-2016 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libcommon/CMakeLists.txt	Thu Dec 29 11:34:40 2016 +0100
+++ b/libcommon/CMakeLists.txt	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/libcommon/malikania/backend/sdl/sdl_util.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libcommon/malikania/backend/sdl/sdl_util.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * sdl_util.cpp -- common SDL2 related code
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libcommon/malikania/backend/sdl/sdl_util.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libcommon/malikania/backend/sdl/sdl_util.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * sdl_util.hpp -- common SDL2 related code
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libcommon/malikania/game.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libcommon/malikania/game.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * game.hpp -- basic game class
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libcommon/malikania/id.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libcommon/malikania/id.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * id.hpp -- integer id generator
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libcommon/malikania/net.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3753 +0,0 @@
-/*
- * net.hpp -- portable C++ socket wrapper
- *
- * Copyright (c) 2013-2016 David Demelier <markand@malikania.fr>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef MALIKANIA_NET_HPP
-#define MALIKANIA_NET_HPP
-
-/**
- * \file net.hpp
- * \brief Networking
- * \author David Demelier <markand@malikania.fr>
- */
-
-/**
- * \defgroup net-module-tcp Network TCP support
- * \brief TCP support in the networking module.
- */
-
-/**
- * \defgroup net-module-udp Network UDP support
- * \brief UDP support in networking module.
- */
-
-/**
- * \defgroup net-module-tls Network TLS support
- * \brief TLS support in networking module.
- */
-
-/**
- * \defgroup net-module-addresses Network predefined addresses
- * \brief Predefined addresses for sockets
- */
-
-/**
- * \defgroup net-module-options Network predefined options
- * \brief Predefined options for sockets
- */
-
-/**
- * \defgroup net-module-backends Network predefined backends
- * \brief Predefined backends for Listener
- */
-
-/**
- * \defgroup net-module-resolv Network resolver
- * \brief Resolv functions
- */
-
-/**
- * \page Networking Networking
- *
- *   - \subpage net-options
- *   - \subpage net-concepts
- */
-
-/**
- * \page net-options User options
- *
- * The user may set the following variables before compiling these files:
- *
- * # General options
- *
- * - **NET_NO_AUTO_INIT**: (bool) Set to 0 if you don't want Socket class to
- *   automatically calls init function and finish functions.
- *
- * - **NET_NO_SSL**: (bool) Set to 0 if you don't have access to OpenSSL
- *   library.
- *
- * - **NET_NO_AUTO_SSL_INIT**: (bool) Set to 0 if you don't want Socket class
- *   with Tls to automatically init the OpenSSL library. You will need to call
- *   ssl::init and ssl::finish.
- *
- * # General compatibility options.
- *
- * The following options are auto detected but you can override them if you
- * want.
- *
- * - **NET_HAVE_INET_PTON**: (bool) Set to 1 if you have inet_pton function.
- *   True for all platforms and Windows
- *   if _WIN32_WINNT is greater or equal to 0x0600.
- *
- * - **NET_HAVE_INET_NTOP**: (bool) Same as above.
- *
- * **Note:** On Windows, it is highly encouraged to set _WIN32_WINNT to at least
- * 0x0600 on MinGW.
- *
- * # Options for Listener class
- *
- * Feature detection, multiple implementations may be avaible, for example,
- * Linux has poll, select and epoll.
- *
- * We assume that `select(2)` is always available.
- *
- * Of course, you can set the variables yourself if you test it with your build
- * system.
- *
- * - **NET_HAVE_POLL**: Defined on all BSD, Linux. Also defined on Windows
- *   if _WIN32_WINNT is set to 0x0600 or greater.
- * - **NET_HAVE_KQUEUE**: Defined on all BSD and Apple.
- * - **NET_HAVE_EPOLL**: Defined on Linux only.
- * - **NET_DEFAULT_BACKEND**: Which backend to use (e.g. `Select`).
- *
- * The preference priority is ordered from left to right.
- *
- * | System        | Backend                 | Class name   |
- * |---------------|-------------------------|--------------|
- * | Linux         | epoll(7)                | Epoll        |
- * | *BSD          | kqueue(2)               | Kqueue       |
- * | Windows       | poll(2), select(2)      | Poll, Select |
- * | Mac OS X      | kqueue(2)               | Kqueue       |
- */
-
-/**
- * \page net-concepts Concepts
- *
- *   - \subpage net-concept-backend
- *   - \subpage net-concept-option
- *   - \subpage net-concept-stream
- *   - \subpage net-concept-datagram
- */
-
-/**
- * \page net-concept-backend Backend (Concept)
- *
- * A backend is an interface for the Listener class. It is primarily designed to
- * be the most suitable for the host environment.
- *
- * The backend must be default constructible, it is highly encouraged to be move
- * constructible.
- *
- * This concepts requires the following functions:
- *
- * # name
- *
- * Get the backend name, informational only.
- *
- * ## Synopsis
- *
- * ````
- * std::string name() const;
- * ````
- *
- * ## Returns
- *
- * The backend name.
- *
- * # set
- *
- * Set one or more condition for the given handle.
- *
- * This erase previous flags if any.
- *
- * ## Synopsis
- *
- * ````
- * void set(const ListenerTable &table, Handle handle, Condition condition,
- * bool add);
- * ````
- *
- * ## Arguments
- *
- *   - **table**: the current table of sockets,
- *   - **handle**: the handle to set,
- *   - **condition**: the condition to add (may be OR'ed),
- *   - **add**: hint set to true if the handle is not currently registered.
- *
- * # unset
- *
- * Unset one or more condition for the given handle.
- *
- * ## Synopsis
- *
- * ````
- * void unset(const ListenerTable &table, Handle handle, Condition condition,
- * bool remove);
- * ````
- *
- * ## Arguments
- *
- *   - **table**: the current table of sockets,
- *   - **handle**: the handle to update,
- *   - **condition**: the condition to remove (may be OR'ed),
- *   - **remove**: hint set to true if the handle will be completely removed.
- *
- * # wait
- *
- * Wait for multiple sockets to be ready.
- *
- * ## Synopsis
- *
- * ````
- * std::vector<ListenerStatus> wait(const ListenerTable &table, int ms);
- * ````
- *
- * ## Arguments
- *
- *   - **table**: the current table,
- *   - **ms**: the number to wait in milliseconds, negative means forever.
- *
- * ## Returns
- *
- * The list of sockets ready paired to their condition.
- */
-
-/**
- * \page net-concept-option Option (Concept)
- *
- * An option can be set or get from a socket.
- *
- * If an operation is not available, provides the function but throws an
- * exception with ENOSYS message.
- *
- * This concepts requires the following functions:
- *
- * # Option (constructor)
- *
- * At least one default constructor must be present.
- *
- * ## Synopsis
- *
- * ````
- * Option() noexcept;
- * ````
- *
- * # set
- *
- * Set the option.
- *
- * ## Synopsis
- *
- * ````
- * template <typename Address>
- * void set(Socket &sc) const;
- * ````
- *
- * ## Arguments
- *
- *   - **sc**: the socket.
- *
- * # get
- *
- * Get an option, T can be any type.
- *
- * ## Synopsis
- *
- * ````
- * template <typename Address>
- * T get(Socket &sc) const;
- * ````
- *
- * ## Arguments
- *
- *   - **sc**: the socket.
- *
- * ## Returns
- *
- * The value.
- */
-
-/**
- * \page net-concept-stream Stream (Concept)
- *
- * This concepts requires the following functions:
- *
- * # type
- *
- * Return the type of socket, usually `SOCK_STREAM`.
- *
- * ## Synopsis
- *
- * ````
- * int type() const noexcept;
- * ````
- *
- * ## Returns
- *
- * The type of socket.
- *
- * # connect
- *
- * Connect to the given address.
- *
- * ## Synopsis
- *
- * ````
- * void connect(const sockaddr *address, socklen_t length); // (0)
- * void connect(const Address &address); // 1 (Optional)
- * ````
- *
- * ## Arguments
- *
- *   - **address**: the address,
- *   - **length**: the address length.
- *
- * ## Throws
- *
- *   - net::WouldBlockError: if the operation would block,
- *   - net::Error: on other error.
- *
- * # accept
- *
- * Accept a new client.
- *
- * If no pending connection is available and operation would block, the
- * implementation must throw WouldBlockError. Any other error can be thrown
- * otherwise a valid socket must be returned.
- *
- * ## Synopsis
- *
- * ````
- * Socket accept();
- * ````
- *
- * ## Returns
- *
- * The new socket.
- *
- * ## Throws
- *
- *   - net::WouldBlockError: if the operation would block,
- *   - net::Error: on other error.
- *
- * # recv
- *
- * Receive data.
- *
- * ## Synopsis
- *
- * ````
- * unsigned recv(void *data, unsigned length);
- * ````
- *
- * ## Arguments
- *
- *   - **data**: the destination buffer,
- *   - **length**: the destination buffer length.
- *
- * ## Returns
- *
- * The number of bytes sent.
- *
- * ## Throws
- *
- *   - net::WouldBlockError: if the operation would block,
- *   - net::Error: on other error.
- *
- * # send
- *
- * Send data.
- *
- * ## Synopsis
- *
- * ````
- * unsigned send(const void *data, unsigned length);
- * ````
- *
- * ## Arguments
- *
- *   - **data**: the data to send,
- *   - **length**: the data length.
- *
- * ## Returns
- *
- * The number of bytes sent.
- *
- * ## Throws
- *
- *   - net::WouldBlockError: if the operation would block,
- *   - net::Error: on other error.
- */
-
-/**
- * \page net-concept-datagram Datagram (Concept)
- *
- * This concepts requires the following functions:
- *
- * # type
- *
- * Return the type of socket, usually `SOCK_DGRAM`.
- *
- * ## Synopsis
- *
- * ````
- * int type() const noexcept;
- * ````
- *
- * ## Returns
- *
- * The type of socket.
- *
- * # recvfrom
- *
- * Receive data.
- *
- * ## Synopsis
- *
- * ````
- * unsigned recvfrom(void *data, unsigned length, sockaddr *address,
- *     socklen_t *addrlen);
- * unsigned recvfrom(void *data, unsigned length, Address *source)
- * ````
- *
- * ## Arguments
- *
- *   - **data**: the data,
- *   - **length**: the length,
- *   - **address**: the source address,
- *   - **addrlen**: the source address in/out length.
- *
- * ## Returns
- *
- * The number of bytes received.
- *
- * ## Throws
- *
- *   - net::WouldBlockError: if the operation would block,
- *   - net::Error: on other error.
- *
- * # sendto
- *
- * ````
- * unsigned sendto(const void *data, unsigned length, const sockaddr *address,
- *     socklen_t addrlen);
- * unsigned sendto(const void *data, unsigned length, const Address &address);
- * ````
- *
- * ## Arguments
- *
- *   - **data**: the data to send,
- *   - **length**: the data length,
- *   - **address**: the destination address,
- *   - **addrlen**: the destination address length.
- *
- * ## Returns
- *
- * The number of bytes sent.
- *
- * ## Throws
- *
- *   - net::WouldBlockError: if the operation would block,
- *   - net::Error: on other error.
- */
-
-/*
- * Headers to include.
- * ------------------------------------------------------------------
- */
-
-/*
- * Include Windows headers before because it brings _WIN32_WINNT if not
- * specified by the user.
- */
-#if defined(_WIN32)
-#   include <WinSock2.h>
-#   include <WS2tcpip.h>
-#else
-#   include <sys/ioctl.h>
-#   include <sys/types.h>
-#   include <sys/socket.h>
-#   include <sys/un.h>
-
-#   include <arpa/inet.h>
-
-#   include <netinet/in.h>
-#   include <netinet/tcp.h>
-
-#   include <fcntl.h>
-#   include <netdb.h>
-#   include <unistd.h>
-#endif
-
-#include <algorithm>
-#include <atomic>
-#include <cassert>
-#include <cerrno>
-#include <chrono>
-#include <climits>
-#include <cstddef>
-#include <cstdlib>
-#include <cstring>
-#include <iterator>
-#include <memory>
-#include <mutex>
-#include <string>
-#include <unordered_map>
-#include <vector>
-
-#if !defined(NET_NO_SSL)
-
-#include <openssl/err.h>
-#include <openssl/evp.h>
-#include <openssl/ssl.h>
-
-#endif // !NET_NO_SSL
-
-/*
- * Determine which I/O multiplexing implementations are available.
- * ------------------------------------------------------------------
- *
- * May define the following:
- *
- *   - NET_HAVE_EPOLL
- *   - NET_HAVE_KQUEUE
- *   - NET_HAVE_POLL
- */
-
-#if defined(_WIN32)
-#   if _WIN32_WINNT >= 0x0600 && !defined(NET_HAVE_POLL)
-#       define NET_HAVE_POLL
-#   endif
-#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__)
-#   if !defined(NET_HAVE_KQUEUE)
-#       define NET_HAVE_KQUEUE
-#   endif
-#   if !defined(NET_HAVE_POLL)
-#       define NET_HAVE_POLL
-#   endif
-#elif defined(__linux__)
-#   if !defined(NET_HAVE_EPOLL)
-#       define NET_HAVE_EPOLL
-#   endif
-#   if !defined(NET_HAVE_POLL)
-#       define NET_HAVE_POLL
-#   endif
-#endif
-
-/*
- * Compatibility macros.
- * ------------------------------------------------------------------
- */
-
-/**
- * \brief Tells if inet_pton is available
- */
-#if !defined(NET_HAVE_INET_PTON)
-#   if defined(_WIN32)
-#       if _WIN32_WINNT >= 0x0600
-#           define NET_HAVE_INET_PTON
-#       endif
-#   else
-#       define NET_HAVE_INET_PTON
-#   endif
-#endif
-
-/**
- * \brief Tells if inet_ntop is available
- */
-#if !defined(NET_HAVE_INET_NTOP)
-#   if defined(_WIN32)
-#       if _WIN32_WINNT >= 0x0600
-#           define NET_HAVE_INET_NTOP
-#       endif
-#   else
-#       define NET_HAVE_INET_NTOP
-#   endif
-#endif
-
-/*
- * Define NET_DEFAULT_BACKEND.
- * ------------------------------------------------------------------
- *
- * Define the default I/O multiplexing implementation to use if not specified.
- */
-
-/**
- * \brief Defines the default backend
- */
-#if defined(_WIN32)
-#   if !defined(NET_DEFAULT_BACKEND)
-#       if defined(NET_HAVE_POLL)
-#           define NET_DEFAULT_BACKEND Poll
-#       else
-#           define NET_DEFAULT_BACKEND Select
-#       endif
-#   endif
-#elif defined(__linux__)
-#   include <sys/epoll.h>
-
-#   if !defined(NET_DEFAULT_BACKEND)
-#       define NET_DEFAULT_BACKEND Epoll
-#   endif
-#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__APPLE__)
-#   include <sys/types.h>
-#   include <sys/event.h>
-#   include <sys/time.h>
-
-#   if !defined(NET_DEFAULT_BACKEND)
-#       define NET_DEFAULT_BACKEND Kqueue
-#   endif
-#else
-#   if !defined(NET_DEFAULT_BACKEND)
-#       define NET_DEFAULT_BACKEND Select
-#   endif
-#endif
-
-#if defined(NET_HAVE_POLL) && !defined(_WIN32)
-#    include <poll.h>
-#endif
-
-namespace malikania {
-
-/**
- * The network namespace.
- */
-namespace net {
-
-/*
- * Portables types.
- * ------------------------------------------------------------------
- *
- * The following types are defined differently between Unix and Windows.
- */
-
-#if defined(_WIN32)
-
-/**
- * Socket type, SOCKET.
- */
-using Handle = SOCKET;
-
-/**
- * Argument to pass to set.
- */
-using ConstArg = const char *;
-
-/**
- * Argument to pass to get.
- */
-using Arg = char *;
-
-#else
-
-/**
- * Socket type, int.
- */
-using Handle = int;
-
-/**
- * Argument to pass to set.
- */
-using ConstArg = const void *;
-
-/**
- * Argument to pass to get.
- */
-using Arg = void *;
-
-#endif
-
-/*
- * Portable constants.
- * ------------------------------------------------------------------
- *
- * These constants are needed to check functions return codes, they are rarely
- * needed in end user code.
- */
-
-#if defined(_WIN32)
-
-/**
- * Socket creation failure or invalidation.
- */
-const Handle Invalid{INVALID_SOCKET};
-
-/**
- * Socket operation failure.
- */
-const int Failure{SOCKET_ERROR};
-
-#else
-
-/**
- * Socket creation failure or invalidation.
- */
-const Handle Invalid{-1};
-
-/**
- * Socket operation failure.
- */
-const int Failure{-1};
-
-#endif
-
-/**
- * Close the socket library.
- */
-inline void finish() noexcept
-{
-#if defined(_WIN32)
-    WSACleanup();
-#endif
-}
-
-/**
- * Initialize the socket library. Except if you defined NET_NO_AUTO_INIT, you
- * don't need to call this
- * function manually.
- */
-inline void init() noexcept
-{
-#if defined(_WIN32)
-    static std::atomic<bool> initialized;
-    static std::mutex mutex;
-
-    std::lock_guard<std::mutex> lock(mutex);
-
-    if (!initialized) {
-        initialized = true;
-
-        WSADATA wsa;
-        WSAStartup(MAKEWORD(2, 2), &wsa);
-
-        /*
-         * If NET_NO_AUTO_INIT is not set then the user must also call finish
-         * himself.
-         */
-#if !defined(NET_NO_AUTO_INIT)
-        atexit(finish);
-#endif
-    }
-#endif
-}
-
-/**
- * Get the last system error.
- *
- * \param errn the error number (errno or WSAGetLastError)
- * \return the error
- */
-inline std::string error(int errn)
-{
-#if defined(_WIN32)
-    LPSTR str = nullptr;
-    std::string errmsg = "Unknown error";
-
-    FormatMessageA(
-        FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
-        NULL,
-        errn,
-        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
-        (LPSTR)&str, 0, NULL);
-
-
-    if (str) {
-        errmsg = std::string(str);
-        LocalFree(str);
-    }
-
-    return errmsg;
-#else
-    return strerror(errn);
-#endif
-}
-
-/**
- * Get the last socket system error. The error is set from errno or from
- * WSAGetLastError on Windows.
- *
- * \return a string message
- */
-inline std::string error()
-{
-#if defined(_WIN32)
-    return error(WSAGetLastError());
-#else
-    return error(errno);
-#endif
-}
-
-#if !defined(NET_NO_SSL)
-
-/**
- * \brief SSL namespace
- */
-namespace ssl {
-
-/**
- * \enum Method
- * \brief Which OpenSSL method to use.
- */
-enum Method {
-    Tlsv1,      //!< TLS v1.2 (recommended)
-    Sslv3       //!< SSLv3
-};
-
-/**
- * Initialize the OpenSSL library. Except if you defined NET_NO_AUTO_SSL_INIT,
- * you don't need to call this function manually.
- */
-inline void init() noexcept
-{
-    static std::atomic<bool> initialized;
-    static std::mutex mutex;
-
-    std::lock_guard<std::mutex> lock(mutex);
-
-    if (!initialized) {
-        initialized = true;
-
-        SSL_library_init();
-        SSL_load_error_strings();
-        OpenSSL_add_all_algorithms();
-
-#if !defined(NET_NO_AUTO_SSL_INIT)
-        atexit(finish);
-#endif
-    }
-}
-
-/**
- * Close the OpenSSL library.
- */
-inline void finish() noexcept
-{
-    ERR_free_strings();
-}
-
-} // !ssl
-
-#endif // !NET_NO_SSL
-
-/*
- * Error class.
- * ------------------------------------------------------------------
- *
- * This is the main exception thrown on socket operations.
- */
-
-/**
- * \brief Base class for sockets error.
- */
-class Error : public std::exception {
-private:
-    std::string m_message;
-
-public:
-    /**
-     * Construct the error using the specified error from the system.
-     *
-     * \param code the error code
-     * \warning the code must be a Winsock error or errno on Unix
-     */
-    inline Error(int code) noexcept
-        : m_message(error(code))
-    {
-    }
-
-    /**
-     * Construct the error using the custom message.
-     *
-     * \param message the message
-     */
-    inline Error(std::string message) noexcept
-        : m_message(std::move(message))
-    {
-    }
-
-    /**
-     * Construct the error using the last message from the system.
-     */
-    inline Error() noexcept
-#if defined(_WIN32)
-        : Error(WSAGetLastError())
-#else
-        : Error(errno)
-#endif
-    {
-    }
-
-    /**
-     * Get the error (only the error content).
-     *
-     * \return the error
-     */
-    const char *what() const noexcept override
-    {
-        return m_message.c_str();
-    }
-};
-
-/**
- * \brief Timeout occured.
- */
-class TimeoutError : public std::exception {
-public:
-    /**
-     * Get the error message.
-     *
-     * \return the message
-     */
-    const char *what() const noexcept override
-    {
-        return std::strerror(ETIMEDOUT);
-    }
-};
-
-/**
- * \brief Operation would block.
- */
-class WouldBlockError : public std::exception {
-public:
-    /**
-     * Get the error message.
-     *
-     * \return the message
-     */
-    const char *what() const noexcept override
-    {
-        return std::strerror(EWOULDBLOCK);
-    }
-};
-
-/**
- * \brief Operation requires sending data to complete.
- */
-class WantWriteError : public std::exception {
-public:
-    /**
-     * Get the error message.
-     *
-     * \return the message
-     */
-    const char *what() const noexcept override
-    {
-        return "operation requires writing to complete";
-    }
-};
-
-/**
- * \brief Operation requires reading data to complete.
- */
-class WantReadError : public std::exception {
-public:
-    /**
-     * Get the error message.
-     *
-     * \return the message
-     */
-    const char *what() const noexcept override
-    {
-        return "operation requires read to complete";
-    }
-};
-
-/*
- * Condition enum
- * ------------------------------------------------------------------
- *
- * Defines if we must wait for reading or writing.
- */
-
-/**
- * \enum Condition
- * \brief Define the required condition for the socket.
- */
-enum class Condition {
-    None,                       //!< No condition is required
-    Readable    = (1 << 0),     //!< The socket must be readable
-    Writable    = (1 << 1),     //!< The socket must be writable
-    All         = 0x3           //! Both are requested
-};
-
-/**
- * Apply bitwise XOR.
- *
- * \param v1 the first value
- * \param v2 the second value
- * \return the new value
- */
-inline Condition operator^(Condition v1, Condition v2) noexcept
-{
-    return static_cast<Condition>(static_cast<int>(v1) ^ static_cast<int>(v2));
-}
-
-/**
- * Apply bitwise AND.
- *
- * \param v1 the first value
- * \param v2 the second value
- * \return the new value
- */
-inline Condition operator&(Condition v1, Condition v2) noexcept
-{
-    return static_cast<Condition>(static_cast<int>(v1) & static_cast<int>(v2));
-}
-
-/**
- * Apply bitwise OR.
- *
- * \param v1 the first value
- * \param v2 the second value
- * \return the new value
- */
-inline Condition operator|(Condition v1, Condition v2) noexcept
-{
-    return static_cast<Condition>(static_cast<int>(v1) | static_cast<int>(v2));
-}
-
-/**
- * Apply bitwise NOT.
- *
- * \param v the value
- * \return the complement
- */
-inline Condition operator~(Condition v) noexcept
-{
-    return static_cast<Condition>(~static_cast<int>(v));
-}
-
-/**
- * Assign bitwise OR.
- *
- * \param v1 the first value
- * \param v2 the second value
- * \return the new value
- */
-inline Condition &operator|=(Condition &v1, Condition v2) noexcept
-{
-    v1 = static_cast<Condition>(static_cast<int>(v1) | static_cast<int>(v2));
-
-    return v1;
-}
-
-/**
- * Assign bitwise AND.
- *
- * \param v1 the first value
- * \param v2 the second value
- * \return the new value
- */
-inline Condition &operator&=(Condition &v1, Condition v2) noexcept
-{
-    v1 = static_cast<Condition>(static_cast<int>(v1) & static_cast<int>(v2));
-
-    return v1;
-}
-
-/**
- * Assign bitwise XOR.
- *
- * \param v1 the first value
- * \param v2 the second value
- * \return the new value
- */
-inline Condition &operator^=(Condition &v1, Condition v2) noexcept
-{
-    v1 = static_cast<Condition>(static_cast<int>(v1) ^ static_cast<int>(v2));
-
-    return v1;
-}
-
-/**
- * \brief Generic socket address storage.
- * \ingroup net-module-addresses
- */
-class Address {
-private:
-    sockaddr_storage m_storage;
-    socklen_t m_length;
-
-public:
-    /**
-     * Construct empty address.
-     */
-    inline Address() noexcept
-        : m_storage{}
-        , m_length(0)
-    {
-    }
-
-    /**
-     * Construct address from existing one.
-     *
-     * \pre address != nullptr
-     * \param address the address
-     * \param length the address length
-     */
-    inline Address(const sockaddr *address, socklen_t length) noexcept
-        : m_length(length)
-    {
-        assert(address);
-
-        std::memcpy(&m_storage, address, length);
-    }
-
-    /**
-     * Get the underlying address.
-     *
-     * \return the address
-     */
-    inline const sockaddr *get() const noexcept
-    {
-        return reinterpret_cast<const sockaddr *>(&m_storage);
-    }
-
-    /**
-     * Overloaded function
-     *
-     * \return the address
-     */
-    inline sockaddr *get() noexcept
-    {
-        return reinterpret_cast<sockaddr *>(&m_storage);
-    }
-
-    /**
-     * Get the underlying address as the given type (e.g sockaddr_in).
-     *
-     * \return the address reference
-     */
-    template <typename T>
-    inline const T &as() const noexcept
-    {
-        return reinterpret_cast<const T &>(m_storage);
-    }
-
-    /**
-     * Overloaded function
-     *
-     * \return the address reference
-     */
-    template <typename T>
-    inline T &as() noexcept
-    {
-        return reinterpret_cast<T &>(m_storage);
-    }
-
-    /**
-     * Get the underlying address length.
-     *
-     * \return the length
-     */
-    inline socklen_t length() const noexcept
-    {
-        return m_length;
-    }
-
-    /**
-     * Get the address domain.
-     *
-     * \return the domain
-     */
-    inline int domain() const noexcept
-    {
-        return m_storage.ss_family;
-    }
-};
-
-/**
- * \brief Address iterator.
- * \ingroup net-module-addresses
- * \see resolve
- *
- * This iterator can be used to try to connect to an host.
- *
- * When you use resolve with unspecified domain or socket type, the function may
- * retrieve several different addresses that you can iterate over to try to
- * connect to.
- *
- * Example:
- *
- * ````cpp
- * SocketTcp sc;
- * AddressIterator end, it = resolve("hostname.test", "80");
- *
- * while (!connected_condition && it != end)
- *   sc.connect(it->address(), it->length());
- * ````
- *
- * When an iterator equals to a default constructed iterator, it is considered
- * not dereferenceable.
- */
-class AddressIterator : public std::iterator<std::forward_iterator_tag, Address> {
-private:
-    std::vector<Address> m_addresses;
-    std::size_t m_index{0};
-
-public:
-    /**
-     * Construct a null iterator.
-     *
-     * The default constructed iterator is not dereferenceable.
-     */
-    inline AddressIterator() noexcept = default;
-
-    /**
-     * Construct an address iterator with a set of addresses.
-     *
-     * \pre index < m_addresses.size()
-     * \param addresses the addresses
-     * \param index the first index
-     */
-    inline AddressIterator(std::vector<Address> addresses, std::size_t index = 0) noexcept
-        : m_addresses(std::move(addresses))
-        , m_index(index)
-    {
-        assert(index < m_addresses.size());
-    }
-
-    /**
-     * Get the generic address.
-     *
-     * \pre this is dereferenceable
-     * \return the generic address
-     */
-    inline const Address &operator*() const noexcept
-    {
-        assert(m_index <= m_addresses.size());
-
-        return m_addresses[m_index];
-    }
-
-    /**
-     * Overloaded function.
-     *
-     * \pre this is dereferenceable
-     * \return the generic address
-     */
-    inline Address &operator*() noexcept
-    {
-        assert(m_index <= m_addresses.size());
-
-        return m_addresses[m_index];
-    }
-
-    /**
-     * Get the generic address.
-     *
-     * \pre this is dereferenceable
-     * \return the generic address
-     */
-    inline const Address *operator->() const noexcept
-    {
-        assert(m_index <= m_addresses.size());
-
-        return &m_addresses[m_index];
-    }
-
-    /**
-     * Overloaded function.
-     *
-     * \pre this is dereferenceable
-     * \return the generic address
-     */
-    inline Address *operator->() noexcept
-    {
-        assert(m_index <= m_addresses.size());
-
-        return &m_addresses[m_index];
-    }
-
-    /**
-     * Pre-increment the iterator.
-     *
-     * \return this
-     */
-    inline AddressIterator &operator++(int) noexcept
-    {
-        if (m_index + 1 >= m_addresses.size()) {
-            m_addresses.clear();
-            m_index = 0;
-        } else
-            m_index ++;
-
-        return *this;
-    }
-
-    /**
-     * Post-increment the iterator.
-     *
-     * \return copy of this
-     */
-    inline AddressIterator operator++() noexcept
-    {
-        AddressIterator save = *this;
-
-        if (m_index + 1 >= m_addresses.size()) {
-            m_addresses.clear();
-            m_index = 0;
-        } else
-            m_index ++;
-
-        return save;
-    }
-
-    friend bool operator==(const AddressIterator &, const AddressIterator &) noexcept;
-    friend bool operator!=(const AddressIterator &, const AddressIterator &) noexcept;
-};
-
-/**
- * Compare two address iterators.
- *
- * \param i1 the first iterator
- * \param i2 the second iterator
- * \return true if they equal
- */
-inline bool operator==(const AddressIterator &i1, const AddressIterator &i2) noexcept
-{
-    return i1.m_addresses == i2.m_addresses && i1.m_index == i2.m_index;
-}
-
-/**
- * Compare two address iterators.
- *
- * \param i1 the first iterator
- * \param i2 the second iterator
- * \return false if they equal
- */
-inline bool operator!=(const AddressIterator &i1, const AddressIterator &i2) noexcept
-{
-    return !(i1 == i2);
-}
-
-/**
- * Compare two generic addresses.
- *
- * \param a1 the first address
- * \param a2 the second address
- * \return true if they equal
- */
-inline bool operator==(const Address &a1, const Address &a2) noexcept
-{
-    return a1.length() == a2.length() && std::memcmp(a1.get(), a2.get(), a1.length()) == 0;
-}
-
-/**
- * Compare two generic addresses.
- *
- * \param a1 the first address
- * \param a2 the second address
- * \return false if they equal
- */
-inline bool operator!=(const Address &a1, const Address &a2) noexcept
-{
-    return !(a1 == a2);
-}
-
-/**
- * \brief Base socket class.
- */
-class Socket {
-protected:
-    /**
-     * The native handle.
-     */
-    Handle m_handle{Invalid};
-
-public:
-    /**
-     * Create a socket handle.
-     *
-     * This is the primary function and the only one that creates the socket
-     * handle, all other constructors are just overloaded functions.
-     *
-     * \param domain the domain AF_*
-     * \param type the type SOCK_*
-     * \param protocol the protocol
-     * \throw Error on errors
-     */
-    Socket(int domain, int type, int protocol)
-    {
-#if !defined(NET_NO_AUTO_INIT)
-        init();
-#endif
-        m_handle = ::socket(domain, type, protocol);
-
-        if (m_handle == Invalid)
-            throw Error();
-    }
-
-    /**
-     * Create the socket with an already defined handle and its protocol.
-     *
-     * \param handle the handle
-     */
-    explicit inline Socket(Handle handle) noexcept
-        : m_handle(handle)
-    {
-    }
-
-    /**
-     * Create an invalid socket. Can be used when you cannot instanciate the
-     * socket immediately.
-     */
-    explicit inline Socket(std::nullptr_t) noexcept
-        : m_handle(Invalid)
-    {
-    }
-
-    /**
-     * Copy constructor deleted.
-     */
-    Socket(const Socket &) = delete;
-
-    /**
-     * Transfer ownership from other to this.
-     *
-     * \param other the other socket
-     */
-    inline Socket(Socket &&other) noexcept
-        : m_handle(other.m_handle)
-    {
-        other.m_handle = Invalid;
-    }
-
-    /**
-     * Default destructor.
-     */
-    virtual ~Socket()
-    {
-        close();
-    }
-
-    /**
-     * Tells if the socket is not invalid.
-     *
-     * \return true if not invalid
-     */
-    inline bool isOpen() const noexcept
-    {
-        return m_handle != Invalid;
-    }
-
-    /**
-     * Set an option for the socket. Wrapper of setsockopt(2).
-     *
-     * \pre isOpen()
-     * \param level the setting level
-     * \param name the name
-     * \param arg the value
-     * \throw Error on errors
-     */
-    template <typename Argument>
-    inline void set(int level, int name, const Argument &arg)
-    {
-        assert(m_handle != Invalid);
-
-        if (::setsockopt(m_handle, level, name, (ConstArg)&arg, sizeof (arg)) == Failure)
-            throw Error();
-    }
-
-    /**
-     * Object-oriented option setter.
-     *
-     * The object must have `set(Socket &) const`.
-     *
-     * \pre isOpen()
-     * \param option the option
-     * \throw Error on errors
-     */
-    template <typename Option>
-    inline void set(const Option &option)
-    {
-        assert(m_handle != Invalid);
-
-        option.set(*this);
-    }
-
-    /**
-     * Get an option for the socket. Wrapper of getsockopt(2).
-     *
-     * \pre isOpen()
-     * \param level the setting level
-     * \param name the name
-     * \return the value
-     * \throw Error on errors
-     */
-    template <typename Argument>
-    Argument get(int level, int name)
-    {
-        assert(m_handle != Invalid);
-
-        Argument desired, result{};
-        socklen_t size = sizeof (result);
-
-        if (::getsockopt(m_handle, level, name, (Arg)&desired, &size) == Failure)
-            throw Error();
-
-        std::memcpy(&result, &desired, size);
-
-        return result;
-    }
-
-    /**
-     * Object-oriented option getter.
-     *
-     * The object must have `T get(Socket &) const`, T can be any type and it is
-     * the value returned from this function.
-     *
-     * \pre isOpen()
-     * \return the same value as get() in the option
-     * \throw Error on errors
-     */
-    template <typename Option>
-    inline auto get() -> decltype(std::declval<Option>().get(*this))
-    {
-        assert(m_handle != Invalid);
-
-        return Option().get(*this);
-    }
-
-    /**
-     * Get the native handle.
-     *
-     * \return the handle
-     * \warning Not portable
-     */
-    inline Handle handle() const noexcept
-    {
-        return m_handle;
-    }
-
-    /**
-     * Bind using a native address.
-     *
-     * \pre isOpen()
-     * \param address the address
-     * \param length the size
-     * \throw Error on errors
-     */
-    inline void bind(const sockaddr *address, socklen_t length)
-    {
-        assert(m_handle != Invalid);
-
-        if (::bind(m_handle, address, length) == Failure)
-            throw Error();
-    }
-
-    /**
-     * Overload that takes an address.
-     *
-     * \pre isOpen()
-     * \param address the address
-     * \throw Error on errors
-     */
-    inline void bind(const Address &address)
-    {
-        assert(m_handle != Invalid);
-
-        bind(address.get(), address.length());
-    }
-
-    /**
-     * Listen for pending connection.
-     *
-     * \pre isOpen()
-     * \param max the maximum number
-     * \throw Error on errors
-     */
-    inline void listen(int max = 128)
-    {
-        assert(m_handle != Invalid);
-
-        if (::listen(m_handle, max) == Failure)
-            throw Error();
-    }
-
-    /**
-     * Get the local name. This is a wrapper of getsockname().
-     *
-     * \pre isOpen()
-     * \return the address
-     * \throw Error on failures
-     */
-    Address getsockname() const
-    {
-        assert(m_handle != Invalid);
-
-        sockaddr_storage ss;
-        socklen_t length = sizeof (sockaddr_storage);
-
-        if (::getsockname(m_handle, reinterpret_cast<sockaddr *>(&ss), &length) == Failure)
-            throw Error();
-
-        return Address(reinterpret_cast<sockaddr *>(&ss), length);
-    }
-
-    /**
-     * Get connected address. This is a wrapper for getpeername().
-     *
-     * \pre isOpen()
-     * \return the address
-     * \throw Error on failures
-     */
-    Address getpeername() const
-    {
-        assert(m_handle != Invalid);
-
-        sockaddr_storage ss;
-        socklen_t length = sizeof (sockaddr_storage);
-
-        if (::getpeername(m_handle, reinterpret_cast<sockaddr *>(&ss), &length) == Failure)
-            throw Error();
-
-        return Address(reinterpret_cast<sockaddr *>(&ss), length);
-    }
-
-    /**
-     * Close the socket.
-     *
-     * Automatically called from the destructor.
-     */
-    void close()
-    {
-        if (m_handle != Invalid) {
-#if defined(_WIN32)
-            ::closesocket(m_handle);
-#else
-            ::close(m_handle);
-#endif
-            m_handle = Invalid;
-        }
-    }
-
-    /**
-     * Assignment operator forbidden.
-     *
-     * \return *this
-     */
-    Socket &operator=(const Socket &) = delete;
-
-    /**
-     * Transfer ownership from other to this. The other socket is left
-     * invalid and will not be closed.
-     *
-     * \param other the other socket
-     * \return this
-     */
-    Socket &operator=(Socket &&other) noexcept
-    {
-        m_handle = other.m_handle;
-        other.m_handle = Invalid;
-
-        return *this;
-    }
-};
-
-/**
- * Compare two sockets.
- *
- * \param s1 the first socket
- * \param s2 the second socket
- * \return true if they equals
- */
-inline bool operator==(const Socket &s1, const Socket &s2)
-{
-    return s1.handle() == s2.handle();
-}
-
-/**
- * Compare two sockets.
- *
- * \param s1 the first socket
- * \param s2 the second socket
- * \return true if they are different
- */
-inline bool operator!=(const Socket &s1, const Socket &s2)
-{
-    return s1.handle() != s2.handle();
-}
-
-/**
- * Compare two sockets.
- *
- * \param s1 the first socket
- * \param s2 the second socket
- * \return true if s1 < s2
- */
-inline bool operator<(const Socket &s1, const Socket &s2)
-{
-    return s1.handle() < s2.handle();
-}
-
-/**
- * Compare two sockets.
- *
- * \param s1 the first socket
- * \param s2 the second socket
- * \return true if s1 > s2
- */
-inline bool operator>(const Socket &s1, const Socket &s2)
-{
-    return s1.handle() > s2.handle();
-}
-
-/**
- * Compare two sockets.
- *
- * \param s1 the first socket
- * \param s2 the second socket
- * \return true if s1 <= s2
- */
-inline bool operator<=(const Socket &s1, const Socket &s2)
-{
-    return s1.handle() <= s2.handle();
-}
-
-/**
- * Compare two sockets.
- *
- * \param s1 the first socket
- * \param s2 the second socket
- * \return true if s1 >= s2
- */
-inline bool operator>=(const Socket &s1, const Socket &s2)
-{
-    return s1.handle() >= s2.handle();
-}
-
-/**
- * \brief Clear TCP implementation.
- * \ingroup net-module-tcp
- *
- * This is the basic TCP protocol that implements recv, send, connect and accept
- * as wrappers of the usual C functions.
- */
-class TcpSocket : public Socket {
-public:
-    /**
-     * Inherited constructors.
-     */
-    using Socket::Socket;
-
-    /**
-     * Construct a TCP socket.
-     *
-     * \param domain the domain
-     * \param protocol the protocol
-     * \throw Error on errors
-     */
-    inline TcpSocket(int domain, int protocol)
-        : Socket(domain, SOCK_STREAM, protocol)
-    {
-    }
-
-    /**
-     * Get the type of the socket.
-     *
-     * \return the type
-     */
-    inline int type() const noexcept
-    {
-        return SOCK_STREAM;
-    }
-
-    /**
-     * Initiate connection.
-     *
-     * \param address the address
-     * \param length the address length
-     * \throw WouldBlockError if the socket is marked non-blocking and
-     * connection cannot be established immediately
-     * \throw Error on other errors
-     */
-    void connect(const sockaddr *address, socklen_t length)
-    {
-        if (::connect(this->m_handle, address, length) == Failure) {
-#if defined(_WIN32)
-            int error = WSAGetLastError();
-
-            if (error == WSAEWOULDBLOCK)
-                throw WouldBlockError();
-            else
-                throw Error(error);
-#else
-            if (errno == EINPROGRESS)
-                throw WouldBlockError();
-            else
-                throw Error();
-#endif
-        }
-    }
-
-    /**
-     * Overloaded function.
-     *
-     * \param address the address
-     * \throw WouldBlockError if the socket is marked non-blocking and
-     * connection cannot be established immediately
-     * \throw Error on other errors
-     */
-    void connect(const Address &address)
-    {
-        connect(address.get(), address.length());
-    }
-
-    /**
-     * Accept a new client.
-     *
-     * If there are no pending connection, an invalid socket is returned.
-     *
-     * \return the new socket
-     * \throw WouldBlockError if the socket is marked non-blocking and no
-     * connection are available
-     * \throw Error on other errors
-     */
-    TcpSocket accept()
-    {
-        Handle handle = ::accept(this->m_handle, nullptr, 0);
-
-        if (handle == Invalid) {
-#if defined(_WIN32)
-            int error = WSAGetLastError();
-
-            if (error == WSAEWOULDBLOCK)
-                throw WouldBlockError();
-            else
-                throw Error(error);
-#else
-            if (errno == EWOULDBLOCK || errno == EAGAIN)
-                throw WouldBlockError();
-            else
-                throw Error();
-#endif
-        }
-
-        return TcpSocket(handle);
-    }
-
-    /**
-     * Receive some data.
-     *
-     * \param data the destination buffer
-     * \param length the buffer length
-     * \return the number of bytes received
-     */
-    unsigned recv(void *data, unsigned length)
-    {
-        int max = length > INT_MAX ? INT_MAX : static_cast<int>(length);
-        int nbread = ::recv(this->m_handle, (Arg)data, max, 0);
-
-        if (nbread == Failure) {
-#if defined(_WIN32)
-            int error = WSAGetLastError();
-
-            if (error == WSAEWOULDBLOCK)
-                throw WouldBlockError();
-            else
-                throw Error(error);
-#else
-            if (errno == EAGAIN || errno == EWOULDBLOCK)
-                throw WouldBlockError();
-            else
-                throw Error();
-#endif
-        }
-
-        return static_cast<unsigned>(nbread);
-    }
-
-    /**
-     * Send some data.
-     *
-     * \param data the data to send
-     * \param length the length
-     * \return the number of bytes sent
-     */
-    unsigned send(const void *data, unsigned length)
-    {
-        int max = length > INT_MAX ? INT_MAX : static_cast<int>(length);
-        int nbsent = ::send(this->m_handle, (ConstArg)data, max, 0);
-
-        if (nbsent == Failure) {
-#if defined(_WIN32)
-            int error = WSAGetLastError();
-
-            if (error == WSAEWOULDBLOCK)
-                throw WouldBlockError();
-            else
-                throw Error();
-#else
-            if (errno == EAGAIN || errno == EWOULDBLOCK)
-                throw WouldBlockError();
-            else
-                throw Error();
-#endif
-        }
-
-        return static_cast<unsigned>(nbsent);
-    }
-};
-
-/**
- * \brief Clear UDP type.
- *
- * This class is the basic implementation of UDP sockets.
- */
-class UdpSocket : public Socket {
-public:
-    /**
-     * Inherited constructors.
-     */
-    using Socket::Socket;
-
-    /**
-     * Construct a TCP socket.
-     *
-     * \param domain the domain
-     * \param protocol the protocol
-     * \throw Error on errors
-     */
-    inline UdpSocket(int domain, int protocol)
-        : Socket(domain, SOCK_DGRAM, protocol)
-    {
-    }
-
-    /**
-     * Get the type of the socket.
-     *
-     * \return the type
-     */
-    inline int type() const noexcept
-    {
-        return SOCK_DGRAM;
-    }
-
-    /**
-     * Receive some data.
-     *
-     * \param data the data
-     * \param length the length
-     * \param address the source address
-     * \param addrlen the source address in/out length
-     * \return the number of bytes received
-     * \throw WouldBlockError if the socket is marked non-blocking and the
-     * operation would block
-     * \throw Error on other errors
-     */
-    unsigned recvfrom(void *data, unsigned length, sockaddr *address, socklen_t *addrlen)
-    {
-        int max = length > INT_MAX ? INT_MAX : static_cast<int>(length);
-        int nbread = ::recvfrom(this->m_handle, (Arg)data, max, 0, address, addrlen);
-
-        if (nbread == Failure) {
-#if defined(_WIN32)
-            int error = WSAGetLastError();
-
-            if (error == EWOULDBLOCK)
-                throw WouldBlockError();
-            else
-                throw Error(error);
-#else
-            if (errno == EAGAIN || errno == EWOULDBLOCK)
-                throw WouldBlockError();
-            else
-                throw Error();
-#endif
-        }
-
-        return static_cast<unsigned>(nbread);
-    }
-
-    /**
-     * Overloaded function.
-     *
-     * \param data the data
-     * \param length the length
-     * \param source the source information (optional)
-     * \throw WouldBlockError if the socket is marked non-blocking and the
-     * operation would block
-     * \throw Error on other errors
-     */
-    inline unsigned recvfrom(void *data, unsigned length, Address *source = nullptr)
-    {
-        sockaddr_storage st;
-        socklen_t socklen = sizeof (sockaddr_storage);
-
-        auto nr = recvfrom(data, length, reinterpret_cast<sockaddr *>(&st), &socklen);
-
-        if (source)
-            *source = Address(reinterpret_cast<const sockaddr *>(&st), socklen);
-
-        return nr;
-    }
-
-    /**
-     * Send some data.
-     *
-     * \param data the data to send
-     * \param length the data length
-     * \param address the destination address
-     * \param addrlen the destination address length
-     * \return the number of bytes sent
-     * \throw WouldBlockError if the socket is marked non-blocking and the
-     * operation would block
-     * \throw Error on other errors
-     */
-    unsigned sendto(const void *data, unsigned length, const sockaddr *address, socklen_t addrlen)
-    {
-        int max = length > INT_MAX ? INT_MAX : static_cast<int>(length);
-        int nbsent = ::sendto(this->m_handle, (ConstArg)data, max, 0, address, addrlen);
-
-        if (nbsent == Failure) {
-#if defined(_WIN32)
-            int error = WSAGetLastError();
-
-            if (error == EWOULDBLOCK)
-                throw WouldBlockError();
-            else
-                throw Error(error);
-#else
-            if (errno == EAGAIN || errno == EWOULDBLOCK)
-                throw WouldBlockError();
-            else
-                throw Error();
-#endif
-        }
-
-        return static_cast<unsigned>(nbsent);
-    }
-
-    /**
-     * Overloaded function
-     *
-     * \param data the data to send
-     * \param length the data length
-     * \param address the destination address
-     * \return the number of bytes sent
-     * \throw WouldBlockError if the socket is marked non-blocking and the
-     * operation would block
-     * \throw Error on other errors
-     */
-    inline unsigned sendto(const void *data, unsigned length, const Address &address)
-    {
-        return sendto(data, length, address.get(), address.length());
-    }
-};
-
-#if !defined(NET_NO_SSL)
-
-/**
- * \brief Experimental TLS support.
- * \ingroup net-module-tls
- * \warning This class is highly experimental.
- */
-class TlsSocket : public Socket {
-public:
-    /**
-     * \brief SSL connection mode.
-     */
-    enum Mode {
-        Server,         //!< Use Server when you accept a socket server side,
-        Client          //!< Use Client when you connect to a server.
-    };
-
-private:
-    using Context = std::shared_ptr<SSL_CTX>;
-    using Ssl = std::unique_ptr<SSL, void (*)(SSL *)>;
-
-    // Determine if we created a TlsSocket from a temporary or a lvalue.
-    bool m_mustclose{false};
-
-    Context m_context;
-    Ssl m_ssl{nullptr, nullptr};
-
-    inline std::string error()
-    {
-        BIO *bio = BIO_new(BIO_s_mem());
-        char *buf = nullptr;
-
-        ERR_print_errors(bio);
-
-        std::size_t length = BIO_get_mem_data (bio, &buf);
-        std::string result(buf, length);
-
-        BIO_free(bio);
-
-        return result;
-    }
-
-    template <typename Function>
-    void wrap(Function &&function)
-    {
-        auto ret = function();
-
-        if (ret <= 0) {
-            int no = SSL_get_error(m_ssl.get(), ret);
-
-            switch (no) {
-            case SSL_ERROR_WANT_READ:
-                throw WantReadError();
-            case SSL_ERROR_WANT_WRITE:
-                throw WantWriteError();
-            default:
-                throw Error(error());
-            }
-        }
-    }
-
-    void create(Mode mode, const SSL_METHOD *method)
-    {
-#if !defined(NET_NO_SSL_AUTO_INIT)
-        ssl::init();
-#endif
-        m_context = Context(SSL_CTX_new(method), SSL_CTX_free);
-        m_ssl = Ssl(SSL_new(m_context.get()), SSL_free);
-
-        SSL_set_fd(m_ssl.get(), this->m_handle);
-
-        if (mode == Server)
-            SSL_set_accept_state(m_ssl.get());
-        else
-            SSL_set_connect_state(m_ssl.get());
-    }
-
-public:
-    /**
-     * Create a socket around an existing one.
-     *
-     * The original socket is moved to this instance and must not be used
-     * anymore.
-     *
-     * \param sock the TCP socket
-     * \param mode the mode
-     * \param method the method
-     */
-    TlsSocket(TcpSocket &&sock, Mode mode = Server, const SSL_METHOD *method = TLSv1_method())
-        : Socket(std::move(sock))
-        , m_mustclose(true)
-    {
-        create(mode, method);
-    }
-
-    /**
-     * Wrap a socket around an existing one without taking ownership.
-     *
-     * The original socket must still exist until this TlsSocket is closed.
-     *
-     * \param sock the TCP socket
-     * \param mode the mode
-     * \param method the method
-     */
-    TlsSocket(TcpSocket &sock, Mode mode = Server, const SSL_METHOD *method = TLSv1_method())
-        : Socket(sock.handle())
-    {
-        create(mode, method);
-    }
-
-    TlsSocket(TlsSocket &&) noexcept = default;
-    TlsSocket &operator=(TlsSocket &&) noexcept = default;
-
-    /**
-     * Destroy the socket if owned.
-     */
-    ~TlsSocket()
-    {
-        /**
-         * If the socket has been created from a rvalue this class owns the
-         * socket and will close it in the parent destructor.
-         *
-         * Otherwise, when created from a lvalue, mark this socket as invalid
-         * to avoid double close'ing it as two sockets points to the same
-         * descriptor.
-         */
-        if (!m_mustclose)
-            m_handle = Invalid;
-    }
-
-    /**
-     * Get the type of socket.
-     *
-     * \return the type
-     */
-    inline int type() const noexcept
-    {
-        return SOCK_STREAM;
-    }
-
-    /**
-     * Use the specified private key file.
-     *
-     * \param file the path to the private key
-     * \param type the type of file
-     */
-    inline void setPrivateKey(std::string file, int type = SSL_FILETYPE_PEM)
-    {
-        if (SSL_use_PrivateKey_file(m_ssl.get(), file.c_str(), type) != 1)
-            throw Error(error());
-    }
-
-    /**
-     * Use the specified certificate file.
-     *
-     * \param file the path to the file
-     * \param type the type of file
-     */
-    inline void setCertificate(std::string file, int type = SSL_FILETYPE_PEM)
-    {
-        if (SSL_use_certificate_file(m_ssl.get(), file.c_str(), type) != 1)
-            throw Error(error());
-    }
-
-    /**
-     * Do handshake, needed in some case when you have non blocking sockets.
-     */
-    void handshake()
-    {
-        wrap([&] () -> int {
-            return SSL_do_handshake(m_ssl.get());
-        });
-    }
-
-    /**
-     * Receive some data.
-     *
-     * \param data the destination buffer
-     * \param length the buffer length
-     * \return the number of bytes received
-     */
-    unsigned recv(void *data, unsigned length)
-    {
-        int max = length > INT_MAX ? INT_MAX : static_cast<int>(length);
-        int nbread = 0;
-
-        wrap([&] () -> int {
-            return (nbread = SSL_read(m_ssl.get(), data, max));
-        });
-
-        return static_cast<unsigned>(nbread < 0 ? 0 : nbread);
-    }
-
-    /**
-     * Send some data.
-     *
-     * \param data the data to send
-     * \param length the length
-     * \return the number of bytes sent
-     */
-    unsigned send(const void *data, unsigned length)
-    {
-        int max = length > INT_MAX ? INT_MAX : static_cast<int>(length);
-        int nbsent = 0;
-
-        wrap([&] () -> int {
-            return (nbsent = SSL_write(m_ssl.get(), data, max));
-        });
-
-        return static_cast<unsigned>(nbsent < 0 ? 0 : nbsent);
-    }
-};
-
-#endif // !NET_NO_SSL
-
-/**
- * \brief IPv4 functions.
- */
-namespace ipv4 {
-
-/**
- * Create an address to bind on any.
- *
- * \param port the port
- * \return the address
- */
-inline Address any(std::uint16_t port)
-{
-    sockaddr_in sin;
-    socklen_t length = sizeof (sockaddr_in);
-
-    std::memset(&sin, 0, sizeof (sockaddr_in));
-    sin.sin_family = AF_INET;
-    sin.sin_addr.s_addr = INADDR_ANY;
-    sin.sin_port = htons(port);
-
-    return Address(reinterpret_cast<const sockaddr *>(&sin), length);
-}
-
-/**
- * Create an address from a IPv4 string.
- *
- * \param ip the ip address
- * \param port the port
- * \return the address
- * \throw Error if inet_pton is unavailable
- */
-inline Address pton(const std::string &ip, std::uint16_t port)
-{
-#if defined(NET_HAVE_INET_PTON)
-#if !defined(NET_NO_AUTO_INIT)
-    init();
-#endif
-
-    sockaddr_in sin;
-    socklen_t length = sizeof (sockaddr_in);
-
-    std::memset(&sin, 0, sizeof (sockaddr_in));
-    sin.sin_family = AF_INET;
-    sin.sin_port = htons(port);
-
-    if (inet_pton(AF_INET, ip.c_str(), &sin.sin_addr) <= 0)
-        throw Error();
-
-    return Address(reinterpret_cast<const sockaddr *>(&sin), length);
-#else
-    (void)ip;
-    (void)port;
-
-    throw Error(std::strerror(ENOSYS));
-#endif
-}
-
-/**
- * Get the underlying ip from the given address.
- *
- * \pre address.domain() == AF_INET
- * \param address the IPv6 address
- * \return the ip address
- * \throw Error if inet_ntop is unavailable
- */
-inline std::string ntop(const Address &address)
-{
-    assert(address.domain() == AF_INET);
-
-#if !defined(NET_NO_AUTO_INIT)
-    init();
-#endif
-
-#if defined(NET_HAVE_INET_NTOP)
-    char result[INET_ADDRSTRLEN + 1];
-
-    std::memset(result, 0, sizeof (result));
-
-    if (!inet_ntop(AF_INET, const_cast<in_addr *>(&address.as<sockaddr_in>().sin_addr), result, sizeof (result)))
-        throw Error();
-
-    return result;
-#else
-    (void)address;
-
-    throw Error(std::strerror(ENOSYS));
-#endif
-}
-
-/**
- * Get the port from the IPv4 address.
- *
- * \pre address.domain() == AF_INET4
- * \param address the address
- * \return the port
- */
-inline std::uint16_t port(const Address &address) noexcept
-{
-    assert(address.domain() == AF_INET);
-
-    return ntohs(address.as<sockaddr_in>().sin_port);
-}
-
-} // !ipv4
-
-/**
- * \brief IPv6 functions.
- */
-namespace ipv6 {
-
-/**
- * Create an address to bind on any.
- *
- * \param port the port
- * \return the address
- */
-inline Address any(std::uint16_t port)
-{
-    sockaddr_in6 sin6;
-    socklen_t length = sizeof (sockaddr_in6);
-
-    std::memset(&sin6, 0, sizeof (sockaddr_in6));
-    sin6.sin6_family = AF_INET6;
-    sin6.sin6_addr = in6addr_any;
-    sin6.sin6_port = htons(port);
-
-    return Address(reinterpret_cast<const sockaddr *>(&sin6), length);
-}
-
-/**
- * Create an address from a IPv4 string.
- *
- * \param ip the ip address
- * \param port the port
- * \return the address
- * \throw Error if inet_pton is unavailable
- */
-inline Address pton(const std::string &ip, std::uint16_t port)
-{
-#if defined(NET_HAVE_INET_PTON)
-#if !defined(NET_NO_AUTO_INIT)
-    init();
-#endif
-
-    sockaddr_in6 sin6;
-    socklen_t length = sizeof (sockaddr_in6);
-
-    std::memset(&sin6, 0, sizeof (sockaddr_in6));
-    sin6.sin6_family = AF_INET6;
-    sin6.sin6_port = htons(port);
-
-    if (inet_pton(AF_INET6, ip.c_str(), &sin6.sin6_addr) <= 0)
-        throw Error();
-
-    return Address(reinterpret_cast<const sockaddr *>(&sin6), length);
-#else
-    (void)ip;
-    (void)port;
-
-    throw Error(std::strerror(ENOSYS));
-#endif
-}
-
-/**
- * Get the underlying ip from the given address.
- *
- * \pre address.domain() == AF_INET6
- * \param address the IPv6 address
- * \return the ip address
- * \throw Error if inet_ntop is unavailable
- */
-inline std::string ntop(const Address &address)
-{
-    assert(address.domain() == AF_INET6);
-
-#if defined(NET_HAVE_INET_NTOP)
-#if !defined(NET_NO_AUTO_INIT)
-    init();
-#endif
-
-    char ret[INET6_ADDRSTRLEN];
-
-    std::memset(ret, 0, sizeof (ret));
-
-    if (!inet_ntop(AF_INET6, const_cast<in6_addr *>(&address.as<sockaddr_in6>().sin6_addr), ret, sizeof (ret)))
-        throw Error();
-
-    return ret;
-#else
-    (void)address;
-
-    throw Error(std::strerror(ENOSYS));
-#endif
-}
-
-/**
- * Get the port from the IPv6 address.
- *
- * \pre address.domain() == AF_INET6
- * \param address the address
- * \return the port
- */
-inline std::uint16_t port(const Address &address) noexcept
-{
-    assert(address.domain() == AF_INET6);
-
-    return ntohs(address.as<sockaddr_in6>().sin6_port);
-}
-
-} // !ipv6
-
-#if !defined(_WIN32)
-
-/**
- * \brief Unix domain functions.
- */
-namespace local {
-
-/**
- * Construct an address to a path.
- *
- * \pre !path.empty()
- * \param path the path
- * \param rm remove the file before (default: false)
- */
-inline Address create(const std::string &path, bool rm = false) noexcept
-{
-    assert(!path.empty());
-
-    // Silently remove the file even if it fails.
-    if (rm)
-        remove(path.c_str());
-
-    sockaddr_un sun;
-    socklen_t length;
-
-    std::memset(sun.sun_path, 0, sizeof (sun.sun_path));
-    std::strncpy(sun.sun_path, path.c_str(), sizeof (sun.sun_path) - 1);
-
-    sun.sun_family = AF_LOCAL;
-
-#if defined(NET_HAVE_SUN_LEN)
-    length = SUN_LEN(&sun);
-#else
-    length = sizeof (sun);
-#endif
-
-    return Address(reinterpret_cast<const sockaddr *>(&sun), length);
-}
-
-/**
- * Get the path from the address.
- *
- * \pre address.domain() == AF_LOCAL
- * \param address the local address
- * \return the path to the socket file
- */
-inline std::string path(const Address &address)
-{
-    assert(address.domain() == AF_LOCAL);
-
-    return reinterpret_cast<const sockaddr_un *>(address.get())->sun_path;
-}
-
-} // !local
-
-#endif // !_WIN32
-
-/**
- * \brief Predefined options.
- */
-namespace option {
-
-/**
- * \ingroup net-module-options
- * \brief Set or get the blocking-mode for a socket.
- * \warning On Windows, it's not possible to check if the socket is blocking or
- * not.
- */
-class SockBlockMode {
-private:
-    bool m_value;
-
-public:
-    /**
-     * Create the option.
-     *
-     * By default the blocking mode is set to true.
-     *
-     * \param value set to true to make blocking sockets
-     */
-    inline SockBlockMode(bool value = true) noexcept
-        : m_value(value)
-    {
-    }
-
-    /**
-     * Set the option.
-     *
-     * \param sc the socket
-     * \throw Error on errors
-     */
-    void set(Socket &sc) const
-    {
-#if defined(O_NONBLOCK) && !defined(_WIN32)
-        int flags;
-
-        if ((flags = fcntl(sc.handle(), F_GETFL, 0)) < 0)
-            flags = 0;
-
-        if (m_value)
-            flags &= ~(O_NONBLOCK);
-        else
-            flags |= O_NONBLOCK;
-
-        if (fcntl(sc.handle(), F_SETFL, flags) < 0)
-            throw Error();
-#else
-        unsigned long flags = (m_value) ? 0 : 1;
-
-        if (ioctlsocket(sc.handle(), FIONBIO, &flags) == Failure)
-            throw Error();
-#endif
-    }
-
-    /**
-     * Get the option.
-     *
-     * \param sc the socket
-     * \return the value
-     * \throw Error on errors
-     */
-    bool get(Socket &sc) const
-    {
-#if defined(O_NONBLOCK) && !defined(_WIN32)
-        int flags = fcntl(sc.handle(), F_GETFL, 0);
-
-        if (flags < 0)
-            throw Error();
-
-        return !(flags & O_NONBLOCK);
-#else
-        (void)sc;
-
-        throw Error(std::strerror(ENOSYS));
-#endif
-    }
-};
-
-/**
- * \ingroup net-module-options
- * \brief Set or get the input buffer.
- */
-class SockReceiveBuffer {
-private:
-    int m_value;
-
-public:
-    /**
-     * Create the option.
-     *
-     * \param size the buffer size
-     */
-    inline SockReceiveBuffer(int size = 2048) noexcept
-        : m_value(size)
-    {
-    }
-
-    /**
-     * Set the option.
-     *
-     * \param sc the socket
-     * \throw Error on errors
-     */
-    inline void set(Socket &sc) const
-    {
-        sc.set(SOL_SOCKET, SO_RCVBUF, m_value);
-    }
-
-    /**
-     * Get the option.
-     *
-     * \param sc the socket
-     * \return the value
-     * \throw Error on errors
-     */
-    inline int get(Socket &sc) const
-    {
-        return sc.get<int>(SOL_SOCKET, SO_RCVBUF);
-    }
-};
-
-/**
- * \ingroup net-module-options
- * \brief Reuse address, must be used before calling Socket::bind
- */
-class SockReuseAddress {
-private:
-    bool m_value;
-
-public:
-    /**
-     * Create the option.
-     *
-     * By default the option reuses the address.
-     *
-     * \param value set to true to reuse the address
-     */
-    inline SockReuseAddress(bool value = true) noexcept
-        : m_value(value)
-    {
-    }
-
-    /**
-     * Set the option.
-     *
-     * \param sc the socket
-     * \throw Error on errors
-     */
-    inline void set(Socket &sc) const
-    {
-        sc.set(SOL_SOCKET, SO_REUSEADDR, m_value ? 1 : 0);
-    }
-
-    /**
-     * Get the option.
-     *
-     * \param sc the socket
-     * \return the value
-     * \throw Error on errors
-     */
-    inline bool get(Socket &sc) const
-    {
-        return sc.get<int>(SOL_SOCKET, SO_REUSEADDR) != 0;
-    }
-};
-
-/**
- * \ingroup net-module-options
- * \brief Set or get the output buffer.
- */
-class SockSendBuffer {
-private:
-    int m_value;
-
-public:
-    /**
-     * Create the option.
-     *
-     * \param size the buffer size
-     */
-    inline SockSendBuffer(int size = 2048) noexcept
-        : m_value(size)
-    {
-    }
-
-    /**
-     * Set the option.
-     *
-     * \param sc the socket
-     * \throw Error on errors
-     */
-    inline void set(Socket &sc) const
-    {
-        sc.set(SOL_SOCKET, SO_SNDBUF, m_value);
-    }
-
-    /**
-     * Get the option.
-     *
-     * \param sc the socket
-     * \return the value
-     * \throw Error on errors
-     */
-    inline int get(Socket &sc) const
-    {
-        return sc.get<int>(SOL_SOCKET, SO_SNDBUF);
-    }
-};
-
-/**
- * \ingroup net-module-options
- * \brief Set this option if you want to disable nagle's algorithm.
- */
-class TcpNoDelay {
-private:
-    bool m_value;
-
-public:
-    /**
-     * Create the option.
-     *
-     * By default disable TCP delay.
-     *
-     * \param value set to true to disable TCP delay
-     */
-    inline TcpNoDelay(bool value = true) noexcept
-        : m_value(value)
-    {
-    }
-
-    /**
-     * Set the option.
-     *
-     * \param sc the socket
-     * \throw Error on errors
-     */
-    inline void set(Socket &sc) const
-    {
-        sc.set(IPPROTO_TCP, TCP_NODELAY, m_value ? 1 : 0);
-    }
-
-    /**
-     * Get the option.
-     *
-     * \param sc the socket
-     * \return the value
-     * \throw Error on errors
-     */
-    inline bool get(Socket &sc) const
-    {
-        return sc.get<int>(IPPROTO_TCP, TCP_NODELAY) != 0;
-    }
-};
-
-/**
- * \ingroup net-module-options
- * \brief Control IPPROTO_IPV6/IPV6_V6ONLY
- *
- * Note: some systems may or not set this option by default so it's a good idea
- * to set it in any case to either
- * false or true if portability is a concern.
- */
-class Ipv6Only {
-private:
-    bool m_value;
-
-public:
-    /**
-     * Create the option.
-     *
-     * By default with want IPv6 only.
-     *
-     * \param value set to true to use IPv6 only
-     */
-    inline Ipv6Only(bool value = true) noexcept
-        : m_value(value)
-    {
-    }
-
-    /**
-     * Set the option.
-     *
-     * \param sc the socket
-     * \throw Error on errors
-     */
-    inline void set(Socket &sc) const
-    {
-        sc.set(IPPROTO_IPV6, IPV6_V6ONLY, m_value ? 1 : 0);
-    }
-
-    /**
-     * Get the option.
-     *
-     * \param sc the socket
-     * \return the value
-     * \throw Error on errors
-     */
-    inline bool get(Socket &sc) const
-    {
-        return sc.get<int>(IPPROTO_IPV6, IPV6_V6ONLY) != 0;
-    }
-};
-
-} // !option
-
-/**
- * \brief Result of polling
- *
- * Result of a select call, returns the first ready socket found with its
- * flags.
- */
-class ListenerStatus {
-public:
-    Handle socket;              //!< which socket is ready
-    Condition flags;            //!< the flags
-};
-
-/**
- * Table used in the socket listener to store which sockets have been
- * set in which directions.
- */
-using ListenerTable = std::unordered_map<Handle, Condition>;
-
-/**
- * \brief Predefined backends for Listener.
- */
-namespace backend {
-
-#if defined(NET_HAVE_EPOLL)
-
-/**
- * \ingroup net-module-backends
- * \brief Linux's epoll.
- */
-class Epoll {
-private:
-    int m_handle{-1};
-    std::vector<epoll_event> m_events;
-
-    Epoll(const Epoll &) = delete;
-    Epoll &operator=(const Epoll &) = delete;
-
-    std::uint32_t toEpoll(Condition condition) const noexcept
-    {
-        std::uint32_t events = 0;
-
-        if ((condition & Condition::Readable) == Condition::Readable)
-            events |= EPOLLIN;
-        if ((condition & Condition::Writable) == Condition::Writable)
-            events |= EPOLLOUT;
-
-        return events;
-    }
-
-    Condition toCondition(std::uint32_t events) const noexcept
-    {
-        Condition condition = Condition::None;
-
-        if ((events & EPOLLIN) || (events & EPOLLHUP))
-            condition |= Condition::Readable;
-        if (events & EPOLLOUT)
-            condition |= Condition::Writable;
-
-        return condition;
-    }
-
-    void update(Handle h, int op, int eflags)
-    {
-        epoll_event ev;
-
-        std::memset(&ev, 0, sizeof (epoll_event));
-
-        ev.events = eflags;
-        ev.data.fd = h;
-
-        if (epoll_ctl(m_handle, op, h, &ev) < 0)
-            throw Error();
-    }
-
-public:
-    /**
-     * Create epoll.
-     *
-     * \throw Error on failures
-     */
-    inline Epoll()
-        : m_handle(epoll_create1(0))
-    {
-        if (m_handle < 0)
-            throw Error();
-    }
-
-    /**
-     * Move constructor.
-     *
-     * \param other the other backend
-     */
-    inline Epoll(Epoll &&other) noexcept
-        : m_handle(other.m_handle)
-    {
-        other.m_handle = -1;
-    }
-
-    /**
-     * Close the kqueue descriptor.
-     */
-    inline ~Epoll()
-    {
-        if (m_handle != -1)
-            close(m_handle);
-    }
-
-    /**
-     * Get the backend name.
-     *
-     * \return kqueue
-     */
-    inline std::string name() const noexcept
-    {
-        return "epoll";
-    }
-
-    /**
-     * For set and unset, we need to apply the whole flags required, so if the
-     * socket was set to Connection::Readable and user **adds**
-     * Connection::Writable, we must set both.
-     *
-     * \param table the listener table
-     * \param h the handle
-     * \param condition the condition
-     * \param add set to true if the socket is new to the backend
-     * \throw Error on failures
-     */
-    void set(const ListenerTable &table, Handle h, Condition condition, bool add)
-    {
-        if (add) {
-            update(h, EPOLL_CTL_ADD, toEpoll(condition));
-            m_events.resize(m_events.size() + 1);
-        } else
-            update(h, EPOLL_CTL_MOD, toEpoll(table.at(h) | condition));
-    }
-
-    /**
-     * Unset is a bit complicated case because Listener tells us which
-     * flag to remove but to update epoll descriptor we need to pass
-     * the effective flags that we want to be applied.
-     *
-     * So we put the same flags that are currently effective and remove the
-     * requested one.
-     *
-     * \param table the listener table
-     * \param h the handle
-     * \param condition the condition
-     * \param add set to true if the socket is new to the backend
-     * \throw Error on failures
-     */
-    void unset(const ListenerTable &table, Handle h, Condition condition, bool remove)
-    {
-        if (remove) {
-            update(h, EPOLL_CTL_DEL, 0);
-            m_events.resize(m_events.size() - 1);
-        } else
-            update(h, EPOLL_CTL_MOD, toEpoll(table.at(h) & ~(condition)));
-    }
-
-    /**
-     * Wait for sockets to be ready.
-     *
-     * \param ms the milliseconds timeout
-     * \return the sockets ready
-     * \throw Error on failures
-     */
-    std::vector<ListenerStatus> wait(const ListenerTable &, int ms)
-    {
-        int ret = epoll_wait(m_handle, m_events.data(), m_events.size(), ms);
-        std::vector<ListenerStatus> result;
-
-        if (ret == 0)
-            throw TimeoutError();
-        if (ret < 0)
-            throw Error();
-
-        for (int i = 0; i < ret; ++i)
-            result.push_back(ListenerStatus{m_events[i].data.fd, toCondition(m_events[i].events)});
-
-        return result;
-    }
-
-    /**
-     * Move operator.
-     *
-     * \param other the other
-     * \return this
-     */
-    inline Epoll &operator=(Epoll &&other)
-    {
-        m_handle = other.m_handle;
-        other.m_handle = -1;
-
-        return *this;
-    }
-};
-
-#endif // !NET_HAVE_EPOLL
-
-#if defined(NET_HAVE_KQUEUE)
-
-/**
- * \ingroup net-module-backends
- * \brief Implements kqueue(2).
- *
- * This implementation is available on all BSD and Mac OS X. It is better than
- * poll(2) because it's O(1), however it's a bit more memory consuming.
- */
-class Kqueue {
-private:
-    std::vector<struct kevent> m_result;
-    int m_handle;
-
-    Kqueue(const Kqueue &) = delete;
-    Kqueue &operator=(const Kqueue &) = delete;
-
-    void update(Handle h, int filter, int kflags)
-    {
-        struct kevent ev;
-
-        EV_SET(&ev, h, filter, kflags, 0, 0, nullptr);
-
-        if (kevent(m_handle, &ev, 1, nullptr, 0, nullptr) < 0)
-            throw Error();
-    }
-
-public:
-    /**
-     * Create kqueue.
-     *
-     * \throw Error on failures
-     */
-    inline Kqueue()
-        : m_handle(kqueue())
-    {
-        if (m_handle < 0)
-            throw Error();
-    }
-
-    /**
-     * Move constructor.
-     *
-     * \param other the other backend
-     */
-    inline Kqueue(Kqueue &&other) noexcept
-        : m_handle(other.m_handle)
-    {
-        other.m_handle = -1;
-    }
-
-    /**
-     * Close the kqueue descriptor.
-     */
-    inline ~Kqueue()
-    {
-        if (m_handle != -1)
-            close(m_handle);
-    }
-
-    /**
-     * Get the backend name.
-     *
-     * \return kqueue
-     */
-    inline std::string name() const noexcept
-    {
-        return "kqueue";
-    }
-
-    /**
-     * Set socket.
-     *
-     * \param h the handle
-     * \param condition the condition
-     * \param add set to true if the socket is new to the backend
-     * \throw Error on failures
-     */
-    void set(const ListenerTable &, Handle h, Condition condition, bool add)
-    {
-        if ((condition & Condition::Readable) == Condition::Readable)
-            update(h, EVFILT_READ, EV_ADD | EV_ENABLE);
-        if ((condition & Condition::Writable) == Condition::Writable)
-            update(h, EVFILT_WRITE, EV_ADD | EV_ENABLE);
-        if (add)
-            m_result.resize(m_result.size() + 1);
-    }
-
-    /**
-     * Unset socket.
-     *
-     * \param h the handle
-     * \param condition the condition
-     * \param remove set to true if the socket is completely removed
-     * \throw Error on failures
-     */
-    void unset(const ListenerTable &, Handle h, Condition condition, bool remove)
-    {
-        if ((condition & Condition::Readable) == Condition::Readable)
-            update(h, EVFILT_READ, EV_DELETE);
-        if ((condition & Condition::Writable) == Condition::Writable)
-            update(h, EVFILT_WRITE, EV_DELETE);
-        if (remove)
-            m_result.resize(m_result.size() - 1);
-    }
-
-    /**
-     * Wait for sockets to be ready.
-     *
-     * \param ms the milliseconds timeout
-     * \return the sockets ready
-     * \throw Error on failures
-     */
-    std::vector<ListenerStatus> wait(const ListenerTable &, int ms)
-    {
-        std::vector<ListenerStatus> sockets;
-        timespec ts = { 0, 0 };
-        timespec *pts = (ms <= 0) ? nullptr : &ts;
-
-        ts.tv_sec = ms / 1000;
-        ts.tv_nsec = (ms % 1000) * 1000000;
-
-        int nevents = kevent(m_handle, nullptr, 0, &m_result[0], m_result.capacity(), pts);
-
-        if (nevents == 0)
-            throw TimeoutError();
-        if (nevents < 0)
-            throw Error();
-
-        for (int i = 0; i < nevents; ++i) {
-            sockets.push_back(ListenerStatus{
-                static_cast<Handle>(m_result[i].ident),
-                m_result[i].filter == EVFILT_READ ? Condition::Readable : Condition::Writable
-            });
-        }
-
-        return sockets;
-    }
-
-    /**
-     * Move operator.
-     *
-     * \param other the other
-     * \return this
-     */
-    inline Kqueue &operator=(Kqueue &&other) noexcept
-    {
-        m_handle = other.m_handle;
-        other.m_handle = -1;
-
-        return *this;
-    }
-};
-
-#endif // !NET_HAVE_KQUEUE
-
-#if defined(NET_HAVE_POLL)
-
-/**
- * \ingroup net-module-backends
- * \brief Implements poll(2).
- *
- * Poll is widely supported and is better than select(2). It is still not the
- * best option as selecting the sockets is O(n).
- */
-class Poll {
-private:
-    std::vector<pollfd> m_fds;
-
-    short toPoll(Condition condition) const noexcept
-    {
-        short result = 0;
-
-        if ((condition & Condition::Readable) == Condition::Readable)
-            result |= POLLIN;
-        if ((condition & Condition::Writable) == Condition::Writable)
-            result |= POLLOUT;
-
-        return result;
-    }
-
-    Condition toCondition(short &event) const noexcept
-    {
-        Condition condition = Condition::None;
-
-        /*
-         * Poll implementations mark the socket differently regarding the
-         * disconnection of a socket.
-         *
-         * At least, even if POLLHUP or POLLIN is set, recv() always return 0 so
-         * we mark the socket as readable.
-         */
-        if ((event & POLLIN) || (event & POLLHUP))
-            condition |= Condition::Readable;
-        if (event & POLLOUT)
-            condition |= Condition::Writable;
-
-        // Reset event for safety.
-        event = 0;
-
-        return condition;
-    }
-
-public:
-    /**
-     * Get the backend name.
-     *
-     * \return kqueue
-     */
-    inline std::string name() const noexcept
-    {
-        return "poll";
-    }
-
-    /**
-     * Set socket.
-     *
-     * \param h the handle
-     * \param condition the condition
-     * \param add set to true if the socket is new to the backend
-     * \throw Error on failures
-     */
-    void set(const ListenerTable &, Handle h, Condition condition, bool add)
-    {
-        if (add)
-            m_fds.push_back(pollfd{h, toPoll(condition), 0});
-        else {
-            auto it = std::find_if(m_fds.begin(), m_fds.end(), [&] (const pollfd &pfd) {
-                return pfd.fd == h;
-            });
-
-            it->events |= toPoll(condition);
-        }
-    }
-
-    /**
-     * Unset socket.
-     *
-     * \param h the handle
-     * \param condition the condition
-     * \param remove set to true if the socket is completely removed
-     * \throw Error on failures
-     */
-    void unset(const ListenerTable &, Handle h, Condition condition, bool remove)
-    {
-        auto it = std::find_if(m_fds.begin(), m_fds.end(), [&] (const pollfd &pfd) {
-            return pfd.fd == h;
-        });
-
-        if (remove)
-            m_fds.erase(it);
-        else
-            it->events &= ~(toPoll(condition));
-    }
-
-    /**
-     * Wait for sockets to be ready.
-     *
-     * \param ms the milliseconds timeout
-     * \return the sockets ready
-     * \throw Error on failures
-     */
-    std::vector<ListenerStatus> wait(const ListenerTable &, int ms)
-    {
-#if defined(_WIN32)
-        auto result = WSAPoll(m_fds.data(), (ULONG)m_fds.size(), ms);
-#else
-        auto result = poll(m_fds.data(), m_fds.size(), ms);
-#endif
-
-        if (result == 0)
-            throw TimeoutError();
-        if (result < 0)
-            throw Error();
-
-        std::vector<ListenerStatus> sockets;
-
-        for (auto &fd : m_fds)
-            if (fd.revents != 0)
-                sockets.push_back(ListenerStatus{fd.fd, toCondition(fd.revents)});
-
-        return sockets;
-    }
-};
-
-#endif // !NET_HAVE_POLL
-
-/**
- * \ingroup net-module-backends
- * \brief Implements select(2)
- *
- * This class is the fallback of any other method, it is not preferred at all
- * for many reasons.
- */
-class Select {
-public:
-    /**
-     * Get the backend name.
-     *
-     * \return select
-     */
-    inline std::string name() const
-    {
-        return "select";
-    }
-
-    /**
-     * No-op.
-     */
-    inline void set(const ListenerTable &, Handle, Condition, bool) noexcept
-    {
-    }
-
-    /**
-     * No-op.
-     */
-    inline void unset(const ListenerTable &, Handle, Condition, bool) noexcept
-    {
-    }
-
-    /**
-     * Wait for sockets to be ready.
-     *
-     * \param table the listener table
-     * \param ms the milliseconds timeout
-     * \return the sockets ready
-     * \throw Error on failures
-     */
-    std::vector<ListenerStatus> wait(const ListenerTable &table, int ms)
-    {
-        timeval maxwait, *towait;
-        fd_set readset;
-        fd_set writeset;
-
-        FD_ZERO(&readset);
-        FD_ZERO(&writeset);
-
-        Handle max = 0;
-
-        for (const auto &pair : table) {
-            if ((pair.second & Condition::Readable) == Condition::Readable)
-                FD_SET(pair.first, &readset);
-            if ((pair.second & Condition::Writable) == Condition::Writable)
-                FD_SET(pair.first, &writeset);
-            if (pair.first > max)
-                max = pair.first;
-        }
-
-        maxwait.tv_sec = 0;
-        maxwait.tv_usec = ms * 1000;
-
-        // Set to nullptr for infinite timeout.
-        towait = (ms < 0) ? nullptr : &maxwait;
-
-        auto error = ::select(static_cast<int>(max + 1), &readset, &writeset, nullptr, towait);
-
-        if (error == Failure)
-            throw Error();
-        if (error == 0)
-            throw TimeoutError();
-
-        std::vector<ListenerStatus> sockets;
-
-        for (const auto &pair : table) {
-            if (FD_ISSET(pair.first, &readset))
-                sockets.push_back(ListenerStatus{pair.first, Condition::Readable});
-            if (FD_ISSET(pair.first, &writeset))
-                sockets.push_back(ListenerStatus{pair.first, Condition::Writable});
-        }
-
-        return sockets;
-    }
-};
-
-} // !backend
-
-/**
- * \brief Synchronous multiplexing
- *
- * Convenient wrapper around the select() system call.
- *
- * This class is implemented using a bridge pattern to allow different uses
- * of listener implementation.
- *
- * You should not reinstanciate a new Listener at each iteartion of your
- * main loop as it can be extremely costly. Instead use the same listener that
- * you can safely modify on the fly.
- *
- * Currently, poll, epoll, select and kqueue are available.
- */
-template <typename Backend = backend :: NET_DEFAULT_BACKEND>
-class Listener {
-private:
-    Backend m_backend;
-    ListenerTable m_table;
-
-public:
-    /**
-     * Construct an empty listener.
-     */
-    Listener() = default;
-
-    /**
-     * Get the backend.
-     *
-     * \return the backend
-     */
-    inline const Backend &backend() const noexcept
-    {
-        return m_backend;
-    }
-
-    /**
-     * Overloaded function.
-     *
-     * \return the backend
-     */
-    inline Backend &backend() noexcept
-    {
-        return m_backend;
-    }
-
-    /**
-     * Get the non-modifiable table.
-     *
-     * \return the table
-     */
-    inline const ListenerTable &table() const noexcept
-    {
-        return m_table;
-    }
-
-    /**
-     * Overloaded function.
-     *
-     * \return the iterator
-     */
-    inline ListenerTable::const_iterator begin() const noexcept
-    {
-        return m_table.begin();
-    }
-
-    /**
-     * Overloaded function.
-     *
-     * \return the iterator
-     */
-    inline ListenerTable::const_iterator cbegin() const noexcept
-    {
-        return m_table.cbegin();
-    }
-
-    /**
-     * Overloaded function.
-     *
-     * \return the iterator
-     */
-    inline ListenerTable::const_iterator end() const noexcept
-    {
-        return m_table.end();
-    }
-
-    /**
-     * Overloaded function.
-     *
-     * \return the iterator
-     */
-    inline ListenerTable::const_iterator cend() const noexcept
-    {
-        return m_table.cend();
-    }
-
-    /**
-     * Add or update a socket to the listener.
-     *
-     * If the socket is already placed with the appropriate flags, the
-     * function is a no-op.
-     *
-     * If incorrect flags are passed, the function does nothing.
-     *
-     * Previous flags are discarded.
-     *
-     * \param sc the socket
-     * \param condition the condition (may be OR'ed)
-     * \throw Error if the backend failed to set
-     */
-    void reset(Handle sc, Condition condition)
-    {
-        if (condition == Condition::None || static_cast<int>(condition) > 0x3)
-            return;
-
-        auto it = m_table.find(sc);
-
-        // Do not update the table if the backend failed to add or update.
-        if (it == m_table.end()) {
-            m_backend.set(m_table, sc, condition, true);
-            m_table.emplace(sc, condition);
-        } else {
-            /*
-             * In this scenario, the socket exist in the registry with at least
-             * one flag, the user may call set with read, write or both flags.
-             *
-             * If one of Readable or Writable is requested, we remove the
-             * opposite one if present.
-             *
-             * If both are requested, we add the missing one.
-             */
-            auto remove = it->second & ~(condition);
-
-            if (remove != Condition::None) {
-                m_backend.unset(m_table, sc, remove, false);
-                it->second &= ~(remove);
-            }
-
-            auto apply = it->second ^ condition;
-
-            if (apply != Condition::None) {
-                m_backend.set(m_table, sc, it->second ^ condition, false);
-                it->second |= (it->second ^ condition);
-            }
-        }
-    }
-
-    /**
-     * Remove one or more flags from the listener for the given socket.
-     *
-     * It's perfectly safe to try removing a flag that is not currently set, the
-     * listener simply ignores them.
-     *
-     * If the socket is not in the registry, this function is a no-op.
-     *
-     * \param sc the socket
-     * \param condition the condition (may be OR'ed)
-     * \see remove
-     */
-    void unset(Handle sc, Condition condition)
-    {
-        if (condition == Condition::None || static_cast<int>(condition) > 0x3)
-            return;
-
-        auto it = m_table.find(sc);
-
-        if (it == m_table.end())
-            return;
-
-        // Remove only present flags.
-        condition = it->second & condition;
-
-        if (condition == Condition::None)
-            return;
-
-        /*
-         * Determine if we should completely remove the socket from the table if
-         * condition once remove is none.
-         */
-        bool removal = (it->second & ~(condition)) == Condition::None;
-
-        m_backend.unset(m_table, sc, condition, removal);
-
-        if (removal)
-            m_table.erase(it);
-        else
-            it->second &= ~(condition);
-    }
-
-    /**
-     * Remove completely the socket from the listener.
-     *
-     * It is a shorthand for unset(sc, Condition::Readable |
-     * Condition::Writable);
-     *
-     * \param sc the socket
-     */
-    inline void remove(Handle sc)
-    {
-        unset(sc, Condition::Readable | Condition::Writable);
-    }
-
-    /**
-     * Remove all sockets.
-     */
-    inline void clear()
-    {
-        while (!m_table.empty())
-            remove(m_table.begin()->first);
-    }
-
-    /**
-     * Get the number of sockets in the listener.
-     *
-     * \return the number of sockets
-     */
-    inline ListenerTable::size_type size() const noexcept
-    {
-        return m_table.size();
-    }
-
-    /**
-     * Select a socket. Waits for a specific amount of time specified as the
-     * duration.
-     *
-     * \param duration the duration
-     * \return the socket ready
-     */
-    template <typename Rep, typename Ratio>
-    inline ListenerStatus wait(const std::chrono::duration<Rep, Ratio> &duration)
-    {
-        auto cvt = std::chrono::duration_cast<std::chrono::milliseconds>(duration);
-        auto max = cvt.count() > INT_MAX ? INT_MAX : static_cast<int>(cvt.count());
-
-        return m_backend.wait(m_table, max)[0];
-    }
-
-    /**
-     * Overload with milliseconds.
-     *
-     * \param timeout the optional timeout in milliseconds
-     * \return the socket ready
-     */
-    inline ListenerStatus wait(long long int timeout = -1)
-    {
-        return wait(std::chrono::milliseconds(timeout));
-    }
-
-    /**
-     * Select multiple sockets.
-     *
-     * \param duration the duration
-     * \return the socket ready
-     */
-    template <typename Rep, typename Ratio>
-    inline std::vector<ListenerStatus> waitMultiple(const std::chrono::duration<Rep, Ratio> &duration)
-    {
-        auto cvt = std::chrono::duration_cast<std::chrono::milliseconds>(duration);
-
-        return m_backend.wait(m_table, cvt.count());
-    }
-
-    /**
-     * Overload with milliseconds.
-     *
-     * \param timeout the optional timeout in milliseconds
-     * \return the socket ready
-     */
-    inline std::vector<ListenerStatus> waitMultiple(int timeout = -1)
-    {
-        return waitMultiple(std::chrono::milliseconds(timeout));
-    }
-};
-
-/**
- * \ingroup net-module-resolv
- *
- * Resolve an hostname immediately.
- *
- * \param host the hostname
- * \param service the service (e.g. http or port number)
- * \param domain the domain (e.g. AF_INET)
- * \param type the type (e.g. SOCK_STREAM)
- * \return the address iterator
- * \throw Error on failures
- */
-inline AddressIterator resolve(const std::string &host,
-                               const std::string &service,
-                               int domain = AF_UNSPEC,
-                               int type = 0)
-{
-#if !defined(NET_NO_AUTO_INIT)
-        init();
-#endif
-
-    struct addrinfo hints, *res, *p;
-
-    std::memset(&hints, 0, sizeof (hints));
-    hints.ai_family = domain;
-    hints.ai_socktype = type;
-
-    int e = getaddrinfo(host.c_str(), service.c_str(), &hints, &res);
-
-    if (e != 0)
-        throw Error(gai_strerror(e));
-
-    std::vector<Address> addresses;
-
-    for (p = res; p != nullptr; p = p->ai_next)
-        addresses.push_back(Address(p->ai_addr, p->ai_addrlen));
-
-    return AddressIterator(addresses, 0);
-}
-
-/**
- * \ingroup net-module-resolv
- *
- * Resolve the first address.
- *
- * \param host the hostname
- * \param service the service name
- * \param domain the domain (e.g. AF_INET)
- * \param type the type (e.g. SOCK_STREAM)
- * \return the first generic address available
- * \throw Error on failures
- * \note do not use AF_UNSPEC and 0 as type for this function
- */
-inline Address resolveOne(const std::string &host, const std::string &service, int domain, int type)
-{
-    AddressIterator it = resolve(host, service, domain, type);
-    AddressIterator end;
-
-    if (it == end)
-        throw Error("no address available");
-
-    return *it;
-}
-
-} // !net
-
-} // !malikania
-
-#endif // !MALIKANIA_NET_HPP
--- a/libcommon/malikania/resources_loader.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libcommon/malikania/resources_loader.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * resources_loader.cpp -- load shared resources files
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libcommon/malikania/resources_loader.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libcommon/malikania/resources_loader.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * resources_loader.hpp -- load shared resources files
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libcommon/malikania/resources_locator.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libcommon/malikania/resources_locator.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * resources_locator.cpp -- file and stream loader
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libcommon/malikania/resources_locator.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libcommon/malikania/resources_locator.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * resources_locator.hpp -- file and stream loader
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libcommon/malikania/util.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libcommon/malikania/util.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * util.cpp -- malikania utilities
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -263,6 +263,42 @@
     return result;
 }
 
+namespace json {
+
+std::runtime_error invalid(const std::string& name, const nlohmann::json::value_t type)
+{
+    std::ostringstream oss;
+
+    oss << "invalid '" << name << "' property ('";
+
+    switch (type) {
+    case nlohmann::json::value_t::null:
+        oss << "null";
+        break;
+    case nlohmann::json::value_t::object:
+        oss << "object";
+        break;
+    case nlohmann::json::value_t::array:
+        oss << "array";
+        break;
+    case nlohmann::json::value_t::string:
+        oss << "string";
+        break;
+    case nlohmann::json::value_t::boolean:
+        oss << "boolean";
+        break;
+    default:
+        oss << "number";
+        break;
+    }
+
+    oss << " expected)";
+
+    return std::runtime_error(oss.str());
+}
+
+} // !json
+
 } // !util
 
 } // !mlk
--- a/libcommon/malikania/util.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libcommon/malikania/util.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * util.hpp -- malikania utilities
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -25,9 +25,12 @@
  */
 
 #include <algorithm>
+#include <stdexcept>
 #include <string>
 #include <vector>
 
+#include "json.hpp"
+
 namespace mlk {
 
 /**
@@ -88,6 +91,17 @@
 
 } // !net
 
+namespace json {
+
+/**
+ * Create an exception with a message like:
+ *
+ * 'invalid '<name>' property ('<type>' expected)
+ */
+std::runtime_error invalid(const std::string& name, const nlohmann::json::value_t type);
+
+} // !json
+
 } // !util
 
 } // !mlk
--- a/libserver/CMakeLists.txt	Thu Dec 29 11:34:40 2016 +0100
+++ b/libserver/CMakeLists.txt	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/libserver/malikania/account.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libserver/malikania/account.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * account.hpp -- account model
  *
- * Copyright (c) 2013-2016 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libserver/malikania/account_dao.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libserver/malikania/account_dao.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * dao-account.cpp -- database account management
  *
- * Copyright (c) 2013-2016 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libserver/malikania/account_dao.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libserver/malikania/account_dao.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * account_dao.hpp -- database account management
  *
- * Copyright (c) 2013-2016 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libserver/malikania/database.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libserver/malikania/database.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * database.cpp -- generic database loader
  *
- * Copyright (c) 2013-2016 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libserver/malikania/database.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libserver/malikania/database.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * database.hpp -- generic database loader
  *
- * Copyright (c) 2013-2016 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libserver/malikania/server.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libserver/malikania/server.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * server.cpp -- malikania basic server
  *
- * Copyright (c) 2016 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2016-2017 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/libserver/malikania/server.hpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/libserver/malikania/server.hpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * server.hpp -- malikania basic server
  *
- * Copyright (c) 2016 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2016-2017 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/server/CMakeLists.txt	Thu Dec 29 11:34:40 2016 +0100
+++ b/server/CMakeLists.txt	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/server/main.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/server/main.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * main.cpp -- main server executable file
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/tests/CMakeLists.txt	Thu Dec 29 11:34:40 2016 +0100
+++ b/tests/CMakeLists.txt	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/tests/libclient/CMakeLists.txt	Thu Dec 29 11:34:40 2016 +0100
+++ b/tests/libclient/CMakeLists.txt	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/tests/libclient/color/CMakeLists.txt	Thu Dec 29 11:34:40 2016 +0100
+++ b/tests/libclient/color/CMakeLists.txt	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/tests/libclient/color/main.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/tests/libclient/color/main.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * main.cpp -- test mlk::color
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/tests/libclient/js-color/CMakeLists.txt	Thu Dec 29 11:34:40 2016 +0100
+++ b/tests/libclient/js-color/CMakeLists.txt	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/tests/libclient/js-color/main.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/tests/libclient/js-color/main.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * main.cpp -- test Color (JavaScript binding)
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/tests/libclient/js-line/CMakeLists.txt	Thu Dec 29 11:34:40 2016 +0100
+++ b/tests/libclient/js-line/CMakeLists.txt	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/tests/libclient/js-line/main.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/tests/libclient/js-line/main.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * main.cpp -- test Line (JavaScript binding)
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/tests/libclient/js-point/CMakeLists.txt	Thu Dec 29 11:34:40 2016 +0100
+++ b/tests/libclient/js-point/CMakeLists.txt	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/tests/libclient/js-point/main.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/tests/libclient/js-point/main.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * main.cpp -- test Point (JavaScript binding)
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/tests/libclient/js-rectangle/CMakeLists.txt	Thu Dec 29 11:34:40 2016 +0100
+++ b/tests/libclient/js-rectangle/CMakeLists.txt	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/tests/libclient/js-rectangle/main.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/tests/libclient/js-rectangle/main.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * main.cpp -- test Rectangle (JavaScript binding)
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/tests/libclient/js-size/CMakeLists.txt	Thu Dec 29 11:34:40 2016 +0100
+++ b/tests/libclient/js-size/CMakeLists.txt	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/tests/libclient/js-size/main.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/tests/libclient/js-size/main.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * main.cpp -- test Size (JavaScript binding)
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/tests/libclient/line/CMakeLists.txt	Thu Dec 29 11:34:40 2016 +0100
+++ b/tests/libclient/line/CMakeLists.txt	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/tests/libclient/line/main.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/tests/libclient/line/main.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * main.cpp -- test mlk::line
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/tests/libclient/point/CMakeLists.txt	Thu Dec 29 11:34:40 2016 +0100
+++ b/tests/libclient/point/CMakeLists.txt	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/tests/libclient/point/main.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/tests/libclient/point/main.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * main.cpp -- test mlk::point
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/tests/libclient/rectangle/CMakeLists.txt	Thu Dec 29 11:34:40 2016 +0100
+++ b/tests/libclient/rectangle/CMakeLists.txt	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/tests/libclient/rectangle/main.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/tests/libclient/rectangle/main.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * main.cpp -- test mlk::rectangle
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/tests/libclient/size/CMakeLists.txt	Thu Dec 29 11:34:40 2016 +0100
+++ b/tests/libclient/size/CMakeLists.txt	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/tests/libclient/size/main.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/tests/libclient/size/main.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * main.cpp -- test mlk::size
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/tests/libcommon/CMakeLists.txt	Thu Dec 29 11:34:40 2016 +0100
+++ b/tests/libcommon/CMakeLists.txt	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/tests/libcommon/js-elapsed-timer/CMakeLists.txt	Thu Dec 29 11:34:40 2016 +0100
+++ b/tests/libcommon/js-elapsed-timer/CMakeLists.txt	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/tests/libcommon/js-elapsed-timer/main.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/tests/libcommon/js-elapsed-timer/main.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * main.cpp -- test ElapsedTimer (JavaScript binding)
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/tests/libcommon/util/CMakeLists.txt	Thu Dec 29 11:34:40 2016 +0100
+++ b/tests/libcommon/util/CMakeLists.txt	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/tests/libcommon/util/main.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/tests/libcommon/util/main.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * main.cpp -- test util
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/tests/libserver/CMakeLists.txt	Thu Dec 29 11:34:40 2016 +0100
+++ b/tests/libserver/CMakeLists.txt	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/tests/libserver/id/CMakeLists.txt	Thu Dec 29 11:34:40 2016 +0100
+++ b/tests/libserver/id/CMakeLists.txt	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/tests/libserver/id/main.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/tests/libserver/id/main.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * main.cpp -- test Id
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/tools/CMakeLists.txt	Thu Dec 29 11:34:40 2016 +0100
+++ b/tools/CMakeLists.txt	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/tools/bcc/CMakeLists.txt	Thu Dec 29 11:34:40 2016 +0100
+++ b/tools/bcc/CMakeLists.txt	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/tools/bcc/main.cpp	Thu Dec 29 11:34:40 2016 +0100
+++ b/tools/bcc/main.cpp	Sun Jan 01 13:35:37 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * main.cpp -- create binary data from assets
  *
- * Copyright (c) 2013-2016 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above