diff --git a/SOURCES/0001-alsa-mixer-Add-support-for-usb-audio-in-the-Dell-doc.patch b/SOURCES/0001-alsa-mixer-Add-support-for-usb-audio-in-the-Dell-doc.patch
new file mode 100644
index 0000000..d5bffcd
--- /dev/null
+++ b/SOURCES/0001-alsa-mixer-Add-support-for-usb-audio-in-the-Dell-doc.patch
@@ -0,0 +1,96 @@
+From 1e057be093d948faa26b94b6efcae79bee7e6aee Mon Sep 17 00:00:00 2001
+From: Hui Wang <hui.wang@canonical.com>
+Date: Fri, 26 May 2017 15:42:40 +0800
+Subject: [PATCH 1/4] alsa-mixer: Add support for usb audio in the Dell dock
+ TB16
+
+There are one headset jack on the front panel of TB16, through this
+jack, we have one stereo headphone output (hw:%f,0,0) and one mono
+headset-mic input (hw:%f,0,0); and there is one speaker output jack
+(hw:%f,1,0) on the rear panel of TB16.
+
+The detail information of the Dell dock TB16:
+http://www.dell.com/support/article/sg/en/sgbsdt1/SLN301105
+
+Signed-off-by: Hui Wang <hui.wang@canonical.com>
+---
+ .../alsa/mixer/profile-sets/90-pulseaudio.rules    |  1 +
+ .../profile-sets/dell-dock-tb16-usb-audio.conf     | 55 ++++++++++++++++++++++
+ 3 files changed, 57 insertions(+)
+ create mode 100644 src/modules/alsa/mixer/profile-sets/dell-dock-tb16-usb-audio.conf
+
+diff --git a/src/modules/alsa/mixer/profile-sets/90-pulseaudio.rules b/src/modules/alsa/mixer/profile-sets/90-pulseaudio.rules
+index 70e34e6fa..805a05b2a 100644
+--- a/src/modules/alsa/mixer/profile-sets/90-pulseaudio.rules
++++ b/src/modules/alsa/mixer/profile-sets/90-pulseaudio.rules
+@@ -98,5 +98,6 @@ ATTRS{idVendor}=="17cc", ATTRS{idProduct}=="1021", ENV{PULSE_PROFILE_SET}="nativ
+ ATTRS{idVendor}=="0763", ATTRS{idProduct}=="2012", ENV{PULSE_PROFILE_SET}="maudio-fasttrack-pro.conf"
+ ATTRS{idVendor}=="045e", ATTRS{idProduct}=="02bb", ENV{PULSE_PROFILE_SET}="kinect-audio.conf"
+ ATTRS{idVendor}=="041e", ATTRS{idProduct}=="322c", ENV{PULSE_PROFILE_SET}="sb-omni-surround-5.1.conf"
++ATTRS{idVendor}=="0bda", ATTRS{idProduct}=="4014", ENV{PULSE_PROFILE_SET}="dell-dock-tb16-usb-audio.conf"
+ 
+ LABEL="pulseaudio_end"
+diff --git a/src/modules/alsa/mixer/profile-sets/dell-dock-tb16-usb-audio.conf b/src/modules/alsa/mixer/profile-sets/dell-dock-tb16-usb-audio.conf
+new file mode 100644
+index 000000000..118655246
+--- /dev/null
++++ b/src/modules/alsa/mixer/profile-sets/dell-dock-tb16-usb-audio.conf
+@@ -0,0 +1,55 @@
++# This file is part of PulseAudio.
++#
++# PulseAudio is free software; you can redistribute it and/or modify
++# it under the terms of the GNU Lesser General Public License as
++# published by the Free Software Foundation; either version 2.1 of the
++# License, or (at your option) any later version.
++#
++# PulseAudio is distributed in the hope that it will be useful, but
++# WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++# General Public License for more details.
++#
++# You should have received a copy of the GNU Lesser General Public License
++# along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
++
++; Dell Dock TB16 USB audio
++;
++; This card has two stereo pairs of output, One Mono input.
++;
++; See default.conf for an explanation on the directives used here.
++
++[General]
++auto-profiles = no
++
++[Mapping analog-stereo-headphone]
++description = Headphone
++device-strings = hw:%f,0,0
++channel-map = left,right
++direction = output
++
++[Mapping analog-stereo-speaker]
++description = Speaker
++device-strings = hw:%f,1,0
++channel-map = left,right
++direction = output
++
++[Mapping analog-stereo-mic]
++description = Headset-Mic
++device-strings = hw:%f,0,0
++channel-map = left,right
++direction = input
++
++
++[Profile output:analog-stereo-speaker]
++description = Speaker
++output-mappings = analog-stereo-speaker
++priority = 60
++skip-probe = yes
++
++[Profile output:analog-stereo-headphone+input:analog-stereo-mic]
++description = Headset
++output-mappings = analog-stereo-headphone
++input-mappings = analog-stereo-mic
++priority = 80
++skip-probe = yes
+-- 
+2.14.3
+
diff --git a/SOURCES/0002-sink-source-update-the-default-sink-source-on-port-s.patch b/SOURCES/0002-sink-source-update-the-default-sink-source-on-port-s.patch
new file mode 100644
index 0000000..2a2a5ec
--- /dev/null
+++ b/SOURCES/0002-sink-source-update-the-default-sink-source-on-port-s.patch
@@ -0,0 +1,60 @@
+From 1e13b722545a23699479bb177648f30f7be396ca Mon Sep 17 00:00:00 2001
+From: Tanu Kaskinen <tanuk@iki.fi>
+Date: Sun, 7 May 2017 12:12:39 +0300
+Subject: [PATCH 2/4] sink, source: update the default sink/source on port
+ switches
+
+When sinks are compared during the default sink selection, the active
+port's availability is inspected. Therefore, the default sink should be
+updated when the active port changes, because the new port may have
+different availability status than the old port.
+
+For example, let's say that a laptop has an analog sink with a speaker
+and a headphone port, and headphones are initially plugged in, so both
+ports can be used[1]. The headphone port is initially the active port.
+There's also a null sink in the system. When the headphones are
+unplugged, the headphone port becomes unavailable, and the null sink
+becomes the new default sink. Then module-switch-on-connect changes the
+analog sink port to speakers. Now the default sink should change back to
+the analog sink, but that doesn't happen without this patch.
+
+[1] Actually we currently mark speakers as unavailable when headphones
+are plugged in, but that's not strictly necessary. My example relies on
+both ports being available initially, so the bug can't be reproduced
+with the current mixer configuration.
+---
+ src/pulsecore/sink.c   | 3 +++
+ src/pulsecore/source.c | 3 +++
+ 2 files changed, 6 insertions(+)
+
+diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
+index aa2182220..ebb13c2c9 100644
+--- a/src/pulsecore/sink.c
++++ b/src/pulsecore/sink.c
+@@ -3355,6 +3355,9 @@ int pa_sink_set_port(pa_sink *s, const char *name, bool save) {
+ 
+     pa_sink_set_port_latency_offset(s, s->active_port->latency_offset);
+ 
++    /* The active port affects the default sink selection. */
++    pa_core_update_default_sink(s->core);
++
+     pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_PORT_CHANGED], s);
+ 
+     return 0;
+diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c
+index 8ce781804..3f0f53b52 100644
+--- a/src/pulsecore/source.c
++++ b/src/pulsecore/source.c
+@@ -2630,6 +2630,9 @@ int pa_source_set_port(pa_source *s, const char *name, bool save) {
+     s->active_port = port;
+     s->save_port = save;
+ 
++    /* The active port affects the default source selection. */
++    pa_core_update_default_source(s->core);
++
+     pa_source_set_port_latency_offset(s, s->active_port->latency_offset);
+ 
+     pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_PORT_CHANGED], s);
+-- 
+2.14.3
+
diff --git a/SOURCES/0003-improve-default-sink-source-handling.patch b/SOURCES/0003-improve-default-sink-source-handling.patch
new file mode 100644
index 0000000..c39ff6a
--- /dev/null
+++ b/SOURCES/0003-improve-default-sink-source-handling.patch
@@ -0,0 +1,1262 @@
+From 84dbc69202771252b0c7a0d8b6b32f728931bb7f Mon Sep 17 00:00:00 2001
+From: Tanu Kaskinen <tanuk@iki.fi>
+Date: Thu, 16 Feb 2017 12:09:38 +0200
+Subject: [PATCH 3/4] improve default sink/source handling
+
+Currently the default sink policy is simple: either the user has
+configured it explicitly, in which case we always use that as the
+default, or we pick the sink with the highest priority. The sink
+priorities are currently static, so there's no need to worry about
+updating the default sink when sink priorities change.
+
+I intend to make things a bit more complex: if the active port of a sink
+is unavailable, the sink should not be the default sink, and I also want
+to make sink priorities dependent on the active port, so changing the
+port should cause re-evaluation of which sink to choose as the default.
+Currently the default sink choice is done only when someone calls
+pa_namereg_get_default_sink(), and change notifications are only sent
+when a sink is created or destroyed. That makes it hard to add new rules
+to the default sink selection policy.
+
+This patch moves the default sink selection to
+pa_core_update_default_sink(), which is called whenever something
+happens that can affect the default sink choice. That function needs to
+know the previous choice in order to send change notifications as
+appropriate, but previously pa_core.default_sink was only set when the
+user had configured it explicitly. Now pa_core.default_sink is always
+set (unless there are no sinks at all), so pa_core_update_default_sink()
+can use that to get the previous choice. The user configuration is saved
+in a new variable, pa_core.configured_default_sink.
+
+pa_namereg_get_default_sink() is now unnecessary, because
+pa_core.default_sink can be used directly to get the
+currently-considered-best sink. pa_namereg_set_default_sink() is
+replaced by pa_core_set_configured_default_sink().
+
+I haven't confirmed it, but I expect that this patch will fix problems
+in the D-Bus protocol related to default sink handling. The D-Bus
+protocol used to get confused when the current default sink gets
+removed. It would incorrectly think that if there's no explicitly
+configured default sink, then there's no default sink at all. Even
+worse, when the D-Bus thinks that there's no default sink, it concludes
+that there are no sinks at all, which made it impossible to configure
+the default sink via the D-Bus interface. Now that pa_core.default_sink
+is always set, except when there really aren't any sinks, the D-Bus
+protocol should behave correctly.
+
+BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=99425
+---
+ src/modules/dbus/iface-core.c               | 114 +++++++++++++------
+ src/modules/dbus/iface-sample.c             |  10 +-
+ src/modules/module-default-device-restore.c |  14 +--
+ src/modules/module-intended-roles.c         |  37 +++---
+ src/modules/module-rescue-streams.c         |  20 ++--
+ src/modules/module-switch-on-connect.c      |  30 ++---
+ src/pulsecore/cli-command.c                 |  20 ++--
+ src/pulsecore/cli-text.c                    |  12 +-
+ src/pulsecore/core.c                        | 170 ++++++++++++++++++++++++++++
+ src/pulsecore/core.h                        |  28 ++++-
+ src/pulsecore/namereg.c                     | 115 +------------------
+ src/pulsecore/namereg.h                     |   6 -
+ src/pulsecore/protocol-native.c             |  19 ++--
+ src/pulsecore/sink.c                        |   7 ++
+ src/pulsecore/source.c                      |   7 ++
+ 15 files changed, 370 insertions(+), 239 deletions(-)
+
+diff --git a/src/modules/dbus/iface-core.c b/src/modules/dbus/iface-core.c
+index 508913de1..3f368ab46 100644
+--- a/src/modules/dbus/iface-core.c
++++ b/src/modules/dbus/iface-core.c
+@@ -721,7 +721,7 @@ static void handle_set_fallback_sink(DBusConnection *conn, DBusMessage *msg, DBu
+         return;
+     }
+ 
+-    pa_namereg_set_default_sink(c->core, pa_dbusiface_device_get_sink(fallback_sink));
++    pa_core_set_configured_default_sink(c->core, pa_dbusiface_device_get_sink(fallback_sink));
+ 
+     pa_dbus_send_empty_reply(conn, msg);
+ }
+@@ -809,7 +809,7 @@ static void handle_set_fallback_source(DBusConnection *conn, DBusMessage *msg, D
+         return;
+     }
+ 
+-    pa_namereg_set_default_source(c->core, pa_dbusiface_device_get_source(fallback_source));
++    pa_core_set_configured_default_source(c->core, pa_dbusiface_device_get_source(fallback_source));
+ 
+     pa_dbus_send_empty_reply(conn, msg);
+ }
+@@ -1692,6 +1692,28 @@ static pa_hook_result_t sample_cache_removed_cb(void *hook_data, void *call_data
+     return PA_HOOK_OK;
+ }
+ 
++static pa_dbusiface_device *create_dbus_object_for_sink(pa_dbusiface_core *c, pa_sink *s) {
++    pa_dbusiface_device *d;
++    const char *object_path;
++    DBusMessage *signal_msg;
++
++    d = pa_dbusiface_device_new_sink(c, s);
++    object_path = pa_dbusiface_device_get_path(d);
++
++    pa_assert_se(pa_hashmap_put(c->sinks_by_index, PA_UINT32_TO_PTR(s->index), d) >= 0);
++    pa_assert_se(pa_hashmap_put(c->sinks_by_path, (char *) object_path, d) >= 0);
++
++    pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
++                                                       PA_DBUS_CORE_INTERFACE,
++                                                       signals[SIGNAL_NEW_SINK].name)));
++    pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
++
++    pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg);
++    dbus_message_unref(signal_msg);
++
++    return d;
++}
++
+ static pa_hook_result_t default_sink_changed_cb(void *hook_data, void *call_data, void *slot_data) {
+     pa_dbusiface_core *c = slot_data;
+     pa_sink *new_fallback_sink = call_data;
+@@ -1707,7 +1729,15 @@ static pa_hook_result_t default_sink_changed_cb(void *hook_data, void *call_data
+         c->fallback_sink = new_fallback_sink ? pa_sink_ref(new_fallback_sink) : NULL;
+ 
+         if (c->fallback_sink) {
+-            pa_assert_se((device_iface = pa_hashmap_get(c->sinks_by_index, PA_UINT32_TO_PTR(c->fallback_sink->index))));
++            device_iface = pa_hashmap_get(c->sinks_by_index, PA_UINT32_TO_PTR(c->fallback_sink->index));
++
++            /* It's possible that we haven't created a dbus object for the
++             * source yet, because if a new source immediately becomes the
++             * default source, the default source change hook is fired before
++             * the put hook. */
++            if (!device_iface)
++                device_iface = create_dbus_object_for_sink(c, c->fallback_sink);
++
+             object_path = pa_dbusiface_device_get_path(device_iface);
+ 
+             pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
+@@ -1730,6 +1760,28 @@ static pa_hook_result_t default_sink_changed_cb(void *hook_data, void *call_data
+     return PA_HOOK_OK;
+ }
+ 
++static pa_dbusiface_device *create_dbus_object_for_source(pa_dbusiface_core *c, pa_source *s) {
++    pa_dbusiface_device *d;
++    const char *object_path;
++    DBusMessage *signal_msg;
++
++    d = pa_dbusiface_device_new_source(c, s);
++    object_path = pa_dbusiface_device_get_path(d);
++
++    pa_assert_se(pa_hashmap_put(c->sources_by_index, PA_UINT32_TO_PTR(s->index), d) >= 0);
++    pa_assert_se(pa_hashmap_put(c->sources_by_path, (char *) object_path, d) >= 0);
++
++    pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
++                                                       PA_DBUS_CORE_INTERFACE,
++                                                       signals[SIGNAL_NEW_SOURCE].name)));
++    pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
++
++    pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg);
++    dbus_message_unref(signal_msg);
++
++    return d;
++}
++
+ static pa_hook_result_t default_source_changed_cb(void *hook_data, void *call_data, void *slot_data) {
+     pa_dbusiface_core *c = slot_data;
+     pa_source *new_fallback_source = call_data;
+@@ -1745,7 +1797,15 @@ static pa_hook_result_t default_source_changed_cb(void *hook_data, void *call_da
+         c->fallback_source = new_fallback_source ? pa_source_ref(new_fallback_source) : NULL;
+ 
+         if (c->fallback_source) {
+-            pa_assert_se((device_iface = pa_hashmap_get(c->sources_by_index, PA_UINT32_TO_PTR(c->fallback_source->index))));
++            device_iface = pa_hashmap_get(c->sources_by_index, PA_UINT32_TO_PTR(c->fallback_source->index));
++
++            /* It's possible that we haven't created a dbus object for the
++             * source yet, because if a new source immediately becomes the
++             * default source, the default source change hook is fired before
++             * the put hook. */
++            if (!device_iface)
++                device_iface = create_dbus_object_for_source(c, c->fallback_source);
++
+             object_path = pa_dbusiface_device_get_path(device_iface);
+ 
+             pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
+@@ -1983,26 +2043,17 @@ static pa_hook_result_t client_unlink_cb(void *hook_data, void *call_data, void
+ static pa_hook_result_t sink_put_cb(void *hook_data, void *call_data, void *slot_data) {
+     pa_dbusiface_core *c = slot_data;
+     pa_sink *s = call_data;
+-    pa_dbusiface_device *d = NULL;
+-    const char *object_path = NULL;
+-    DBusMessage *signal_msg = NULL;
+ 
+     pa_assert(c);
+     pa_assert(s);
+ 
+-    d = pa_dbusiface_device_new_sink(c, s);
+-    object_path = pa_dbusiface_device_get_path(d);
+-
+-    pa_assert_se(pa_hashmap_put(c->sinks_by_index, PA_UINT32_TO_PTR(s->index), d) >= 0);
+-    pa_assert_se(pa_hashmap_put(c->sinks_by_path, (char *) object_path, d) >= 0);
+-
+-    pa_assert_se(signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
+-                                                      PA_DBUS_CORE_INTERFACE,
+-                                                      signals[SIGNAL_NEW_SINK].name));
+-    pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
++    /* We may have alredy encountered this sink, because if the new sink was
++     * chosen as the default sink, the default sink change hook was fired
++     * first, and we saw the sink in default_sink_changed_cb(). */
++    if (pa_hashmap_get(c->sinks_by_index, PA_UINT32_TO_PTR(s->index)))
++        return PA_HOOK_OK;
+ 
+-    pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg);
+-    dbus_message_unref(signal_msg);
++    create_dbus_object_for_sink(c, s);
+ 
+     return PA_HOOK_OK;
+ }
+@@ -2037,26 +2088,17 @@ static pa_hook_result_t sink_unlink_cb(void *hook_data, void *call_data, void *s
+ static pa_hook_result_t source_put_cb(void *hook_data, void *call_data, void *slot_data) {
+     pa_dbusiface_core *c = slot_data;
+     pa_source *s = call_data;
+-    pa_dbusiface_device *d = NULL;
+-    const char *object_path = NULL;
+-    DBusMessage *signal_msg = NULL;
+ 
+     pa_assert(c);
+     pa_assert(s);
+ 
+-    d = pa_dbusiface_device_new_source(c, s);
+-    object_path = pa_dbusiface_device_get_path(d);
+-
+-    pa_assert_se(pa_hashmap_put(c->sources_by_index, PA_UINT32_TO_PTR(s->index), d) >= 0);
+-    pa_assert_se(pa_hashmap_put(c->sources_by_path, (char *) object_path, d) >= 0);
+-
+-    pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
+-                                                       PA_DBUS_CORE_INTERFACE,
+-                                                       signals[SIGNAL_NEW_SOURCE].name)));
+-    pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
++    /* We may have alredy encountered this source, because if the new source
++     * was chosen as the default source, the default source change hook was
++     * fired first, and we saw the source in default_source_changed_cb(). */
++    if (pa_hashmap_get(c->sources_by_index, PA_UINT32_TO_PTR(s->index)))
++        return PA_HOOK_OK;
+ 
+-    pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg);
+-    dbus_message_unref(signal_msg);
++    create_dbus_object_for_source(c, s);
+ 
+     return PA_HOOK_OK;
+ }
+@@ -2158,8 +2200,8 @@ pa_dbusiface_core *pa_dbusiface_core_new(pa_core *core) {
+     c->samples = pa_hashmap_new_full(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func, NULL, (pa_free_cb_t) pa_dbusiface_sample_free);
+     c->modules = pa_hashmap_new_full(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func, NULL, (pa_free_cb_t) pa_dbusiface_module_free);
+     c->clients = pa_hashmap_new_full(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func, NULL, (pa_free_cb_t) pa_dbusiface_client_free);
+-    c->fallback_sink = pa_namereg_get_default_sink(core);
+-    c->fallback_source = pa_namereg_get_default_source(core);
++    c->fallback_sink = core->default_sink;
++    c->fallback_source = core->default_source;
+     c->default_sink_changed_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_DEFAULT_SINK_CHANGED],
+                                                    PA_HOOK_NORMAL, default_sink_changed_cb, c);
+     c->default_source_changed_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_DEFAULT_SOURCE_CHANGED],
+diff --git a/src/modules/dbus/iface-sample.c b/src/modules/dbus/iface-sample.c
+index 61f2ba091..51189196d 100644
+--- a/src/modules/dbus/iface-sample.c
++++ b/src/modules/dbus/iface-sample.c
+@@ -352,7 +352,6 @@ static void handle_play(DBusConnection *conn, DBusMessage *msg, void *userdata)
+     DBusMessageIter msg_iter;
+     dbus_uint32_t volume = 0;
+     pa_proplist *property_list = NULL;
+-    pa_sink *sink = NULL;
+ 
+     pa_assert(conn);
+     pa_assert(msg);
+@@ -370,13 +369,18 @@ static void handle_play(DBusConnection *conn, DBusMessage *msg, void *userdata)
+         goto finish;
+     }
+ 
+-    if (!(sink = pa_namereg_get_default_sink(s->sample->core))) {
++    if (!s->sample->core->default_sink) {
+         pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED,
+                            "Can't play sample %s, because there are no sinks available.", s->sample->name);
+         goto finish;
+     }
+ 
+-    if (pa_scache_play_item(s->sample->core, s->sample->name, sink, volume, property_list, NULL) < 0) {
++    if (pa_scache_play_item(s->sample->core,
++                            s->sample->name,
++                            s->sample->core->default_sink,
++                            volume,
++                            property_list,
++                            NULL) < 0) {
+         pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "Playing sample %s failed.", s->sample->name);
+         goto finish;
+     }
+diff --git a/src/modules/module-default-device-restore.c b/src/modules/module-default-device-restore.c
+index d76e28e68..56fee67f8 100644
+--- a/src/modules/module-default-device-restore.c
++++ b/src/modules/module-default-device-restore.c
+@@ -56,7 +56,7 @@ static void load(struct userdata *u) {
+ 
+     /* We never overwrite manually configured settings */
+ 
+-    if (u->core->default_sink)
++    if (u->core->configured_default_sink)
+         pa_log_info("Manually configured default sink, not overwriting.");
+     else if ((f = pa_fopen_cloexec(u->sink_filename, "r"))) {
+         char ln[256] = "";
+@@ -69,7 +69,7 @@ static void load(struct userdata *u) {
+         if (!ln[0])
+             pa_log_info("No previous default sink setting, ignoring.");
+         else if ((s = pa_namereg_get(u->core, ln, PA_NAMEREG_SINK))) {
+-            pa_namereg_set_default_sink(u->core, s);
++            pa_core_set_configured_default_sink(u->core, s);
+             pa_log_info("Restored default sink '%s'.", ln);
+         } else
+             pa_log_info("Saved default sink '%s' not existent, not restoring default sink setting.", ln);
+@@ -77,7 +77,7 @@ static void load(struct userdata *u) {
+     } else if (errno != ENOENT)
+         pa_log("Failed to load default sink: %s", pa_cstrerror(errno));
+ 
+-    if (u->core->default_source)
++    if (u->core->configured_default_source)
+         pa_log_info("Manually configured default source, not overwriting.");
+     else if ((f = pa_fopen_cloexec(u->source_filename, "r"))) {
+         char ln[256] = "";
+@@ -90,7 +90,7 @@ static void load(struct userdata *u) {
+         if (!ln[0])
+             pa_log_info("No previous default source setting, ignoring.");
+         else if ((s = pa_namereg_get(u->core, ln, PA_NAMEREG_SOURCE))) {
+-            pa_namereg_set_default_source(u->core, s);
++            pa_core_set_configured_default_source(u->core, s);
+             pa_log_info("Restored default source '%s'.", ln);
+         } else
+             pa_log_info("Saved default source '%s' not existent, not restoring default source setting.", ln);
+@@ -107,8 +107,7 @@ static void save(struct userdata *u) {
+ 
+     if (u->sink_filename) {
+         if ((f = pa_fopen_cloexec(u->sink_filename, "w"))) {
+-            pa_sink *s = pa_namereg_get_default_sink(u->core);
+-            fprintf(f, "%s\n", s ? s->name : "");
++            fprintf(f, "%s\n", u->core->default_sink ? u->core->default_sink->name : "");
+             fclose(f);
+         } else
+             pa_log("Failed to save default sink: %s", pa_cstrerror(errno));
+@@ -116,8 +115,7 @@ static void save(struct userdata *u) {
+ 
+     if (u->source_filename) {
+         if ((f = pa_fopen_cloexec(u->source_filename, "w"))) {
+-            pa_source *s = pa_namereg_get_default_source(u->core);
+-            fprintf(f, "%s\n", s ? s->name : "");
++            fprintf(f, "%s\n", u->core->default_source ? u->core->default_source->name : "");
+             fclose(f);
+         } else
+             pa_log("Failed to save default source: %s", pa_cstrerror(errno));
+diff --git a/src/modules/module-intended-roles.c b/src/modules/module-intended-roles.c
+index 60ec7e982..f906b8800 100644
+--- a/src/modules/module-intended-roles.c
++++ b/src/modules/module-intended-roles.c
+@@ -69,7 +69,7 @@ static bool role_match(pa_proplist *proplist, const char *role) {
+ 
+ static pa_hook_result_t sink_input_new_hook_callback(pa_core *c, pa_sink_input_new_data *new_data, struct userdata *u) {
+     const char *role;
+-    pa_sink *s, *def;
++    pa_sink *s;
+     uint32_t idx;
+ 
+     pa_assert(c);
+@@ -92,13 +92,13 @@ static pa_hook_result_t sink_input_new_hook_callback(pa_core *c, pa_sink_input_n
+     }
+ 
+     /* Prefer the default sink over any other sink, just in case... */
+-    if ((def = pa_namereg_get_default_sink(c)))
+-        if (role_match(def->proplist, role) && pa_sink_input_new_data_set_sink(new_data, def, false))
++    if (c->default_sink)
++        if (role_match(c->default_sink->proplist, role) && pa_sink_input_new_data_set_sink(new_data, c->default_sink, false))
+             return PA_HOOK_OK;
+ 
+     /* @todo: favour the highest priority device, not the first one we find? */
+     PA_IDXSET_FOREACH(s, c->sinks, idx) {
+-        if (s == def)
++        if (s == c->default_sink)
+             continue;
+ 
+         if (!PA_SINK_IS_LINKED(pa_sink_get_state(s)))
+@@ -113,7 +113,7 @@ static pa_hook_result_t sink_input_new_hook_callback(pa_core *c, pa_sink_input_n
+ 
+ static pa_hook_result_t source_output_new_hook_callback(pa_core *c, pa_source_output_new_data *new_data, struct userdata *u) {
+     const char *role;
+-    pa_source *s, *def;
++    pa_source *s;
+     uint32_t idx;
+ 
+     pa_assert(c);
+@@ -136,9 +136,9 @@ static pa_hook_result_t source_output_new_hook_callback(pa_core *c, pa_source_ou
+     }
+ 
+     /* Prefer the default source over any other source, just in case... */
+-    if ((def = pa_namereg_get_default_source(c)))
+-        if (role_match(def->proplist, role)) {
+-            pa_source_output_new_data_set_source(new_data, def, false);
++    if (c->default_source)
++        if (role_match(c->default_source->proplist, role)) {
++            pa_source_output_new_data_set_source(new_data, c->default_source, false);
+             return PA_HOOK_OK;
+         }
+ 
+@@ -146,7 +146,7 @@ static pa_hook_result_t source_output_new_hook_callback(pa_core *c, pa_source_ou
+         if (s->monitor_of)
+             continue;
+ 
+-        if (s == def)
++        if (s == c->default_source)
+             continue;
+ 
+         if (!PA_SOURCE_IS_LINKED(pa_source_get_state(s)))
+@@ -259,7 +259,6 @@ static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source,
+ static pa_hook_result_t sink_unlink_hook_callback(pa_core *c, pa_sink *sink, struct userdata *u) {
+     pa_sink_input *si;
+     uint32_t idx;
+-    pa_sink *def;
+ 
+     pa_assert(c);
+     pa_assert(sink);
+@@ -271,7 +270,7 @@ static pa_hook_result_t sink_unlink_hook_callback(pa_core *c, pa_sink *sink, str
+         return PA_HOOK_OK;
+ 
+     /* If there not default sink, then there is no sink at all */
+-    if (!(def = pa_namereg_get_default_sink(c)))
++    if (!c->default_sink)
+         return PA_HOOK_OK;
+ 
+     PA_IDXSET_FOREACH(si, sink->inputs, idx) {
+@@ -286,14 +285,14 @@ static pa_hook_result_t sink_unlink_hook_callback(pa_core *c, pa_sink *sink, str
+             continue;
+ 
+         /* Would the default sink fit? If so, let's use it */
+-        if (def != sink && role_match(def->proplist, role))
+-            if (pa_sink_input_move_to(si, def, false) >= 0)
++        if (c->default_sink != sink && role_match(c->default_sink->proplist, role))
++            if (pa_sink_input_move_to(si, c->default_sink, false) >= 0)
+                 continue;
+ 
+         /* Try to find some other fitting sink */
+         /* @todo: favour the highest priority device, not the first one we find? */
+         PA_IDXSET_FOREACH(d, c->sinks, jdx) {
+-            if (d == def || d == sink)
++            if (d == c->default_sink || d == sink)
+                 continue;
+ 
+             if (!PA_SINK_IS_LINKED(pa_sink_get_state(d)))
+@@ -311,7 +310,6 @@ static pa_hook_result_t sink_unlink_hook_callback(pa_core *c, pa_sink *sink, str
+ static pa_hook_result_t source_unlink_hook_callback(pa_core *c, pa_source *source, struct userdata *u) {
+     pa_source_output *so;
+     uint32_t idx;
+-    pa_source *def;
+ 
+     pa_assert(c);
+     pa_assert(source);
+@@ -323,7 +321,7 @@ static pa_hook_result_t source_unlink_hook_callback(pa_core *c, pa_source *sourc
+         return PA_HOOK_OK;
+ 
+     /* If there not default source, then there is no source at all */
+-    if (!(def = pa_namereg_get_default_source(c)))
++    if (!c->default_source)
+         return PA_HOOK_OK;
+ 
+     PA_IDXSET_FOREACH(so, source->outputs, idx) {
+@@ -341,15 +339,16 @@ static pa_hook_result_t source_unlink_hook_callback(pa_core *c, pa_source *sourc
+             continue;
+ 
+         /* Would the default source fit? If so, let's use it */
+-        if (def != source && role_match(def->proplist, role) && !source->monitor_of == !def->monitor_of) {
+-            pa_source_output_move_to(so, def, false);
++        if (c->default_source != source && role_match(c->default_source->proplist, role)
++                && !source->monitor_of == !c->default_source->monitor_of) {
++            pa_source_output_move_to(so, c->default_source, false);
+             continue;
+         }
+ 
+         /* Try to find some other fitting source */
+         /* @todo: favour the highest priority device, not the first one we find? */
+         PA_IDXSET_FOREACH(d, c->sources, jdx) {
+-            if (d == def || d == source)
++            if (d == c->default_source || d == source)
+                 continue;
+ 
+             if (!PA_SOURCE_IS_LINKED(pa_source_get_state(d)))
+diff --git a/src/modules/module-rescue-streams.c b/src/modules/module-rescue-streams.c
+index 60ac1c4cf..d3c9953ec 100644
+--- a/src/modules/module-rescue-streams.c
++++ b/src/modules/module-rescue-streams.c
+@@ -96,7 +96,7 @@ static void build_group_ports(pa_hashmap *g_ports, pa_hashmap *s_ports) {
+ }
+ 
+ static pa_sink* find_evacuation_sink(pa_core *c, pa_sink_input *i, pa_sink *skip) {
+-    pa_sink *target, *def, *fb_sink = NULL;
++    pa_sink *target, *fb_sink = NULL;
+     uint32_t idx;
+     pa_hashmap *all_ports;
+     pa_device_port *best_port;
+@@ -104,15 +104,13 @@ static pa_sink* find_evacuation_sink(pa_core *c, pa_sink_input *i, pa_sink *skip
+     pa_assert(c);
+     pa_assert(i);
+ 
+-    def = pa_namereg_get_default_sink(c);
+-
+-    if (def && def != skip && pa_sink_input_may_move_to(i, def))
+-        return def;
++    if (c->default_sink && c->default_sink != skip && pa_sink_input_may_move_to(i, c->default_sink))
++        return c->default_sink;
+ 
+     all_ports = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
+ 
+     PA_IDXSET_FOREACH(target, c->sinks, idx) {
+-        if (target == def)
++        if (target == c->default_sink)
+             continue;
+ 
+         if (target == skip)
+@@ -204,7 +202,7 @@ static pa_hook_result_t sink_input_move_fail_hook_callback(pa_core *c, pa_sink_i
+ }
+ 
+ static pa_source* find_evacuation_source(pa_core *c, pa_source_output *o, pa_source *skip) {
+-    pa_source *target, *def, *fb_source = NULL;
++    pa_source *target, *fb_source = NULL;
+     uint32_t idx;
+     pa_hashmap *all_ports;
+     pa_device_port *best_port;
+@@ -212,15 +210,13 @@ static pa_source* find_evacuation_source(pa_core *c, pa_source_output *o, pa_sou
+     pa_assert(c);
+     pa_assert(o);
+ 
+-    def = pa_namereg_get_default_source(c);
+-
+-    if (def && def != skip && pa_source_output_may_move_to(o, def))
+-        return def;
++    if (c->default_source && c->default_source != skip && pa_source_output_may_move_to(o, c->default_source))
++        return c->default_source;
+ 
+     all_ports = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
+ 
+     PA_IDXSET_FOREACH(target, c->sources, idx) {
+-        if (target == def)
++        if (target == c->default_source)
+             continue;
+ 
+         if (target == skip)
+diff --git a/src/modules/module-switch-on-connect.c b/src/modules/module-switch-on-connect.c
+index c844add6e..776c923ee 100644
+--- a/src/modules/module-switch-on-connect.c
++++ b/src/modules/module-switch-on-connect.c
+@@ -55,7 +55,7 @@ struct userdata {
+ static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, void* userdata) {
+     pa_sink_input *i;
+     uint32_t idx;
+-    pa_sink *def;
++    pa_sink *old_default_sink;
+     const char *s;
+     struct userdata *u = userdata;
+ 
+@@ -75,24 +75,25 @@ static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, void*
+             return PA_HOOK_OK;
+     }
+ 
+-    def = pa_namereg_get_default_sink(c);
+-    if (def == sink)
++    if (c->default_sink == sink)
+         return PA_HOOK_OK;
+ 
+     if (u->only_from_unavailable)
+-        if (!def->active_port || def->active_port->available != PA_AVAILABLE_NO)
++        if (!c->default_sink->active_port || c->default_sink->active_port->available != PA_AVAILABLE_NO)
+             return PA_HOOK_OK;
+ 
++    old_default_sink = c->default_sink;
++
+     /* Actually do the switch to the new sink */
+-    pa_namereg_set_default_sink(c, sink);
++    pa_core_set_configured_default_sink(c, sink);
+ 
+     /* Now move all old inputs over */
+-    if (pa_idxset_size(def->inputs) <= 0) {
++    if (pa_idxset_size(old_default_sink->inputs) <= 0) {
+         pa_log_debug("No sink inputs to move away.");
+         return PA_HOOK_OK;
+     }
+ 
+-    PA_IDXSET_FOREACH(i, def->inputs, idx) {
++    PA_IDXSET_FOREACH(i, old_default_sink->inputs, idx) {
+         if (i->save_sink || !PA_SINK_INPUT_IS_LINKED(i->state))
+             continue;
+ 
+@@ -110,7 +111,7 @@ static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, void*
+ static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source, void* userdata) {
+     pa_source_output *o;
+     uint32_t idx;
+-    pa_source *def;
++    pa_source *old_default_source;
+     const char *s;
+     struct userdata *u = userdata;
+ 
+@@ -134,24 +135,25 @@ static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source,
+             return PA_HOOK_OK;
+     }
+ 
+-    def = pa_namereg_get_default_source(c);
+-    if (def == source)
++    if (c->default_source == source)
+         return PA_HOOK_OK;
+ 
+     if (u->only_from_unavailable)
+-        if (!def->active_port || def->active_port->available != PA_AVAILABLE_NO)
++        if (!c->default_source->active_port || c->default_source->active_port->available != PA_AVAILABLE_NO)
+             return PA_HOOK_OK;
+ 
++    old_default_source = c->default_source;
++
+     /* Actually do the switch to the new source */
+-    pa_namereg_set_default_source(c, source);
++    pa_core_set_configured_default_source(c, source);
+ 
+     /* Now move all old outputs over */
+-    if (pa_idxset_size(def->outputs) <= 0) {
++    if (pa_idxset_size(old_default_source->outputs) <= 0) {
+         pa_log_debug("No source outputs to move away.");
+         return PA_HOOK_OK;
+     }
+ 
+-    PA_IDXSET_FOREACH(o, def->outputs, idx) {
++    PA_IDXSET_FOREACH(o, old_default_source->outputs, idx) {
+         if (o->save_source || !PA_SOURCE_OUTPUT_IS_LINKED(o->state))
+             continue;
+ 
+diff --git a/src/pulsecore/cli-command.c b/src/pulsecore/cli-command.c
+index 9a7360582..5a632be45 100644
+--- a/src/pulsecore/cli-command.c
++++ b/src/pulsecore/cli-command.c
+@@ -344,8 +344,6 @@ static int pa_cli_command_stat(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, bool
+     char bytes[PA_BYTES_SNPRINT_MAX];
+     const pa_mempool_stat *mstat;
+     unsigned k;
+-    pa_sink *def_sink;
+-    pa_source *def_source;
+ 
+     static const char* const type_table[PA_MEMBLOCK_TYPE_MAX] = {
+         [PA_MEMBLOCK_POOL] = "POOL",
+@@ -388,12 +386,10 @@ static int pa_cli_command_stat(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, bool
+     pa_strbuf_printf(buf, "Default channel map: %s\n",
+                      pa_channel_map_snprint(cm, sizeof(cm), &c->default_channel_map));
+ 
+-    def_sink = pa_namereg_get_default_sink(c);
+-    def_source = pa_namereg_get_default_source(c);
+     pa_strbuf_printf(buf, "Default sink name: %s\n"
+                      "Default source name: %s\n",
+-                     def_sink ? def_sink->name : "none",
+-                     def_source ? def_source->name : "none");
++                     c->default_sink ? c->default_sink->name : "none",
++                     c->default_source ? c->default_source->name : "none");
+ 
+     for (k = 0; k < PA_MEMBLOCK_TYPE_MAX; k++)
+         pa_strbuf_printf(buf,
+@@ -1034,7 +1030,7 @@ static int pa_cli_command_sink_default(pa_core *c, pa_tokenizer *t, pa_strbuf *b
+     }
+ 
+     if ((s = pa_namereg_get(c, n, PA_NAMEREG_SINK)))
+-        pa_namereg_set_default_sink(c, s);
++        pa_core_set_configured_default_sink(c, s);
+     else
+         pa_strbuf_printf(buf, "Sink %s does not exist.\n", n);
+ 
+@@ -1056,7 +1052,7 @@ static int pa_cli_command_source_default(pa_core *c, pa_tokenizer *t, pa_strbuf
+     }
+ 
+     if ((s = pa_namereg_get(c, n, PA_NAMEREG_SOURCE)))
+-        pa_namereg_set_default_source(c, s);
++        pa_core_set_configured_default_source(c, s);
+     else
+         pa_strbuf_printf(buf, "Source %s does not exist.\n", n);
+     return 0;
+@@ -1850,20 +1846,20 @@ static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, bool
+     }
+ 
+     nl = false;
+-    if ((sink = pa_namereg_get_default_sink(c))) {
++    if (c->default_sink) {
+         if (!nl) {
+             pa_strbuf_puts(buf, "\n");
+             nl = true;
+         }
+ 
+-        pa_strbuf_printf(buf, "set-default-sink %s\n", sink->name);
++        pa_strbuf_printf(buf, "set-default-sink %s\n", c->default_sink->name);
+     }
+ 
+-    if ((source = pa_namereg_get_default_source(c))) {
++    if (c->default_source) {
+         if (!nl)
+             pa_strbuf_puts(buf, "\n");
+ 
+-        pa_strbuf_printf(buf, "set-default-source %s\n", source->name);
++        pa_strbuf_printf(buf, "set-default-source %s\n", c->default_source->name);
+     }
+ 
+     pa_strbuf_puts(buf, "\n### EOF\n");
+diff --git a/src/pulsecore/cli-text.c b/src/pulsecore/cli-text.c
+index af79a1ebe..ded82f6e4 100644
+--- a/src/pulsecore/cli-text.c
++++ b/src/pulsecore/cli-text.c
+@@ -232,7 +232,7 @@ static const char *source_state_to_string(pa_source_state_t state) {
+ 
+ char *pa_sink_list_to_string(pa_core *c) {
+     pa_strbuf *s;
+-    pa_sink *sink, *default_sink;
++    pa_sink *sink;
+     uint32_t idx = PA_IDXSET_INVALID;
+     pa_assert(c);
+ 
+@@ -240,8 +240,6 @@ char *pa_sink_list_to_string(pa_core *c) {
+ 
+     pa_strbuf_printf(s, "%u sink(s) available.\n", pa_idxset_size(c->sinks));
+ 
+-    default_sink = pa_namereg_get_default_sink(c);
+-
+     PA_IDXSET_FOREACH(sink, c->sinks, idx) {
+         char ss[PA_SAMPLE_SPEC_SNPRINT_MAX],
+             cv[PA_CVOLUME_SNPRINT_VERBOSE_MAX],
+@@ -273,7 +271,7 @@ char *pa_sink_list_to_string(pa_core *c) {
+             "\tchannel map: %s%s%s\n"
+             "\tused by: %u\n"
+             "\tlinked by: %u\n",
+-            sink == default_sink ? '*' : ' ',
++            sink == c->default_sink ? '*' : ' ',
+             sink->index,
+             sink->name,
+             sink->driver,
+@@ -350,7 +348,7 @@ char *pa_sink_list_to_string(pa_core *c) {
+ 
+ char *pa_source_list_to_string(pa_core *c) {
+     pa_strbuf *s;
+-    pa_source *source, *default_source;
++    pa_source *source;
+     uint32_t idx = PA_IDXSET_INVALID;
+     pa_assert(c);
+ 
+@@ -358,8 +356,6 @@ char *pa_source_list_to_string(pa_core *c) {
+ 
+     pa_strbuf_printf(s, "%u source(s) available.\n", pa_idxset_size(c->sources));
+ 
+-    default_source = pa_namereg_get_default_source(c);
+-
+     PA_IDXSET_FOREACH(source, c->sources, idx) {
+         char ss[PA_SAMPLE_SPEC_SNPRINT_MAX],
+             cv[PA_CVOLUME_SNPRINT_VERBOSE_MAX],
+@@ -389,7 +385,7 @@ char *pa_source_list_to_string(pa_core *c) {
+             "\tchannel map: %s%s%s\n"
+             "\tused by: %u\n"
+             "\tlinked by: %u\n",
+-            source == default_source ? '*' : ' ',
++            source == c->default_source ? '*' : ' ',
+             source->index,
+             source->name,
+             source->driver,
+diff --git a/src/pulsecore/core.c b/src/pulsecore/core.c
+index 2a96dfa5e..da1abb3ba 100644
+--- a/src/pulsecore/core.c
++++ b/src/pulsecore/core.c
+@@ -223,6 +223,176 @@ static void core_free(pa_object *o) {
+     pa_xfree(c);
+ }
+ 
++void pa_core_set_configured_default_sink(pa_core *core, pa_sink *sink) {
++    pa_sink *old_sink;
++
++    pa_assert(core);
++
++    old_sink = core->configured_default_sink;
++
++    if (sink == old_sink)
++        return;
++
++    core->configured_default_sink = sink;
++    pa_log_info("configured_default_sink: %s -> %s",
++                old_sink ? old_sink->name : "(unset)", sink ? sink->name : "(unset)");
++
++    pa_core_update_default_sink(core);
++}
++
++void pa_core_set_configured_default_source(pa_core *core, pa_source *source) {
++    pa_source *old_source;
++
++    pa_assert(core);
++
++    old_source = core->configured_default_source;
++
++    if (source == old_source)
++        return;
++
++    core->configured_default_source = source;
++    pa_log_info("configured_default_source: %s -> %s",
++                old_source ? old_source->name : "(unset)", source ? source->name : "(unset)");
++
++    pa_core_update_default_source(core);
++}
++
++/* a  < b  ->  return -1
++ * a == b  ->  return  0
++ * a  > b  ->  return  1 */
++static int compare_sinks(pa_sink *a, pa_sink *b) {
++    pa_core *core;
++
++    core = a->core;
++
++    /* The configured default sink is preferred over any other sink. */
++    if (b == core->configured_default_sink)
++        return -1;
++    if (a == core->configured_default_sink)
++        return 1;
++
++    if (a->priority < b->priority)
++        return -1;
++    if (a->priority > b->priority)
++        return 1;
++
++    /* It's hard to find any difference between these sinks, but maybe one of
++     * them is already the default sink? If so, it's best to keep it as the
++     * default to avoid changing the routing for no good reason. */
++    if (b == core->default_sink)
++        return -1;
++    if (a == core->default_sink)
++        return 1;
++
++    return 0;
++}
++
++void pa_core_update_default_sink(pa_core *core) {
++    pa_sink *best = NULL;
++    pa_sink *sink;
++    uint32_t idx;
++    pa_sink *old_default_sink;
++
++    pa_assert(core);
++
++    PA_IDXSET_FOREACH(sink, core->sinks, idx) {
++        if (!best) {
++            best = sink;
++            continue;
++        }
++
++        if (compare_sinks(sink, best) > 0)
++            best = sink;
++    }
++
++    old_default_sink = core->default_sink;
++
++    if (best == old_default_sink)
++        return;
++
++    core->default_sink = best;
++    pa_log_info("default_sink: %s -> %s",
++                old_default_sink ? old_default_sink->name : "(unset)", best ? best->name : "(unset)");
++
++    /* If the default sink changed, it may be that the default source has to be
++     * changed too, because monitor sources are prioritized partly based on the
++     * priorities of the monitored sinks. */
++    pa_core_update_default_source(core);
++
++    pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_SERVER | PA_SUBSCRIPTION_EVENT_CHANGE, PA_INVALID_INDEX);
++    pa_hook_fire(&core->hooks[PA_CORE_HOOK_DEFAULT_SINK_CHANGED], core->default_sink);
++}
++
++/* a  < b  ->  return -1
++ * a == b  ->  return  0
++ * a  > b  ->  return  1 */
++static int compare_sources(pa_source *a, pa_source *b) {
++    pa_core *core;
++
++    core = a->core;
++
++    /* The configured default source is preferred over any other source. */
++    if (b == core->configured_default_source)
++        return -1;
++    if (a == core->configured_default_source)
++        return 1;
++
++    /* Monitor sources lose to non-monitor sources. */
++    if (a->monitor_of && !b->monitor_of)
++        return -1;
++    if (!a->monitor_of && b->monitor_of)
++        return 1;
++
++    if (a->priority < b->priority)
++        return -1;
++    if (a->priority > b->priority)
++        return 1;
++
++    /* If the sources are monitors, we can compare the monitored sinks. */
++    if (a->monitor_of)
++        return compare_sinks(a->monitor_of, b->monitor_of);
++
++    /* It's hard to find any difference between these sources, but maybe one of
++     * them is already the default source? If so, it's best to keep it as the
++     * default to avoid changing the routing for no good reason. */
++    if (b == core->default_source)
++        return -1;
++    if (a == core->default_source)
++        return 1;
++
++    return 0;
++}
++
++void pa_core_update_default_source(pa_core *core) {
++    pa_source *best = NULL;
++    pa_source *source;
++    uint32_t idx;
++    pa_source *old_default_source;
++
++    pa_assert(core);
++
++    PA_IDXSET_FOREACH(source, core->sources, idx) {
++        if (!best) {
++            best = source;
++            continue;
++        }
++
++        if (compare_sources(source, best) > 0)
++            best = source;
++    }
++
++    old_default_source = core->default_source;
++
++    if (best == old_default_source)
++        return;
++
++    core->default_source = best;
++    pa_log_info("default_source: %s -> %s",
++                old_default_source ? old_default_source->name : "(unset)", best ? best->name : "(unset)");
++    pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_SERVER | PA_SUBSCRIPTION_EVENT_CHANGE, PA_INVALID_INDEX);
++    pa_hook_fire(&core->hooks[PA_CORE_HOOK_DEFAULT_SOURCE_CHANGED], core->default_source);
++}
++
+ static void exit_callback(pa_mainloop_api *m, pa_time_event *e, const struct timeval *t, void *userdata) {
+     pa_core *c = userdata;
+     pa_assert(c->exit_event == e);
+diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h
+index 802111ba1..6e613edeb 100644
+--- a/src/pulsecore/core.h
++++ b/src/pulsecore/core.h
+@@ -160,9 +160,18 @@ struct pa_core {
+     /* Some hashmaps for all sorts of entities */
+     pa_hashmap *namereg, *shared;
+ 
+-    /* The default sink/source */
+-    pa_source *default_source;
++    /* The default sink/source as configured by the user. If the user hasn't
++     * explicitly configured anything, these are set to NULL. */
++    pa_sink *configured_default_sink;
++    pa_source *configured_default_source;
++
++    /* The effective default sink/source. If no sink or source is explicitly
++     * configured as the default, we pick the device that ranks highest
++     * according to the compare_sinks() and compare_sources() functions in
++     * core.c. pa_core_update_default_sink/source() has to be called whenever
++     * anything changes that might change the comparison results. */
+     pa_sink *default_sink;
++    pa_source *default_source;
+ 
+     pa_channel_map default_channel_map;
+     pa_sample_spec default_sample_spec;
+@@ -223,6 +232,21 @@ enum {
+ 
+ pa_core* pa_core_new(pa_mainloop_api *m, bool shared, bool enable_memfd, size_t shm_size);
+ 
++void pa_core_set_configured_default_sink(pa_core *core, pa_sink *sink);
++void pa_core_set_configured_default_source(pa_core *core, pa_source *source);
++
++/* These should be called whenever something changes that may affect the
++ * default sink or source choice.
++ *
++ * If the default source choice happens between two monitor sources, the
++ * monitored sinks are compared, so if the default sink changes, the default
++ * source may change too. However, pa_core_update_default_sink() calls
++ * pa_core_update_default_source() internally, so it's sufficient to only call
++ * pa_core_update_default_sink() when something happens that affects the sink
++ * ordering. */
++void pa_core_update_default_sink(pa_core *core);
++void pa_core_update_default_source(pa_core *core);
++
+ /* Check whether no one is connected to this core */
+ void pa_core_check_idle(pa_core *c);
+ 
+diff --git a/src/pulsecore/namereg.c b/src/pulsecore/namereg.c
+index 47bfc087f..0b7388592 100644
+--- a/src/pulsecore/namereg.c
++++ b/src/pulsecore/namereg.c
+@@ -168,17 +168,6 @@ const char *pa_namereg_register(pa_core *c, const char *name, pa_namereg_type_t
+ 
+     pa_assert_se(pa_hashmap_put(c->namereg, e->name, e) >= 0);
+ 
+-    /* If a sink or source is registered and there was none registered
+-     * before we inform the clients which then can ask for the default
+-     * sink/source which is then assigned. We don't adjust the default
+-     * sink/source here right away to give the module the chance to
+-     * register more sinks/sources before we choose a new default
+-     * sink/source. */
+-
+-    if ((!c->default_sink && type == PA_NAMEREG_SINK) ||
+-        (!c->default_source && type == PA_NAMEREG_SOURCE))
+-        pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SERVER|PA_SUBSCRIPTION_EVENT_CHANGE, PA_INVALID_INDEX);
+-
+     return e->name;
+ }
+ 
+@@ -189,12 +178,6 @@ void pa_namereg_unregister(pa_core *c, const char *name) {
+     pa_assert(name);
+ 
+     pa_assert_se(e = pa_hashmap_remove(c->namereg, name));
+-
+-    if (c->default_sink == e->data)
+-        pa_namereg_set_default_sink(c, NULL);
+-    else if (c->default_source == e->data)
+-        pa_namereg_set_default_source(c, NULL);
+-
+     pa_xfree(e->name);
+     pa_xfree(e);
+ }
+@@ -205,22 +188,16 @@ void* pa_namereg_get(pa_core *c, const char *name, pa_namereg_type_t type) {
+     pa_assert(c);
+ 
+     if (type == PA_NAMEREG_SOURCE && (!name || pa_streq(name, "@DEFAULT_SOURCE@"))) {
+-        pa_source *s;
+-
+-        if ((s = pa_namereg_get_default_source(c)))
+-            return s;
++        return c->default_source;
+ 
+     } else if (type == PA_NAMEREG_SINK && (!name || pa_streq(name, "@DEFAULT_SINK@"))) {
+-        pa_sink *s;
+-
+-        if ((s = pa_namereg_get_default_sink(c)))
+-            return s;
++        return c->default_sink;
+ 
+     } else if (type == PA_NAMEREG_SOURCE && name && pa_streq(name, "@DEFAULT_MONITOR@")) {
+-        pa_sink *s;
+-
+-        if ((s = pa_namereg_get(c, NULL, PA_NAMEREG_SINK)))
+-            return s->monitor_source;
++        if (c->default_sink)
++            return c->default_sink->monitor_source;
++        else
++            return NULL;
+     }
+ 
+     if (!name)
+@@ -248,83 +225,3 @@ void* pa_namereg_get(pa_core *c, const char *name, pa_namereg_type_t type) {
+ 
+     return NULL;
+ }
+-
+-pa_sink* pa_namereg_set_default_sink(pa_core*c, pa_sink *s) {
+-    pa_assert(c);
+-
+-    if (s && !PA_SINK_IS_LINKED(pa_sink_get_state(s)))
+-        return NULL;
+-
+-    if (c->default_sink != s) {
+-        c->default_sink = s;
+-        pa_hook_fire(&c->hooks[PA_CORE_HOOK_DEFAULT_SINK_CHANGED], c->default_sink);
+-        pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SERVER|PA_SUBSCRIPTION_EVENT_CHANGE, PA_INVALID_INDEX);
+-    }
+-
+-    return s;
+-}
+-
+-pa_source* pa_namereg_set_default_source(pa_core*c, pa_source *s) {
+-    pa_assert(c);
+-
+-    if (s && !PA_SOURCE_IS_LINKED(pa_source_get_state(s)))
+-        return NULL;
+-
+-    if (c->default_source != s) {
+-        c->default_source = s;
+-        pa_hook_fire(&c->hooks[PA_CORE_HOOK_DEFAULT_SOURCE_CHANGED], c->default_source);
+-        pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SERVER|PA_SUBSCRIPTION_EVENT_CHANGE, PA_INVALID_INDEX);
+-    }
+-
+-    return s;
+-}
+-
+-pa_sink *pa_namereg_get_default_sink(pa_core *c) {
+-    pa_sink *s, *best = NULL;
+-    uint32_t idx;
+-
+-    pa_assert(c);
+-
+-    if (c->default_sink && PA_SINK_IS_LINKED(pa_sink_get_state(c->default_sink)))
+-        return c->default_sink;
+-
+-    PA_IDXSET_FOREACH(s, c->sinks, idx)
+-        if (PA_SINK_IS_LINKED(pa_sink_get_state(s)))
+-            if (!best || s->priority > best->priority)
+-                best = s;
+-
+-    return best;
+-}
+-
+-pa_source *pa_namereg_get_default_source(pa_core *c) {
+-    pa_source *s, *best = NULL;
+-    uint32_t idx;
+-
+-    pa_assert(c);
+-
+-    if (c->default_source && PA_SOURCE_IS_LINKED(pa_source_get_state(c->default_source)))
+-        return c->default_source;
+-
+-    /* First, try to find one that isn't a monitor */
+-    PA_IDXSET_FOREACH(s, c->sources, idx)
+-        if (!s->monitor_of && PA_SOURCE_IS_LINKED(pa_source_get_state(s)))
+-            if (!best ||
+-                s->priority > best->priority)
+-                best = s;
+-
+-    if (best)
+-        return best;
+-
+-    /* Then, fallback to a monitor */
+-    PA_IDXSET_FOREACH(s, c->sources, idx)
+-        if (PA_SOURCE_IS_LINKED(pa_source_get_state(s)))
+-            if (!best ||
+-                s->priority > best->priority ||
+-                (s->priority == best->priority &&
+-                 s->monitor_of &&
+-                 best->monitor_of &&
+-                 s->monitor_of->priority > best->monitor_of->priority))
+-                best = s;
+-
+-    return best;
+-}
+diff --git a/src/pulsecore/namereg.h b/src/pulsecore/namereg.h
+index 467db5d43..eb3475ad3 100644
+--- a/src/pulsecore/namereg.h
++++ b/src/pulsecore/namereg.h
+@@ -36,12 +36,6 @@ const char *pa_namereg_register(pa_core *c, const char *name, pa_namereg_type_t
+ void pa_namereg_unregister(pa_core *c, const char *name);
+ void* pa_namereg_get(pa_core *c, const char *name, pa_namereg_type_t type);
+ 
+-pa_sink* pa_namereg_set_default_sink(pa_core*c, pa_sink *s);
+-pa_source* pa_namereg_set_default_source(pa_core*c, pa_source *s);
+-
+-pa_sink *pa_namereg_get_default_sink(pa_core *c);
+-pa_source *pa_namereg_get_default_source(pa_core *c);
+-
+ bool pa_namereg_is_valid_name(const char *name);
+ bool pa_namereg_is_valid_name_or_wildcard(const char *name, pa_namereg_type_t type);
+ char* pa_namereg_make_valid_name(const char *name);
+diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c
+index 13f4f6238..8869ae4fa 100644
+--- a/src/pulsecore/protocol-native.c
++++ b/src/pulsecore/protocol-native.c
+@@ -3637,10 +3637,9 @@ static void command_get_info_list(pa_pdispatch *pd, uint32_t command, uint32_t t
+ static void command_get_server_info(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
+     pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
+     pa_tagstruct *reply;
+-    pa_sink *def_sink;
+-    pa_source *def_source;
+     pa_sample_spec fixed_ss;
+     char *h, *u;
++    pa_core *core;
+ 
+     pa_native_connection_assert_ref(c);
+     pa_assert(t);
+@@ -3664,18 +3663,18 @@ static void command_get_server_info(pa_pdispatch *pd, uint32_t command, uint32_t
+     pa_tagstruct_puts(reply, h);
+     pa_xfree(h);
+ 
+-    fixup_sample_spec(c, &fixed_ss, &c->protocol->core->default_sample_spec);
++    core = c->protocol->core;
++
++    fixup_sample_spec(c, &fixed_ss, &core->default_sample_spec);
+     pa_tagstruct_put_sample_spec(reply, &fixed_ss);
+ 
+-    def_sink = pa_namereg_get_default_sink(c->protocol->core);
+-    pa_tagstruct_puts(reply, def_sink ? def_sink->name : NULL);
+-    def_source = pa_namereg_get_default_source(c->protocol->core);
+-    pa_tagstruct_puts(reply, def_source ? def_source->name : NULL);
++    pa_tagstruct_puts(reply, core->default_sink ? core->default_sink->name : NULL);
++    pa_tagstruct_puts(reply, core->default_source ? core->default_source->name : NULL);
+ 
+     pa_tagstruct_putu32(reply, c->protocol->core->cookie);
+ 
+     if (c->version >= 15)
+-        pa_tagstruct_put_channel_map(reply, &c->protocol->core->default_channel_map);
++        pa_tagstruct_put_channel_map(reply, &core->default_channel_map);
+ 
+     pa_pstream_send_tagstruct(c->pstream, reply);
+ }
+@@ -4347,7 +4346,7 @@ static void command_set_default_sink_or_source(pa_pdispatch *pd, uint32_t comman
+         source = pa_namereg_get(c->protocol->core, s, PA_NAMEREG_SOURCE);
+         CHECK_VALIDITY(c->pstream, source, tag, PA_ERR_NOENTITY);
+ 
+-        pa_namereg_set_default_source(c->protocol->core, source);
++        pa_core_set_configured_default_source(c->protocol->core, source);
+     } else {
+         pa_sink *sink;
+         pa_assert(command == PA_COMMAND_SET_DEFAULT_SINK);
+@@ -4355,7 +4354,7 @@ static void command_set_default_sink_or_source(pa_pdispatch *pd, uint32_t comman
+         sink = pa_namereg_get(c->protocol->core, s, PA_NAMEREG_SINK);
+         CHECK_VALIDITY(c->pstream, sink, tag, PA_ERR_NOENTITY);
+ 
+-        pa_namereg_set_default_sink(c->protocol->core, sink);
++        pa_core_set_configured_default_sink(c->protocol->core, sink);
+     }
+ 
+     pa_pstream_send_simple_ack(c->pstream, tag);
+diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
+index ebb13c2c9..b4b373a58 100644
+--- a/src/pulsecore/sink.c
++++ b/src/pulsecore/sink.c
+@@ -660,6 +660,8 @@ void pa_sink_put(pa_sink* s) {
+ 
+     pa_source_put(s->monitor_source);
+ 
++    pa_core_update_default_sink(s->core);
++
+     pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_NEW, s->index);
+     pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_PUT], s);
+ }
+@@ -690,6 +692,11 @@ void pa_sink_unlink(pa_sink* s) {
+         pa_namereg_unregister(s->core, s->name);
+     pa_idxset_remove_by_data(s->core->sinks, s, NULL);
+ 
++    if (s == s->core->configured_default_sink)
++        pa_core_set_configured_default_sink(s->core, NULL);
++    else
++        pa_core_update_default_sink(s->core);
++
+     if (s->card)
+         pa_idxset_remove_by_data(s->card->sinks, s, NULL);
+ 
+diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c
+index 3f0f53b52..ccf8efc91 100644
+--- a/src/pulsecore/source.c
++++ b/src/pulsecore/source.c
+@@ -603,6 +603,8 @@ void pa_source_put(pa_source *s) {
+     else
+         pa_assert_se(source_set_state(s, PA_SOURCE_IDLE) == 0);
+ 
++    pa_core_update_default_source(s->core);
++
+     pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE | PA_SUBSCRIPTION_EVENT_NEW, s->index);
+     pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_PUT], s);
+ }
+@@ -632,6 +634,11 @@ void pa_source_unlink(pa_source *s) {
+         pa_namereg_unregister(s->core, s->name);
+     pa_idxset_remove_by_data(s->core->sources, s, NULL);
+ 
++    if (s == s->core->configured_default_source)
++        pa_core_set_configured_default_source(s->core, NULL);
++    else
++        pa_core_update_default_source(s->core);
++
+     if (s->card)
+         pa_idxset_remove_by_data(s->card->sources, s, NULL);
+ 
+-- 
+2.14.3
+
diff --git a/SOURCES/0004-core-device-port-check-availability-when-choosing-th.patch b/SOURCES/0004-core-device-port-check-availability-when-choosing-th.patch
new file mode 100644
index 0000000..9569aff
--- /dev/null
+++ b/SOURCES/0004-core-device-port-check-availability-when-choosing-th.patch
@@ -0,0 +1,70 @@
+From fa883e254c28a36657b0f28443bd69ee5a1821e0 Mon Sep 17 00:00:00 2001
+From: Tanu Kaskinen <tanuk@iki.fi>
+Date: Thu, 16 Feb 2017 12:09:39 +0200
+Subject: [PATCH 4/4] core, device-port: check availability when choosing the
+ default device
+
+It doesn't make sense to use a sink or source whose active port is
+unavailable, so let's take this into account when choosing the default
+sink and source.
+---
+ src/pulsecore/core.c        | 16 ++++++++++++++++
+ src/pulsecore/device-port.c |  8 ++++++++
+ 2 files changed, 24 insertions(+)
+
+diff --git a/src/pulsecore/core.c b/src/pulsecore/core.c
+index da1abb3ba..340b41ff3 100644
+--- a/src/pulsecore/core.c
++++ b/src/pulsecore/core.c
+@@ -265,6 +265,14 @@ static int compare_sinks(pa_sink *a, pa_sink *b) {
+ 
+     core = a->core;
+ 
++    /* Available sinks always beat unavailable sinks. */
++    if (a->active_port && a->active_port->available == PA_AVAILABLE_NO
++            && (!b->active_port || b->active_port->available != PA_AVAILABLE_NO))
++        return -1;
++    if (b->active_port && b->active_port->available == PA_AVAILABLE_NO
++            && (!a->active_port || a->active_port->available != PA_AVAILABLE_NO))
++        return 1;
++
+     /* The configured default sink is preferred over any other sink. */
+     if (b == core->configured_default_sink)
+         return -1;
+@@ -331,6 +339,14 @@ static int compare_sources(pa_source *a, pa_source *b) {
+ 
+     core = a->core;
+ 
++    /* Available sources always beat unavailable sources. */
++    if (a->active_port && a->active_port->available == PA_AVAILABLE_NO
++            && (!b->active_port || b->active_port->available != PA_AVAILABLE_NO))
++        return -1;
++    if (b->active_port && b->active_port->available == PA_AVAILABLE_NO
++            && (!a->active_port || a->active_port->available != PA_AVAILABLE_NO))
++        return 1;
++
+     /* The configured default source is preferred over any other source. */
+     if (b == core->configured_default_source)
+         return -1;
+diff --git a/src/pulsecore/device-port.c b/src/pulsecore/device-port.c
+index 7c9ddf325..76a7e80a1 100644
+--- a/src/pulsecore/device-port.c
++++ b/src/pulsecore/device-port.c
+@@ -93,6 +93,14 @@ void pa_device_port_set_available(pa_device_port *p, pa_available_t status) {
+      * be created before port objects, and then p->card could be non-NULL for
+      * the whole lifecycle of pa_device_port. */
+     if (p->card) {
++        /* A sink or source whose active port is unavailable can't be the
++         * default sink/source, so port availability changes may affect the
++         * default sink/source choice. */
++        if (p->direction == PA_DIRECTION_OUTPUT)
++            pa_core_update_default_sink(p->core);
++        else
++            pa_core_update_default_source(p->core);
++
+         pa_subscription_post(p->core, PA_SUBSCRIPTION_EVENT_CARD|PA_SUBSCRIPTION_EVENT_CHANGE, p->card->index);
+         pa_hook_fire(&p->core->hooks[PA_CORE_HOOK_PORT_AVAILABLE_CHANGED], p);
+     }
+-- 
+2.14.3
+
diff --git a/SOURCES/add-dell-dock-conf.path b/SOURCES/add-dell-dock-conf.path
new file mode 100644
index 0000000..663fe18
--- /dev/null
+++ b/SOURCES/add-dell-dock-conf.path
@@ -0,0 +1,18 @@
+--- pulseaudio-10.0/src/Makefile.in	2017-01-18 04:54:18.000000000 +0100
++++ pulseaudio-10.0-new/src/Makefile.in	2018-01-16 11:45:09.881076974 +0100
+@@ -3009,6 +3009,7 @@
+ 	modules/alsa/mixer/paths/hdmi-output-7.conf
+ am__dist_alsaprofilesets_DATA_DIST =  \
+ 	modules/alsa/mixer/profile-sets/default.conf \
++	modules/alsa/mixer/profile-sets/dell-dock-tb16-usb-audio.conf \
+ 	modules/alsa/mixer/profile-sets/force-speaker.conf \
+ 	modules/alsa/mixer/profile-sets/force-speaker-and-int-mic.conf \
+ 	modules/alsa/mixer/profile-sets/maudio-fasttrack-pro.conf \
+@@ -4244,6 +4245,7 @@
+ libavahi_wrap_la_LIBADD = $(AM_LIBADD) $(AVAHI_CFLAGS) libpulsecore-@PA_MAJORMINOR@.la libpulsecommon-@PA_MAJORMINOR@.la libpulse.la
+ @HAVE_ALSA_TRUE@dist_alsaprofilesets_DATA = \
+ @HAVE_ALSA_TRUE@		modules/alsa/mixer/profile-sets/default.conf \
++@HAVE_ALSA_TRUE@		modules/alsa/mixer/profile-sets/dell-dock-tb16-usb-audio.conf \
+ @HAVE_ALSA_TRUE@		modules/alsa/mixer/profile-sets/force-speaker.conf \
+ @HAVE_ALSA_TRUE@		modules/alsa/mixer/profile-sets/force-speaker-and-int-mic.conf \
+ @HAVE_ALSA_TRUE@		modules/alsa/mixer/profile-sets/maudio-fasttrack-pro.conf \
diff --git a/SPECS/pulseaudio.spec b/SPECS/pulseaudio.spec
index fcb1a4c..e7484ba 100644
--- a/SPECS/pulseaudio.spec
+++ b/SPECS/pulseaudio.spec
@@ -25,7 +25,7 @@
 Name:           pulseaudio
 Summary:        Improved Linux Sound Server
 Version:        %{pa_major}%{?pa_minor:.%{pa_minor}}
-Release:        3%{?snap:.%{snap}git%{shortcommit}}%{?dist}
+Release:        5%{?snap:.%{snap}git%{shortcommit}}%{?dist}
 License:        LGPLv2+
 URL:            http://www.freedesktop.org/wiki/Software/PulseAudio
 %if 0%{?gitrel}
@@ -54,6 +54,11 @@ Patch2: pulseaudio-9.0-disable_flat_volumes.patch
 Patch3: pulseaudio-8.99.2-getaffinity.patch
 
 ## upstream patches
+Patch101: 0001-alsa-mixer-Add-support-for-usb-audio-in-the-Dell-doc.patch
+Patch102: 0002-sink-source-update-the-default-sink-source-on-port-s.patch
+Patch103: 0003-improve-default-sink-source-handling.patch
+Patch104: 0004-core-device-port-check-availability-when-choosing-th.patch
+Patch105: add-dell-dock-conf.path
 
 ## upstreamable patches
 
@@ -251,6 +256,11 @@ This package contains GDM integration hooks for the PulseAudio sound server.
 %patch1 -p1 -b .autostart
 %patch2 -p1 -b .disable_flat_volumes
 %patch3 -p1 -b .affinity
+%patch101 -p1 -b .101
+%patch102 -p1 -b .102
+%patch103 -p1 -b .103
+%patch104 -p1 -b .104
+%patch105 -p1 -b .105
 
 sed -i.no_consolekit -e \
   's/^load-module module-console-kit/#load-module module-console-kit/' \
@@ -591,6 +601,15 @@ exit 0
 %attr(0600, gdm, gdm) %{_localstatedir}/lib/gdm/.pulse/default.pa
 
 %changelog
+* Tue Jan 16 2018 Wim Taymans <wtaymans@redhat.com> - 10.0-5
+- Dist the new config file for Dell dock TB16
+- Resolves: #1457385
+
+* Wed Aug 09 2017 Wim Taymans <wtaymans@redhat.com> - 10.0-4
+- Add support for usb audio in the Dell dock TB16
+- Add patches to improve default sinks
+- Resolves: #1457385
+
 * Thu Mar 09 2017 Wim Taymans <wtaymans@redhat.com> - 10.0-3
 - Add more Requires to avoid testing multiple versions
 - Resolves: #1387036