diff --git a/NEWS b/NEWS
index f67b3da47..3bbfdf0b4 100644
--- a/NEWS
+++ b/NEWS
@@ -8,9 +8,14 @@ ver 0.22 (not yet released)
   - ffmpeg: new plugin based on FFmpeg's libavfilter library
   - hdcd: new plugin based on FFmpeg's "af_hdcd" for HDCD playback
 
-ver 0.21.7 (not yet released)
+ver 0.21.7 (2019/04/03)
+* input
+  - qobuz/tidal: scan tags when loading a playlist
 * require Meson 0.49.0 for native libgcrypt-config support
 * fix build failure with -Dlocal_socket=false
+* Haiku
+  - fix build
+  - add version info
 
 ver 0.21.6 (2019/03/17)
 * protocol
diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml
index c0dfc58fb..e2672f984 100644
--- a/android/AndroidManifest.xml
+++ b/android/AndroidManifest.xml
@@ -2,8 +2,8 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="org.musicpd"
           android:installLocation="auto"
-          android:versionCode="28"
-          android:versionName="0.21.6">
+          android:versionCode="29"
+          android:versionName="0.21.7">
 
   <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="26"/>
 
diff --git a/meson.build b/meson.build
index b029d0ec5..8b13a43e4 100644
--- a/meson.build
+++ b/meson.build
@@ -390,6 +390,7 @@ more_deps = []
 if is_android
   subdir('src/java')
   target_type = 'shared_library'
+  target_name = 'mpd'
   link_args += [
     '-Wl,--no-undefined,-shared,-Bsymbolic',
     '-llog',
@@ -399,12 +400,20 @@ if is_android
     declare_dependency(sources: [classes_jar]),
     java_dep,
   ]
+elif is_haiku
+  target_type = 'executable'
+  target_name = 'mpd.nores'
+  link_args += [
+    '-lnetwork',
+    '-lbe',
+  ]
 else
   target_type = 'executable'
+  target_name = 'mpd'
 endif
 
 mpd = build_target(
-  'mpd',
+  target_name,
   sources,
   target_type: target_type,
   include_directories: inc,
@@ -443,6 +452,14 @@ endif
 
 if is_haiku
   subdir('src/haiku')
+  custom_target(
+    'mpd',
+    output: 'mpd',
+    input: [mpd, rsrc],
+    command: [addres, '@OUTPUT@', '@INPUT0@', '@INPUT1@'],
+    install: true,
+    install_dir: get_option('bindir'),
+  )
 endif
 
 configure_file(output: 'config.h', configuration: conf)
diff --git a/python/build/libs.py b/python/build/libs.py
index 8fc1f2258..ac7984afb 100644
--- a/python/build/libs.py
+++ b/python/build/libs.py
@@ -112,8 +112,8 @@ liblame = AutotoolsProject(
 )
 
 ffmpeg = FfmpegProject(
-    'http://ffmpeg.org/releases/ffmpeg-4.1.1.tar.xz',
-    '373749824dfd334d84e55dff406729edfd1606575ee44dd485d97d45ea4d2d86',
+    'http://ffmpeg.org/releases/ffmpeg-4.1.3.tar.xz',
+    '0c3020452880581a8face91595b239198078645e7d7184273b8bcc7758beb63d',
     'lib/libavcodec.a',
     [
         '--disable-shared', '--enable-static',
@@ -341,8 +341,8 @@ ffmpeg = FfmpegProject(
 )
 
 curl = AutotoolsProject(
-    'http://curl.haxx.se/download/curl-7.64.0.tar.xz',
-    '2f2f13fa34d44aa29cb444077ad7dc4dc6d189584ad552e0aaeb06e608af6001',
+    'http://curl.haxx.se/download/curl-7.64.1.tar.xz',
+    '9252332a7f871ce37bfa7f78bdd0a0e3924d8187cc27cb57c76c9474a7168fb3',
     'lib/libcurl.a',
     [
         '--disable-shared', '--enable-static',
@@ -375,8 +375,8 @@ libexpat = AutotoolsProject(
 )
 
 libnfs = AutotoolsProject(
-    'https://github.com/sahlberg/libnfs/archive/libnfs-3.0.0.tar.gz',
-    '445d92c5fc55e4a5b115e358e60486cf8f87ee50e0103d46a02e7fb4618566a5',
+    'https://github.com/sahlberg/libnfs/archive/libnfs-4.0.0.tar.gz',
+    '6ee77e9fe220e2d3e3b1f53cfea04fb319828cc7dbb97dd9df09e46e901d797d',
     'lib/libnfs.a',
     [
         '--disable-shared', '--enable-static',
@@ -387,7 +387,7 @@ libnfs = AutotoolsProject(
 
         '--disable-utils', '--disable-examples',
     ],
-    base='libnfs-libnfs-3.0.0',
+    base='libnfs-libnfs-4.0.0',
     autoreconf=True,
 )
 
diff --git a/src/command/PlaylistCommands.cxx b/src/command/PlaylistCommands.cxx
index 9c0ae779d..8f2801bcc 100644
--- a/src/command/PlaylistCommands.cxx
+++ b/src/command/PlaylistCommands.cxx
@@ -20,6 +20,7 @@
 #include "config.h"
 #include "PlaylistCommands.hxx"
 #include "Request.hxx"
+#include "Instance.hxx"
 #include "db/Selection.hxx"
 #include "db/DatabasePlaylist.hxx"
 #include "CommandError.hxx"
@@ -28,6 +29,7 @@
 #include "PlaylistError.hxx"
 #include "db/PlaylistVector.hxx"
 #include "SongLoader.hxx"
+#include "song/DetachedSong.hxx"
 #include "BulkEdit.hxx"
 #include "playlist/PlaylistQueue.hxx"
 #include "playlist/Print.hxx"
@@ -77,11 +79,21 @@ handle_load(Client &client, Request args, gcc_unused Response &r)
 
 	const ScopeBulkEdit bulk_edit(client.GetPartition());
 
+	auto &playlist = client.GetPlaylist();
+	const unsigned old_size = playlist.GetLength();
+
 	const SongLoader loader(client);
 	playlist_open_into_queue(uri,
 				 range.start, range.end,
-				 client.GetPlaylist(),
+				 playlist,
 				 client.GetPlayerControl(), loader);
+
+	/* invoke the RemoteTagScanner on all newly added songs */
+	auto &instance = client.GetInstance();
+	const unsigned new_size = playlist.GetLength();
+	for (unsigned i = old_size; i < new_size; ++i)
+		instance.LookupRemoteTag(playlist.queue.Get(i).GetURI());
+
 	return CommandResult::OK;
 }
 
diff --git a/src/decoder/plugins/HybridDsdDecoderPlugin.cxx b/src/decoder/plugins/HybridDsdDecoderPlugin.cxx
index 3269c601d..afe443822 100644
--- a/src/decoder/plugins/HybridDsdDecoderPlugin.cxx
+++ b/src/decoder/plugins/HybridDsdDecoderPlugin.cxx
@@ -39,8 +39,8 @@ InitHybridDsdDecoder(const ConfigBlock &block)
 	   without a DSD DAC, the PCM (=ALAC) part of the file is
 	   better */
 	if (block.GetBlockParam("enabled") == nullptr) {
-		LogInfo(hybrid_dsd_domain,
-			"The Hybrid DSD decoder is disabled because it was not explicitly enabled");
+		LogDebug(hybrid_dsd_domain,
+			 "The Hybrid DSD decoder is disabled because it was not explicitly enabled");
 		return false;
 	}
 
diff --git a/src/haiku/add_resources.sh b/src/haiku/add_resources.sh
new file mode 100755
index 000000000..3303233f2
--- /dev/null
+++ b/src/haiku/add_resources.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+cp "$2" "$1" && xres -o "$1" -- "$3" && mimeset -f "$1" || (rm -f "$1"; exit 1)
diff --git a/src/haiku/meson.build b/src/haiku/meson.build
index 36b634420..390ecff17 100644
--- a/src/haiku/meson.build
+++ b/src/haiku/meson.build
@@ -1,18 +1,26 @@
-rc = meson.find_program('rc')
-xres = meson.find_program('xres')
+haiku_conf = configuration_data()
+haiku_conf.set('VERSION', meson.project_version())
+
+splitted_version = meson.project_version().split('~')[0].split('.')
+haiku_conf.set('VERSION_MAJOR', splitted_version[0])
+haiku_conf.set('VERSION_MINOR', splitted_version.get(1, '0'))
+haiku_conf.set('VERSION_REVISION', splitted_version.get(2, '0'))
+haiku_conf.set('VERSION_EXTRA', splitted_version.get(3, '0'))
+
+mpd_rdef = configure_file(
+  input: 'mpd.rdef.in',
+  output: 'mpd.rdef',
+  configuration: haiku_conf,
+)
+
+rc = find_program('rc')
+xres = find_program('xres')
 
 rsrc = custom_target(
   'mpd.rsrc',
   output: 'mpd.rsrc',
-  input: 'mpd.rdef',
+  input: mpd_rdef,
   command: [rc, '-o', '@OUTPUT@', '@INPUT@'],
 )
 
-custom_target(
-  'mpd.rsrc',
-  output: 'mpd',
-  input: [mpd, rsrc],
-  command: [xres, '-o', '@OUTPUT@', '--', '@INPUT@'],
-  install: true,
-  install_dir: get_option('bindir'),
-)
+addres = files('add_resources.sh')
diff --git a/src/haiku/mpd.rdef b/src/haiku/mpd.rdef.in
similarity index 93%
rename from src/haiku/mpd.rdef
rename to src/haiku/mpd.rdef.in
index 6f1aca2d9..c4dbea63c 100644
--- a/src/haiku/mpd.rdef
+++ b/src/haiku/mpd.rdef.in
@@ -2,7 +2,15 @@ resource app_signature "application/x-vnd.MusicPD";
 
 resource app_flags B_BACKGROUND_APP;
 
-// TODO: resource app_version {};
+resource app_version {
+	major = @VERSION_MAJOR@,
+	middle = @VERSION_MINOR@,
+	minor = @VERSION_REVISION@,
+	variety = B_APPV_ALPHA,
+	internal = @VERSION_EXTRA@,
+	short_info = "Music Player Daemon @VERSION@",
+    long_info  = "Music Player Daemon @VERSION@ ©The Music Player Daemon Project"
+};
 
 resource vector_icon {
 	$"6E6369661F050102031604BEE29BBEC5403EC540BEE29B4A10004A10000001C6"
diff --git a/src/input/plugins/CurlInputPlugin.cxx b/src/input/plugins/CurlInputPlugin.cxx
index 74d28fde0..b16f1eb84 100644
--- a/src/input/plugins/CurlInputPlugin.cxx
+++ b/src/input/plugins/CurlInputPlugin.cxx
@@ -306,9 +306,8 @@ input_curl_init(EventLoop &event_loop, const ConfigBlock &block)
 {
 	try {
 		curl_init = new CurlInit(event_loop);
-	} catch (const std::runtime_error &e) {
-		LogError(e);
-		throw PluginUnavailable(e.what());
+	} catch (...) {
+		std::throw_with_nested(PluginUnavailable("CURL initialization failed"));
 	}
 
 	const auto version_info = curl_version_info(CURLVERSION_FIRST);
diff --git a/src/input/plugins/SmbclientInputPlugin.cxx b/src/input/plugins/SmbclientInputPlugin.cxx
index 4469dbab5..b4b0785f8 100644
--- a/src/input/plugins/SmbclientInputPlugin.cxx
+++ b/src/input/plugins/SmbclientInputPlugin.cxx
@@ -28,8 +28,6 @@
 
 #include <libsmbclient.h>
 
-#include <stdexcept>
-
 class SmbclientInputStream final : public InputStream {
 	SMBCCTX *ctx;
 	int fd;
@@ -72,9 +70,8 @@ input_smbclient_init(EventLoop &, const ConfigBlock &)
 {
 	try {
 		SmbclientInit();
-	} catch (const std::runtime_error &e) {
-		// TODO: use std::throw_with_nested()?
-		throw PluginUnavailable(e.what());
+	} catch (...) {
+		std::throw_with_nested(PluginUnavailable("libsmbclient initialization failed"));
 	}
 
 	// TODO: create one global SMBCCTX here?
diff --git a/src/output/plugins/HaikuOutputPlugin.cxx b/src/output/plugins/HaikuOutputPlugin.cxx
index 5d8cbf374..86fa7baf5 100644
--- a/src/output/plugins/HaikuOutputPlugin.cxx
+++ b/src/output/plugins/HaikuOutputPlugin.cxx
@@ -140,9 +140,6 @@ HaikuOutput::Close() noexcept
 
 HaikuOutput::~HaikuOutput()
 {
-	delete_sem(new_buffer);
-	delete_sem(buffer_done);
-
 	finalize_application();
 }