[Pkg-voip-commits] [ring] 01/03: Imported Upstream version 20160712.1.66bea8b~dfsg1

Alexandre Viau aviau at moszumanska.debian.org
Wed Jul 13 13:58:54 UTC 2016


This is an automated email from the git hooks/post-receive script.

aviau pushed a commit to branch master
in repository ring.

commit 5cae43c541576a96d56520bbb9b6c4eacf76cd2c
Author: aviau <alexandre at alexandreviau.net>
Date:   Wed Jul 13 09:55:29 2016 -0400

    Imported Upstream version 20160712.1.66bea8b~dfsg1
---
 .gitmodules                                        |   3 +
 client-gnome/CMakeLists.txt                        |   2 +
 client-gnome/po/ar.po                              |   2 +-
 client-gnome/po/bg.po                              |   6 +-
 client-gnome/po/ca.po                              | 269 +++++++-------
 client-gnome/po/{ca.po => el.po}                   |  39 +-
 client-gnome/po/es.po                              |   7 +-
 client-gnome/po/{nl.po => fi.po}                   |  32 +-
 client-gnome/po/he.po                              |  20 +-
 client-gnome/po/hr.po                              | 167 ++++-----
 client-gnome/po/nl.po                              | 331 ++++++++---------
 client-gnome/po/{ca.po => nl_NL.po}                |  45 ++-
 client-gnome/po/pt_BR.po                           |   7 +-
 client-gnome/src/accountimportexportview.cpp       | 411 +++++++++++++++++++++
 client-gnome/src/accountimportexportview.h         |  40 ++
 client-gnome/src/accountview.cpp                   | 138 +++++--
 client-gnome/src/ring_client.cpp                   |  22 +-
 client-gnome/ui/accountimportexportview.ui         | 211 +++++++++++
 client-gnome/ui/accountview.ui                     |  28 +-
 client-gnome/ui/ringiconmenu.ui                    |  18 -
 client-gnome/ui/ui.gresource.xml                   |   2 +-
 daemon/configure.ac                                |  56 +--
 daemon/contrib/src/ffmpeg/rules.mak                |  15 +-
 daemon/contrib/src/gmp/rules.mak                   |   2 +-
 daemon/contrib/src/gnutls/SHA512SUMS               |   2 +-
 .../src/gnutls/dtls-packet-reordering.patch        |   5 -
 daemon/contrib/src/gnutls/format-security.patch    |   6 -
 daemon/contrib/src/gnutls/rules.mak                |   8 +-
 daemon/contrib/src/gsm/include_ios.patch           |  11 +
 daemon/contrib/src/gsm/rules.mak                   |   1 +
 daemon/contrib/src/jsoncpp/SHA512SUMS              |   2 +-
 daemon/contrib/src/jsoncpp/rules.mak               |   2 +-
 daemon/contrib/src/natpmp/SHA512SUMS               |   1 +
 daemon/contrib/src/natpmp/rules.mak                |  21 ++
 daemon/contrib/src/nettle/rules.mak                |  13 +-
 daemon/contrib/src/opus/rules.mak                  |   4 -
 daemon/contrib/src/pjproject/gnutls.patch          |   8 +-
 daemon/contrib/src/speexdsp/rules.mak              |   2 +-
 daemon/contrib/src/uuid/rules.mak                  |   4 +
 daemon/contrib/src/vpx/rules.mak                   |  18 +-
 daemon/contrib/src/x264/rules.mak                  |   2 +
 daemon/src/Makefile.am                             |  37 +-
 daemon/src/account.cpp                             |   4 -
 daemon/src/account_factory.cpp                     |   4 -
 daemon/src/call.h                                  |   2 -
 daemon/src/client/callmanager.cpp                  |   2 -
 daemon/src/client/configurationmanager.cpp         |  26 --
 daemon/src/manager.cpp                             |  12 -
 daemon/src/manager.h                               |   4 -
 daemon/src/media/audio/Makefile.am                 |   8 +
 daemon/src/media/audio/coreaudio/Makefile.am       |   4 +
 daemon/src/media/audio/coreaudio/audiodevice.cpp   |   4 +
 daemon/src/media/audio/coreaudio/audiodevice.h     |   6 +
 daemon/src/media/audio/coreaudio/corelayer.cpp     |  18 +-
 daemon/src/media/audio/coreaudio/corelayer.h       |   2 +
 daemon/src/media/video/Makefile.am                 |   3 +-
 daemon/src/ringdht/Makefile.am                     |   4 -
 daemon/src/ringdht/ringaccount.cpp                 |  11 +
 daemon/src/sip/sdp.cpp                             |   4 -
 daemon/src/sip/sipaccount.cpp                      |  28 +-
 daemon/src/sip/sipaccount.h                        |   4 -
 daemon/src/sip/sipcall.cpp                         |   8 -
 daemon/src/sip/sipcall.h                           |   2 -
 daemon/src/sip/siptransport.cpp                    |  12 +-
 daemon/src/sip/siptransport.h                      |   6 -
 daemon/src/sip/sipvoiplink.cpp                     |  10 -
 daemon/src/upnp/upnp_context.cpp                   | 407 +++++++++++++++-----
 daemon/src/upnp/upnp_context.h                     | 124 ++++---
 daemon/src/upnp/upnp_control.cpp                   |  18 +-
 daemon/src/upnp/upnp_igd.h                         |  93 ++++-
 docs/source/dev/releasing.rst                      |   2 +-
 lrc/src/macromodel.cpp                             |   7 +-
 lrc/src/private/videorenderermanager.cpp           | 113 +++---
 lrc/src/recentmodel.cpp                            |   4 +-
 lrc/src/tlsmethodmodel.cpp                         |  17 +-
 lrc/src/tlsmethodmodel.h                           |   3 +-
 make-ring.py                                       |  28 +-
 77 files changed, 1999 insertions(+), 1025 deletions(-)

diff --git a/.gitmodules b/.gitmodules
index 002160e..83252bf 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -16,3 +16,6 @@
 [submodule "client-macosx"]
 	path = client-macosx
 	url = https://gerrit-ring.savoirfairelinux.com/ring-client-macosx
+[submodule "client-ios"]
+	path = client-ios
+	url = https://gerrit-ring.savoirfairelinux.com/ring-client-ios
diff --git a/client-gnome/CMakeLists.txt b/client-gnome/CMakeLists.txt
index 0622c8e..1549826 100644
--- a/client-gnome/CMakeLists.txt
+++ b/client-gnome/CMakeLists.txt
@@ -310,6 +310,8 @@ SET( SRC_FILES
    src/chatview.cpp
    src/avatarmanipulation.h
    src/avatarmanipulation.cpp
+   src/accountimportexportview.h
+   src/accountimportexportview.cpp
 )
 
 # compile glib resource files to c code
diff --git a/client-gnome/po/ar.po b/client-gnome/po/ar.po
index 4376275..0a34126 100644
--- a/client-gnome/po/ar.po
+++ b/client-gnome/po/ar.po
@@ -11,7 +11,7 @@ msgstr ""
 "Project-Id-Version: Ring\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2015-11-13 09:43-0500\n"
-"PO-Revision-Date: 2016-04-14 15:25+0000\n"
+"PO-Revision-Date: 2016-05-12 17:43+0000\n"
 "Last-Translator: Omar Mohamed <om_80_m at yahoo.com>\n"
 "Language-Team: Arabic (http://www.transifex.com/savoirfairelinux/ring/language/ar/)\n"
 "MIME-Version: 1.0\n"
diff --git a/client-gnome/po/bg.po b/client-gnome/po/bg.po
index 639b928..8a4e844 100644
--- a/client-gnome/po/bg.po
+++ b/client-gnome/po/bg.po
@@ -9,7 +9,7 @@ msgstr ""
 "Project-Id-Version: Ring\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2015-11-13 09:43-0500\n"
-"PO-Revision-Date: 2016-03-28 16:48+0000\n"
+"PO-Revision-Date: 2016-06-06 19:35+0000\n"
 "Last-Translator: Любомир Василев\n"
 "Language-Team: Bulgarian (http://www.transifex.com/savoirfairelinux/ring/language/bg/)\n"
 "MIME-Version: 1.0\n"
@@ -347,11 +347,11 @@ msgstr ""
 
 #: ui/accountadvancedtab.ui:558 ui/accountadvancedtab.ui:632
 msgid "Min"
-msgstr ""
+msgstr "Минимум"
 
 #: ui/accountadvancedtab.ui:581 ui/accountadvancedtab.ui:655
 msgid "Max"
-msgstr ""
+msgstr "Максимум"
 
 #: ui/accountadvancedtab.ui:605
 msgid "<b>Audio RTP Port Range</b>"
diff --git a/client-gnome/po/ca.po b/client-gnome/po/ca.po
index 280e138..ed302b4 100644
--- a/client-gnome/po/ca.po
+++ b/client-gnome/po/ca.po
@@ -4,13 +4,14 @@
 # 
 # Translators:
 # David <stakewinner00 at mykolab.com>, 2015
+# Jaume <retrasado.man at gmail.com>, 2016
 msgid ""
 msgstr ""
 "Project-Id-Version: Ring\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2015-11-13 09:43-0500\n"
-"PO-Revision-Date: 2016-03-24 20:09+0000\n"
-"Last-Translator: Guillaume Roguez\n"
+"PO-Revision-Date: 2016-05-26 12:59+0000\n"
+"Last-Translator: Jaume <retrasado.man at gmail.com>\n"
 "Language-Team: Catalan (http://www.transifex.com/savoirfairelinux/ring/language/ca/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
@@ -29,47 +30,47 @@ msgstr "Nom"
 
 #: src/accountaudiotab.cpp:195 src/accountvideotab.cpp:204
 msgid "Bitrate"
-msgstr ""
+msgstr "Taxa de bits"
 
 #: src/accountaudiotab.cpp:199
 msgid "Samplerate"
-msgstr ""
+msgstr "Freqüència de mostreig"
 
 #: src/accountgeneraltab.cpp:210
 msgid "Alias"
-msgstr ""
+msgstr "Àlies"
 
 #: src/accountgeneraltab.cpp:221
 msgid "Type"
-msgstr ""
+msgstr "Tipus"
 
 #: src/accountgeneraltab.cpp:250
 msgid "auto-generating..."
-msgstr ""
+msgstr "autogenerant..."
 
 #: src/accountgeneraltab.cpp:269
 msgid "Hostname"
-msgstr ""
+msgstr "Nom d'amfitrió"
 
 #: src/accountgeneraltab.cpp:279
 msgid "Username"
-msgstr ""
+msgstr "Nom d'usuari"
 
 #: src/accountgeneraltab.cpp:289
 msgid "Password"
-msgstr ""
+msgstr "Contrasenya"
 
 #: src/accountgeneraltab.cpp:302
 msgid "Show password"
-msgstr ""
+msgstr "Mostra la contrasenya"
 
 #: src/accountgeneraltab.cpp:308
 msgid "Proxy"
-msgstr ""
+msgstr "Intermediari"
 
 #: src/accountgeneraltab.cpp:318
 msgid "Voicemail number"
-msgstr ""
+msgstr "Nombre de correu de veu"
 
 #: src/accountgeneraltab.cpp:330
 msgctxt "The DHT bootstrap server url"
@@ -78,15 +79,15 @@ msgstr ""
 
 #: src/accountgeneraltab.cpp:342
 msgid "Auto-answer calls"
-msgstr ""
+msgstr "Autorespondre trucades"
 
 #: src/accountgeneraltab.cpp:350
 msgid "UPnP enabled"
-msgstr ""
+msgstr "UPnP habitlitat"
 
 #: src/accountgeneraltab.cpp:358
 msgid "DTMF tone type:"
-msgstr ""
+msgstr "Tipus de to DTMF"
 
 #: src/accountvideotab.cpp:200
 msgctxt "The name of the codec"
@@ -96,22 +97,22 @@ msgstr "Nom"
 #: src/accountview.cpp:159
 msgctxt "Account settings"
 msgid "General"
-msgstr ""
+msgstr "General"
 
 #: src/accountview.cpp:163
 msgctxt "Account settings"
 msgid "Audio"
-msgstr ""
+msgstr "Àudio"
 
 #: src/accountview.cpp:167
 msgctxt "Account settings"
 msgid "Video"
-msgstr ""
+msgstr "Vídeo"
 
 #: src/accountview.cpp:171
 msgctxt "Account settings"
 msgid "Advanced"
-msgstr ""
+msgstr "Avançat"
 
 #: src/accountview.cpp:175
 msgctxt "Account settings"
@@ -121,11 +122,11 @@ msgstr "Seguretat"
 #: src/accountview.cpp:229
 #, c-format
 msgid "Are you sure you want to delete account \"%s\"?"
-msgstr ""
+msgstr "Esteu segur que voleu esborrar el compte \"%s\"?"
 
 #: src/accountview.cpp:313 src/accountview.cpp:315
 msgid "New Account"
-msgstr ""
+msgstr "Compte Nou"
 
 #: src/accountview.cpp:399
 msgctxt "Account state column"
@@ -135,24 +136,24 @@ msgstr "Habilitat"
 #: src/accountview.cpp:405
 msgctxt "Account alias (name) column"
 msgid "Alias"
-msgstr ""
+msgstr "Àlies"
 
 #: src/accountview.cpp:409
 msgctxt "Account status column"
 msgid "Status"
-msgstr ""
+msgstr "Estat"
 
 #: src/contactsview.cpp:305
 msgid "_Copy name"
-msgstr ""
+msgstr "_Copia nom"
 
 #: src/contactsview.cpp:316 src/contactsview.cpp:331
 msgid "_Copy number"
-msgstr ""
+msgstr "_Copia telèfon"
 
 #: src/dialogs.c:53
 msgid "Working..."
-msgstr ""
+msgstr "Treballant..."
 
 #: src/dialogs.c:84
 #, c-format
@@ -166,170 +167,170 @@ msgstr ""
 msgid ""
 "The GNOME client for Ring.\n"
 "Ring is a secured and distributed communication software."
-msgstr ""
+msgstr "El client de GNOME per a Ring.\nRing és un programari de comunicació segur i distribuït."
 
 #: src/editcontactview.cpp:196
 msgctxt "Phone number category"
 msgid "home"
-msgstr ""
+msgstr "casa"
 
 #: src/generalsettingsview.cpp:94
 msgid ""
 "Are you sure you want to clear all your history?\n"
 "This operation will also reset the Frequent Contacts list"
-msgstr ""
+msgstr "Esteu segura que voleu esborrar tot el vostre historial?\nAquesta operació també esborrarà la llista de Contactes Freqüents."
 
 #: src/historyview.cpp:184
 msgid "_Copy"
-msgstr ""
+msgstr "_Copia"
 
 #: src/historyview.cpp:402
 msgctxt "Call history"
 msgid "Call"
-msgstr ""
+msgstr "Trucada"
 
 #: src/historyview.cpp:447
 msgctxt "Call history"
 msgid "Date"
-msgstr ""
+msgstr "Data"
 
 #: src/ringnotify.cpp:86
 msgid "Incoming call"
-msgstr ""
+msgstr "Trucada entrant"
 
 #: src/ringnotify.cpp:169
 #, c-format
 msgctxt "Text message notification"
 msgid "%s says:"
-msgstr ""
+msgstr "%s diu:"
 
 #: src/ring_client_options.c:65
 msgid "Enable debug"
-msgstr ""
+msgstr "Habilitar depuració"
 
 #: src/ring_client_options.c:67
 msgid ""
 "Restores the hidden state of the main window (only applicable to the primary"
 " instance)"
-msgstr ""
+msgstr "Restaura l'estat ocult de la finestra principal (només s'aplica a la instància principal)"
 
 #: src/ring_client_options.c:84
 msgid "- GNOME client for Ring"
-msgstr ""
+msgstr "- Client de GNOME per a Ring"
 
 #: src/backends/edscontactbackend.cpp:201
 msgid "Unknown EDS addressbook"
-msgstr ""
+msgstr "Llibreta d'adreces EDS desconeguda"
 
 #: src/backends/edscontactbackend.cpp:221
 msgctxt "Backend type"
 msgid "Contacts"
-msgstr ""
+msgstr "Contactes"
 
 #: src/utils/menus.cpp:67
 msgid "_Add to contact"
-msgstr ""
+msgstr "_Afegir al contacte"
 
 #: src/ringmainwindow.cpp:944
 msgctxt ""
 "Please try to make the translation 50 chars or less so that it fits into the"
 " layout"
 msgid "Search contacts or enter number"
-msgstr ""
+msgstr "Busqueu contactes o introduïu el nombre"
 
 #: src/ringwelcomeview.cpp:61
 msgid "fetching RingID..."
-msgstr ""
+msgstr "buscant RingID"
 
 #: src/ringwelcomeview.cpp:92
 msgid ""
 "Ring is a secure and distributed voice, video, and chat communication "
 "platform that requires no centralized server and leaves the power of privacy"
 " in the hands of the user."
-msgstr ""
+msgstr "Ring és una plataforma de veu, vídeo i xat segura i distribuïda que no requereix un servidor central i deixa en mans de l'usuari el poder de la privacitat."
 
 #: src/ringwelcomeview.cpp:102
 msgctxt "Do not translate \"RingID\""
 msgid ""
 "This is your RingID.\n"
 "Copy and share it with your friends!"
-msgstr ""
+msgstr "Aquest és el vostre RingID.\nCopieu i compartiu amb les vostres amistats!"
 
 #: src/video/video_widget.cpp:478
 msgid "Share screen area"
-msgstr ""
+msgstr "Compartir pantalla"
 
 #: src/video/video_widget.cpp:484
 msgid "Share file"
-msgstr ""
+msgstr "Compartir arxiu"
 
 #: ui/accountadvancedtab.ui:81
 msgid "Registration expire timeout (seconds):"
-msgstr ""
+msgstr "Temps d'expiració del registre (segons):"
 
 #: ui/accountadvancedtab.ui:103
 msgid "Allow calls from unknown peers"
-msgstr ""
+msgstr "Permetre trucades de nodes desconeguts"
 
 #: ui/accountadvancedtab.ui:117
 msgid "Allow calls from peers in your call history"
-msgstr ""
+msgstr "Permetre trucades de nodes del vostre historial de trucades"
 
 #: ui/accountadvancedtab.ui:131
 msgid "Allow calls from peers in your contacts list"
-msgstr ""
+msgstr "Permetre trucades de nodes de la vostra llista de contactes"
 
 #: ui/accountadvancedtab.ui:149
 msgid "<b>Registration</b>"
-msgstr ""
+msgstr "<b>Registre</b>"
 
 #: ui/accountadvancedtab.ui:176
 msgid "Use random port"
-msgstr ""
+msgstr "Fer servir un port aleatori"
 
 #: ui/accountadvancedtab.ui:197
 msgid "Local port:"
-msgstr ""
+msgstr "Port local:"
 
 #: ui/accountadvancedtab.ui:223
 msgid "<b>Network Interface</b>"
-msgstr ""
+msgstr "<b>Interfície de xarxa</b>"
 
 #: ui/accountadvancedtab.ui:249
 msgid "Same as local parameters"
-msgstr ""
+msgstr "Igual que els paràmetres locals"
 
 #: ui/accountadvancedtab.ui:264
 msgid "Set published address and port:"
-msgstr ""
+msgstr "Establir port i adreça publicats:"
 
 #: ui/accountadvancedtab.ui:288
 msgid "Address"
-msgstr ""
+msgstr "Adreça"
 
 #: ui/accountadvancedtab.ui:310
 msgid "Port"
-msgstr ""
+msgstr "Port"
 
 #: ui/accountadvancedtab.ui:336
 msgid "Use STUN"
-msgstr ""
+msgstr "Utilitza STUN"
 
 #: ui/accountadvancedtab.ui:359 ui/accountadvancedtab.ui:408
 msgid "server URL"
-msgstr ""
+msgstr "URl del servidor"
 
 #: ui/accountadvancedtab.ui:385
 msgid "Use TURN"
-msgstr ""
+msgstr "Utilitza TURN"
 
 #: ui/accountadvancedtab.ui:430
 msgid "username"
-msgstr ""
+msgstr "nom d'usuari"
 
 #: ui/accountadvancedtab.ui:451
 msgid "password"
-msgstr ""
+msgstr "contrasenya"
 
 #: ui/accountadvancedtab.ui:475
 msgid "realm"
@@ -337,7 +338,7 @@ msgstr ""
 
 #: ui/accountadvancedtab.ui:504
 msgid "<b>Published Address</b>"
-msgstr ""
+msgstr "<b>Adreça publicada</b>"
 
 #: ui/accountadvancedtab.ui:533
 msgid ""
@@ -347,19 +348,19 @@ msgstr ""
 
 #: ui/accountadvancedtab.ui:558 ui/accountadvancedtab.ui:632
 msgid "Min"
-msgstr ""
+msgstr "Mín"
 
 #: ui/accountadvancedtab.ui:581 ui/accountadvancedtab.ui:655
 msgid "Max"
-msgstr ""
+msgstr "Màx"
 
 #: ui/accountadvancedtab.ui:605
 msgid "<b>Audio RTP Port Range</b>"
-msgstr ""
+msgstr "<b>Interval de Ports d'Àudio RTP</b>"
 
 #: ui/accountadvancedtab.ui:679
 msgid "<b>Video RTP Port Range</b>"
-msgstr ""
+msgstr "<b>Interval de Ports de Vídeo RTP</b>"
 
 #: ui/accountadvancedtab.ui:695
 msgid "<b>SDP Session Negotiation (ICE Fallback)</b>"
@@ -367,31 +368,31 @@ msgstr ""
 
 #: ui/accountaudiotab.ui:59 ui/accountvideotab.ui:59
 msgid "Up"
-msgstr ""
+msgstr "Amunt"
 
 #: ui/accountaudiotab.ui:66 ui/accountvideotab.ui:66
 msgid "Down"
-msgstr ""
+msgstr "Avall"
 
 #: ui/accountaudiotab.ui:77 ui/accountvideotab.ui:77
 msgid "<b>Codecs</b>"
-msgstr ""
+msgstr "<b>Còdecs</b>"
 
 #: ui/accountgeneraltab.ui:42
 msgid "<b>Account</b>"
-msgstr ""
+msgstr "<b>Comptes</b>"
 
 #: ui/accountgeneraltab.ui:80
 msgid "<b>Parameters</b>"
-msgstr ""
+msgstr "<b>Paràmetres</b>"
 
 #: ui/accountsecuritytab.ui:37
 msgid "Encrypt media streams (SRTP)"
-msgstr ""
+msgstr "Xifra el flux de mitjans (SRTP)"
 
 #: ui/accountsecuritytab.ui:58
 msgid "Key exchange protocol"
-msgstr ""
+msgstr "Protocol d'intercanvi de claus"
 
 #: ui/accountsecuritytab.ui:76
 msgid "Fallback on RTP on encryption failure"
@@ -399,19 +400,19 @@ msgstr ""
 
 #: ui/accountsecuritytab.ui:94
 msgid "<b>Media Stream Encryption</b>"
-msgstr ""
+msgstr "<b>Xifratge del Flux de Mitjans</b>"
 
 #: ui/accountsecuritytab.ui:121
 msgid "Encrypt negotiation (TLS)"
-msgstr ""
+msgstr "Negociació de xifrat (TLS)"
 
 #: ui/accountsecuritytab.ui:146
 msgid "CA certificate"
-msgstr ""
+msgstr "Certificat CA"
 
 #: ui/accountsecuritytab.ui:183
 msgid "User certificate"
-msgstr ""
+msgstr "Certificat d'usuari"
 
 #: ui/accountsecuritytab.ui:220
 msgid "Private key"
@@ -419,27 +420,27 @@ msgstr "Clau privada"
 
 #: ui/accountsecuritytab.ui:243
 msgid "Private key password"
-msgstr ""
+msgstr "Contrasenya de la clau privada"
 
 #: ui/accountsecuritytab.ui:290
 msgid "TLS protocol method"
-msgstr ""
+msgstr "Mètode del protocol TLS"
 
 #: ui/accountsecuritytab.ui:313
 msgid "Outgoing TLS server name"
-msgstr ""
+msgstr "Servidor TLS sortint"
 
 #: ui/accountsecuritytab.ui:335
 msgid "Negotiation timeout (seconds)"
-msgstr ""
+msgstr "Temps d'espera de la negociació (segons)"
 
 #: ui/accountsecuritytab.ui:369
 msgid "Use default ciphers"
-msgstr ""
+msgstr "Utilitza xifrats per defecte"
 
 #: ui/accountsecuritytab.ui:385
 msgid "Use custom cipher list"
-msgstr ""
+msgstr "Utilitza llista de xifrats personalitzats"
 
 #: ui/accountsecuritytab.ui:442
 msgid "Verify incoming certificates (server side)"
@@ -459,7 +460,7 @@ msgstr ""
 
 #: ui/accountvideotab.ui:90
 msgid "Enable Video"
-msgstr ""
+msgstr "Habilita el vídeo"
 
 #: ui/accountview.ui:59
 msgid "<b>−</b>"
@@ -471,7 +472,7 @@ msgstr ""
 
 #: ui/choosecontactview.ui:34
 msgid "Create New"
-msgstr ""
+msgstr "Crea Nou"
 
 #: ui/currentcallview.ui:73
 msgid "Send"
@@ -479,56 +480,56 @@ msgstr "Enviar"
 
 #: ui/currentcallview.ui:191
 msgid "End this call"
-msgstr ""
+msgstr "Finalitza aquesta trucada"
 
 #: ui/currentcallview.ui:195 ui/currentcallview.ui:356
 msgid "End call"
-msgstr ""
+msgstr "Finalitza la trucada"
 
 #: ui/currentcallview.ui:213
 msgid "Toggle hold"
-msgstr ""
+msgstr "Mantenir en espera"
 
 #: ui/currentcallview.ui:217 ui/currentcallview.ui:239
 #: ui/currentcallview.ui:347
 msgid "Hold"
-msgstr ""
+msgstr "En espera"
 
 #: ui/currentcallview.ui:235
 msgid "Toggle mute audio"
-msgstr ""
+msgstr "Activa silenci d'àudio"
 
 #: ui/currentcallview.ui:257
 msgid "Toggle mute video"
-msgstr ""
+msgstr "Activa silenci de vídeo"
 
 #: ui/currentcallview.ui:261 ui/currentcallview.ui:338
 msgid "Mute video"
-msgstr ""
+msgstr "Silencia el vídeo"
 
 #: ui/currentcallview.ui:280
 msgid "Toggle record audio"
-msgstr ""
+msgstr "Activa silenci"
 
 #: ui/currentcallview.ui:283
 msgid "Record audio"
-msgstr ""
+msgstr "Grava l'àudio"
 
 #: ui/currentcallview.ui:299
 msgid "Toggle show chat"
-msgstr ""
+msgstr "Mostra el xat"
 
 #: ui/currentcallview.ui:303 ui/currentcallview.ui:320
 msgid "Chat"
-msgstr ""
+msgstr "Xat"
 
 #: ui/currentcallview.ui:329
 msgid "Mute audio"
-msgstr ""
+msgstr "Silencia l'àudio"
 
 #: ui/currentcallview.ui:365
 msgid "Record"
-msgstr ""
+msgstr "Grava"
 
 #: ui/editcontactview.ui:12
 msgid "Select addressbook"
@@ -536,7 +537,7 @@ msgstr ""
 
 #: ui/editcontactview.ui:15
 msgid "Addressbook"
-msgstr ""
+msgstr "Llibreta d'adreces"
 
 #: ui/editcontactview.ui:29
 msgid "Name"
@@ -544,7 +545,7 @@ msgstr "Nom"
 
 #: ui/editcontactview.ui:32
 msgid "Contact name"
-msgstr ""
+msgstr "Nom de contacte"
 
 #: ui/editcontactview.ui:47
 msgid "Select how this number will be categorized"
@@ -560,19 +561,19 @@ msgstr ""
 
 #: ui/editcontactview.ui:72
 msgid "Number or Ring ID"
-msgstr ""
+msgstr "Nombre o Ring ID"
 
 #: ui/editcontactview.ui:83
 msgid "Save"
-msgstr ""
+msgstr "Desa"
 
 #: ui/generalsettingsview.ui:32
 msgid "<b>Ring Settings</b>"
-msgstr ""
+msgstr "<b>Opcions de Ring</b>"
 
 #: ui/generalsettingsview.ui:46
 msgid "Start Ring on login"
-msgstr ""
+msgstr "Obre Ring a l'inici"
 
 #: ui/generalsettingsview.ui:55
 msgid "Hide Ring on close instead of quitting."
@@ -604,23 +605,23 @@ msgstr ""
 
 #: ui/generalsettingsview.ui:160
 msgid "Clear all history"
-msgstr ""
+msgstr "Neteja l'historial"
 
 #: ui/incomingcallview.ui:88
 msgid "Incoming..."
-msgstr ""
+msgstr "Entrant..."
 
 #: ui/incomingcallview.ui:122
 msgid "   Accept"
-msgstr ""
+msgstr "Accepta"
 
 #: ui/incomingcallview.ui:137
 msgid "   Reject"
-msgstr ""
+msgstr "Rebutja"
 
 #: ui/incomingcallview.ui:152
 msgid "   Hang-up"
-msgstr ""
+msgstr "Penja"
 
 #: ui/mediasettingsview.ui:36
 msgid "Audio manager:"
@@ -644,88 +645,88 @@ msgstr ""
 
 #: ui/mediasettingsview.ui:163
 msgid "Device:"
-msgstr ""
+msgstr "Dispositiu"
 
 #: ui/mediasettingsview.ui:175
 msgid "Channel:"
-msgstr ""
+msgstr "Canal:"
 
 #: ui/mediasettingsview.ui:187
 msgid "Resolution:"
-msgstr ""
+msgstr "Resolució"
 
 #: ui/mediasettingsview.ui:199
 msgid "Frame rate:"
-msgstr ""
+msgstr "Velocitat de fotogrames"
 
 #: ui/mediasettingsview.ui:258
 msgid "<b>Camera Settings</b>"
-msgstr ""
+msgstr "<b>Opcions de Càmera</b>"
 
 #: ui/ringgearsmenu.ui:13
 msgid "_About"
-msgstr ""
+msgstr "_Sobre"
 
 #: ui/ringgearsmenu.ui:19
 msgid "_Quit"
-msgstr ""
+msgstr "_Tanca"
 
 #: ui/ringmainwindow.ui:20
 msgid "Menu"
-msgstr ""
+msgstr "Menú"
 
 #: ui/ringmainwindow.ui:54
 msgid "General"
-msgstr ""
+msgstr "General"
 
 #: ui/ringmainwindow.ui:64
 msgid "Media"
-msgstr ""
+msgstr "Mitjans"
 
 #: ui/ringmainwindow.ui:75
 msgid "Accounts"
-msgstr ""
+msgstr "Comptes"
 
 #: ui/ringmainwindow.ui:93
 msgid "Settings"
-msgstr ""
+msgstr "Opcions"
 
 #: ui/ringmainwindow.ui:192
 msgid "Conversations"
-msgstr ""
+msgstr "Converses"
 
 #: ui/ringmainwindow.ui:211
 msgid "Contacts"
-msgstr ""
+msgstr "Contactes"
 
 #: ui/ringmainwindow.ui:230
 msgid "History"
-msgstr ""
+msgstr "Historial"
 
 #: ui/ringmainwindow.ui:290
 msgid "Welcome to  "
-msgstr ""
+msgstr "Benvingut a"
 
 #: ui/ringmainwindow.ui:307
 msgid "Enter your alias to get started:"
-msgstr ""
+msgstr "Introduïu el vostre àlies per començar:"
 
 #: ui/ringmainwindow.ui:324
 msgid "Generating your Ring account..."
-msgstr ""
+msgstr "Generant el vostre compte de Ring..."
 
 #: ui/ringmainwindow.ui:338
 msgid "Next"
-msgstr ""
+msgstr "Següent"
 
 #: ui/ringmainwindow.ui:360
 msgid "Your Ring account has been created with the following Ring ID:"
-msgstr ""
+msgstr "El vostre compte de Ring ha sigut creat amb el següent Ring ID:"
 
 #: ui/ringmainwindow.ui:375
 msgid "Share it with your friends so they can contact you via Ring!"
-msgstr ""
+msgstr "Compartiu amb els vostres amics per que puguen contactar-vos a través de Ring!"
 
 #: ui/ringmainwindow.ui:380
 msgid "Done"
-msgstr ""
+msgstr "Fet"
diff --git a/client-gnome/po/ca.po b/client-gnome/po/el.po
similarity index 97%
copy from client-gnome/po/ca.po
copy to client-gnome/po/el.po
index 280e138..55c6052 100644
--- a/client-gnome/po/ca.po
+++ b/client-gnome/po/el.po
@@ -3,29 +3,28 @@
 # This file is distributed under the same license as the Ring package.
 # 
 # Translators:
-# David <stakewinner00 at mykolab.com>, 2015
 msgid ""
 msgstr ""
 "Project-Id-Version: Ring\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2015-11-13 09:43-0500\n"
-"PO-Revision-Date: 2016-03-24 20:09+0000\n"
+"PO-Revision-Date: 2016-06-06 20:47+0000\n"
 "Last-Translator: Guillaume Roguez\n"
-"Language-Team: Catalan (http://www.transifex.com/savoirfairelinux/ring/language/ca/)\n"
+"Language-Team: Greek (http://www.transifex.com/savoirfairelinux/ring/language/el/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Language: ca\n"
+"Language: el\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
 #: src/accountaudiotab.cpp:185 src/accountvideotab.cpp:194
 msgid "Enabled"
-msgstr "Habilitat"
+msgstr ""
 
 #: src/accountaudiotab.cpp:191
 msgctxt "Name of the codec"
 msgid "Name"
-msgstr "Nom"
+msgstr "Όνομα"
 
 #: src/accountaudiotab.cpp:195 src/accountvideotab.cpp:204
 msgid "Bitrate"
@@ -41,7 +40,7 @@ msgstr ""
 
 #: src/accountgeneraltab.cpp:221
 msgid "Type"
-msgstr ""
+msgstr "Τύπος"
 
 #: src/accountgeneraltab.cpp:250
 msgid "auto-generating..."
@@ -49,7 +48,7 @@ msgstr ""
 
 #: src/accountgeneraltab.cpp:269
 msgid "Hostname"
-msgstr ""
+msgstr "Hostname"
 
 #: src/accountgeneraltab.cpp:279
 msgid "Username"
@@ -91,7 +90,7 @@ msgstr ""
 #: src/accountvideotab.cpp:200
 msgctxt "The name of the codec"
 msgid "Name"
-msgstr "Nom"
+msgstr "Όνομα"
 
 #: src/accountview.cpp:159
 msgctxt "Account settings"
@@ -116,7 +115,7 @@ msgstr ""
 #: src/accountview.cpp:175
 msgctxt "Account settings"
 msgid "Security"
-msgstr "Seguretat"
+msgstr ""
 
 #: src/accountview.cpp:229
 #, c-format
@@ -130,7 +129,7 @@ msgstr ""
 #: src/accountview.cpp:399
 msgctxt "Account state column"
 msgid "Enabled"
-msgstr "Habilitat"
+msgstr ""
 
 #: src/accountview.cpp:405
 msgctxt "Account alias (name) column"
@@ -191,7 +190,7 @@ msgstr ""
 #: src/historyview.cpp:447
 msgctxt "Call history"
 msgid "Date"
-msgstr ""
+msgstr "Ημερομηνία"
 
 #: src/ringnotify.cpp:86
 msgid "Incoming call"
@@ -224,7 +223,7 @@ msgstr ""
 #: src/backends/edscontactbackend.cpp:221
 msgctxt "Backend type"
 msgid "Contacts"
-msgstr ""
+msgstr "Επαφές"
 
 #: src/utils/menus.cpp:67
 msgid "_Add to contact"
@@ -309,7 +308,7 @@ msgstr ""
 
 #: ui/accountadvancedtab.ui:310
 msgid "Port"
-msgstr ""
+msgstr "Port"
 
 #: ui/accountadvancedtab.ui:336
 msgid "Use STUN"
@@ -415,7 +414,7 @@ msgstr ""
 
 #: ui/accountsecuritytab.ui:220
 msgid "Private key"
-msgstr "Clau privada"
+msgstr ""
 
 #: ui/accountsecuritytab.ui:243
 msgid "Private key password"
@@ -475,7 +474,7 @@ msgstr ""
 
 #: ui/currentcallview.ui:73
 msgid "Send"
-msgstr "Enviar"
+msgstr ""
 
 #: ui/currentcallview.ui:191
 msgid "End this call"
@@ -492,7 +491,7 @@ msgstr ""
 #: ui/currentcallview.ui:217 ui/currentcallview.ui:239
 #: ui/currentcallview.ui:347
 msgid "Hold"
-msgstr ""
+msgstr "Αναμονή"
 
 #: ui/currentcallview.ui:235
 msgid "Toggle mute audio"
@@ -540,7 +539,7 @@ msgstr ""
 
 #: ui/editcontactview.ui:29
 msgid "Name"
-msgstr "Nom"
+msgstr "Όνομα"
 
 #: ui/editcontactview.ui:32
 msgid "Contact name"
@@ -696,11 +695,11 @@ msgstr ""
 
 #: ui/ringmainwindow.ui:211
 msgid "Contacts"
-msgstr ""
+msgstr "Επαφές"
 
 #: ui/ringmainwindow.ui:230
 msgid "History"
-msgstr ""
+msgstr "Ιστορικό"
 
 #: ui/ringmainwindow.ui:290
 msgid "Welcome to  "
diff --git a/client-gnome/po/es.po b/client-gnome/po/es.po
index f4a97db..2073bad 100644
--- a/client-gnome/po/es.po
+++ b/client-gnome/po/es.po
@@ -6,6 +6,7 @@
 # David <stakewinner00 at mykolab.com>, 2015
 # Emiliano Ariel Vazquez <emilianovazquez at gmail.com>, 2015
 # Ernesto Rodriguez Ortiz <ernesto.rodriguezortiz at savoirfairelinux.com>, 2015-2016
+# Juanjo Faico <juanjofaico22 at openmailbox.org>, 2016
 # Jusore Mondos <jusore at gmail.com>, 2016
 # Stepan Salenikovich, 2015
 msgid ""
@@ -13,8 +14,8 @@ msgstr ""
 "Project-Id-Version: Ring\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2015-11-13 09:43-0500\n"
-"PO-Revision-Date: 2016-03-29 03:06+0000\n"
-"Last-Translator: Ernesto Rodriguez Ortiz <ernesto.rodriguezortiz at savoirfairelinux.com>\n"
+"PO-Revision-Date: 2016-04-29 17:51+0000\n"
+"Last-Translator: Juanjo Faico <juanjofaico22 at openmailbox.org>\n"
 "Language-Team: Spanish (http://www.transifex.com/savoirfairelinux/ring/language/es/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
@@ -668,7 +669,7 @@ msgstr "<b>Configuración de la cámara</b>"
 
 #: ui/ringgearsmenu.ui:13
 msgid "_About"
-msgstr "_Sobre"
+msgstr "_Acerca de"
 
 #: ui/ringgearsmenu.ui:19
 msgid "_Quit"
diff --git a/client-gnome/po/nl.po b/client-gnome/po/fi.po
similarity index 97%
copy from client-gnome/po/nl.po
copy to client-gnome/po/fi.po
index 3cdd9e3..0348a73 100644
--- a/client-gnome/po/nl.po
+++ b/client-gnome/po/fi.po
@@ -8,13 +8,13 @@ msgstr ""
 "Project-Id-Version: Ring\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2015-11-13 09:43-0500\n"
-"PO-Revision-Date: 2016-03-24 20:09+0000\n"
-"Last-Translator: Guillaume Roguez\n"
-"Language-Team: Dutch (http://www.transifex.com/savoirfairelinux/ring/language/nl/)\n"
+"PO-Revision-Date: 2015-09-10 22:02+0000\n"
+"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
+"Language-Team: Finnish (http://www.transifex.com/savoirfairelinux/ring/language/fi/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Language: nl\n"
+"Language: fi\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
 #: src/accountaudiotab.cpp:185 src/accountvideotab.cpp:194
@@ -24,7 +24,7 @@ msgstr ""
 #: src/accountaudiotab.cpp:191
 msgctxt "Name of the codec"
 msgid "Name"
-msgstr ""
+msgstr "Nimi"
 
 #: src/accountaudiotab.cpp:195 src/accountvideotab.cpp:204
 msgid "Bitrate"
@@ -36,7 +36,7 @@ msgstr ""
 
 #: src/accountgeneraltab.cpp:210
 msgid "Alias"
-msgstr "Alias"
+msgstr ""
 
 #: src/accountgeneraltab.cpp:221
 msgid "Type"
@@ -48,15 +48,15 @@ msgstr ""
 
 #: src/accountgeneraltab.cpp:269
 msgid "Hostname"
-msgstr "Hostnaam"
+msgstr ""
 
 #: src/accountgeneraltab.cpp:279
 msgid "Username"
-msgstr "Gebruikersnaam"
+msgstr ""
 
 #: src/accountgeneraltab.cpp:289
 msgid "Password"
-msgstr "Wachtwoord"
+msgstr ""
 
 #: src/accountgeneraltab.cpp:302
 msgid "Show password"
@@ -90,7 +90,7 @@ msgstr ""
 #: src/accountvideotab.cpp:200
 msgctxt "The name of the codec"
 msgid "Name"
-msgstr ""
+msgstr "Nimi"
 
 #: src/accountview.cpp:159
 msgctxt "Account settings"
@@ -100,12 +100,12 @@ msgstr ""
 #: src/accountview.cpp:163
 msgctxt "Account settings"
 msgid "Audio"
-msgstr ""
+msgstr "Ääni"
 
 #: src/accountview.cpp:167
 msgctxt "Account settings"
 msgid "Video"
-msgstr ""
+msgstr "Video"
 
 #: src/accountview.cpp:171
 msgctxt "Account settings"
@@ -134,7 +134,7 @@ msgstr ""
 #: src/accountview.cpp:405
 msgctxt "Account alias (name) column"
 msgid "Alias"
-msgstr "Alias"
+msgstr ""
 
 #: src/accountview.cpp:409
 msgctxt "Account status column"
@@ -366,11 +366,11 @@ msgstr ""
 
 #: ui/accountaudiotab.ui:59 ui/accountvideotab.ui:59
 msgid "Up"
-msgstr ""
+msgstr "Ylös"
 
 #: ui/accountaudiotab.ui:66 ui/accountvideotab.ui:66
 msgid "Down"
-msgstr ""
+msgstr "Alas"
 
 #: ui/accountaudiotab.ui:77 ui/accountvideotab.ui:77
 msgid "<b>Codecs</b>"
@@ -539,7 +539,7 @@ msgstr ""
 
 #: ui/editcontactview.ui:29
 msgid "Name"
-msgstr ""
+msgstr "Nimi"
 
 #: ui/editcontactview.ui:32
 msgid "Contact name"
diff --git a/client-gnome/po/he.po b/client-gnome/po/he.po
index 3a07d50..6b0ef81 100644
--- a/client-gnome/po/he.po
+++ b/client-gnome/po/he.po
@@ -4,14 +4,14 @@
 # 
 # Translators:
 # FIRST AUTHOR <EMAIL at ADDRESS>, 2014
-# GenghisKhan <genghiskhan at gmx.ca>, 2015
+# GenghisKhan <genghiskhan at gmx.ca>, 2015-2016
 msgid ""
 msgstr ""
 "Project-Id-Version: Ring\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2015-11-13 09:43-0500\n"
-"PO-Revision-Date: 2016-03-24 20:09+0000\n"
-"Last-Translator: Guillaume Roguez\n"
+"PO-Revision-Date: 2016-05-23 00:25+0000\n"
+"Last-Translator: GenghisKhan <genghiskhan at gmx.ca>\n"
 "Language-Team: Hebrew (http://www.transifex.com/savoirfairelinux/ring/language/he/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
@@ -236,7 +236,7 @@ msgctxt ""
 "Please try to make the translation 50 chars or less so that it fits into the"
 " layout"
 msgid "Search contacts or enter number"
-msgstr ""
+msgstr "חפש אנשי קשר או הזן מספר"
 
 #: src/ringwelcomeview.cpp:61
 msgid "fetching RingID..."
@@ -258,11 +258,11 @@ msgstr ""
 
 #: src/video/video_widget.cpp:478
 msgid "Share screen area"
-msgstr ""
+msgstr "שתף אזור מסך"
 
 #: src/video/video_widget.cpp:484
 msgid "Share file"
-msgstr ""
+msgstr "שתף קובץ"
 
 #: ui/accountadvancedtab.ui:81
 msgid "Registration expire timeout (seconds):"
@@ -388,7 +388,7 @@ msgstr "<b>פרמטרים</b>"
 
 #: ui/accountsecuritytab.ui:37
 msgid "Encrypt media streams (SRTP)"
-msgstr ""
+msgstr "הצפן זרמי מדיה (SRTP)"
 
 #: ui/accountsecuritytab.ui:58
 msgid "Key exchange protocol"
@@ -605,11 +605,11 @@ msgstr ""
 
 #: ui/generalsettingsview.ui:160
 msgid "Clear all history"
-msgstr ""
+msgstr "טהר היסטוריה"
 
 #: ui/incomingcallview.ui:88
 msgid "Incoming..."
-msgstr ""
+msgstr "קריאה נכנסת..."
 
 #: ui/incomingcallview.ui:122
 msgid "   Accept"
@@ -693,7 +693,7 @@ msgstr "הגדרות"
 
 #: ui/ringmainwindow.ui:192
 msgid "Conversations"
-msgstr ""
+msgstr "דיונים"
 
 #: ui/ringmainwindow.ui:211
 msgid "Contacts"
diff --git a/client-gnome/po/hr.po b/client-gnome/po/hr.po
index 52f2c06..1f443af 100644
--- a/client-gnome/po/hr.po
+++ b/client-gnome/po/hr.po
@@ -3,13 +3,14 @@
 # This file is distributed under the same license as the Ring package.
 # 
 # Translators:
+# Ivica  Kolić <ikoli at yahoo.com>, 2016
 msgid ""
 msgstr ""
 "Project-Id-Version: Ring\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2015-11-13 09:43-0500\n"
-"PO-Revision-Date: 2016-03-24 20:09+0000\n"
-"Last-Translator: Guillaume Roguez\n"
+"PO-Revision-Date: 2016-06-05 22:50+0000\n"
+"Last-Translator: Ivica  Kolić <ikoli at yahoo.com>\n"
 "Language-Team: Croatian (http://www.transifex.com/savoirfairelinux/ring/language/hr/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
@@ -24,7 +25,7 @@ msgstr "Uključeno"
 #: src/accountaudiotab.cpp:191
 msgctxt "Name of the codec"
 msgid "Name"
-msgstr ""
+msgstr "Ime"
 
 #: src/accountaudiotab.cpp:195 src/accountvideotab.cpp:204
 msgid "Bitrate"
@@ -40,7 +41,7 @@ msgstr "Alias"
 
 #: src/accountgeneraltab.cpp:221
 msgid "Type"
-msgstr ""
+msgstr "Vrsta"
 
 #: src/accountgeneraltab.cpp:250
 msgid "auto-generating..."
@@ -56,7 +57,7 @@ msgstr "Korisničko ime"
 
 #: src/accountgeneraltab.cpp:289
 msgid "Password"
-msgstr ""
+msgstr "Lozinka"
 
 #: src/accountgeneraltab.cpp:302
 msgid "Show password"
@@ -64,11 +65,11 @@ msgstr "Prikaži lozinku"
 
 #: src/accountgeneraltab.cpp:308
 msgid "Proxy"
-msgstr ""
+msgstr "Proxy"
 
 #: src/accountgeneraltab.cpp:318
 msgid "Voicemail number"
-msgstr ""
+msgstr "Broj govorne pošte"
 
 #: src/accountgeneraltab.cpp:330
 msgctxt "The DHT bootstrap server url"
@@ -81,7 +82,7 @@ msgstr "Automatski primi pozive"
 
 #: src/accountgeneraltab.cpp:350
 msgid "UPnP enabled"
-msgstr ""
+msgstr "UPnP omogućen"
 
 #: src/accountgeneraltab.cpp:358
 msgid "DTMF tone type:"
@@ -90,7 +91,7 @@ msgstr ""
 #: src/accountvideotab.cpp:200
 msgctxt "The name of the codec"
 msgid "Name"
-msgstr ""
+msgstr "Ime"
 
 #: src/accountview.cpp:159
 msgctxt "Account settings"
@@ -115,16 +116,16 @@ msgstr "Napredno"
 #: src/accountview.cpp:175
 msgctxt "Account settings"
 msgid "Security"
-msgstr ""
+msgstr "Sigurnost"
 
 #: src/accountview.cpp:229
 #, c-format
 msgid "Are you sure you want to delete account \"%s\"?"
-msgstr ""
+msgstr "Jeste li sigurni da želite izbrisati račun \"%s\"?"
 
 #: src/accountview.cpp:313 src/accountview.cpp:315
 msgid "New Account"
-msgstr ""
+msgstr "Novi račun"
 
 #: src/accountview.cpp:399
 msgctxt "Account state column"
@@ -139,15 +140,15 @@ msgstr "Alias"
 #: src/accountview.cpp:409
 msgctxt "Account status column"
 msgid "Status"
-msgstr ""
+msgstr "Status"
 
 #: src/contactsview.cpp:305
 msgid "_Copy name"
-msgstr ""
+msgstr "_Kopiraj ime"
 
 #: src/contactsview.cpp:316 src/contactsview.cpp:331
 msgid "_Copy number"
-msgstr ""
+msgstr "_Kopiraj broj"
 
 #: src/dialogs.c:53
 msgid "Working..."
@@ -180,7 +181,7 @@ msgstr ""
 
 #: src/historyview.cpp:184
 msgid "_Copy"
-msgstr ""
+msgstr "_Kopiraj"
 
 #: src/historyview.cpp:402
 msgctxt "Call history"
@@ -190,17 +191,17 @@ msgstr "Nazovi"
 #: src/historyview.cpp:447
 msgctxt "Call history"
 msgid "Date"
-msgstr ""
+msgstr "Datum"
 
 #: src/ringnotify.cpp:86
 msgid "Incoming call"
-msgstr ""
+msgstr "Dolazni poziv"
 
 #: src/ringnotify.cpp:169
 #, c-format
 msgctxt "Text message notification"
 msgid "%s says:"
-msgstr ""
+msgstr "%s kaže:"
 
 #: src/ring_client_options.c:65
 msgid "Enable debug"
@@ -214,27 +215,27 @@ msgstr ""
 
 #: src/ring_client_options.c:84
 msgid "- GNOME client for Ring"
-msgstr ""
+msgstr "- GNOME klijent za Ring"
 
 #: src/backends/edscontactbackend.cpp:201
 msgid "Unknown EDS addressbook"
-msgstr ""
+msgstr "Nepoznati EDS adresar"
 
 #: src/backends/edscontactbackend.cpp:221
 msgctxt "Backend type"
 msgid "Contacts"
-msgstr ""
+msgstr "Kontakti"
 
 #: src/utils/menus.cpp:67
 msgid "_Add to contact"
-msgstr ""
+msgstr "_Dodaj u kontakt"
 
 #: src/ringmainwindow.cpp:944
 msgctxt ""
 "Please try to make the translation 50 chars or less so that it fits into the"
 " layout"
 msgid "Search contacts or enter number"
-msgstr ""
+msgstr "Traži kontakt ili unesi broj"
 
 #: src/ringwelcomeview.cpp:61
 msgid "fetching RingID..."
@@ -256,11 +257,11 @@ msgstr ""
 
 #: src/video/video_widget.cpp:478
 msgid "Share screen area"
-msgstr ""
+msgstr "Dijelite područje zaslona"
 
 #: src/video/video_widget.cpp:484
 msgid "Share file"
-msgstr ""
+msgstr "Dijeli datoteku"
 
 #: ui/accountadvancedtab.ui:81
 msgid "Registration expire timeout (seconds):"
@@ -280,23 +281,23 @@ msgstr ""
 
 #: ui/accountadvancedtab.ui:149
 msgid "<b>Registration</b>"
-msgstr ""
+msgstr "<b>Registracija</b>"
 
 #: ui/accountadvancedtab.ui:176
 msgid "Use random port"
-msgstr ""
+msgstr "Koristi nasumični port"
 
 #: ui/accountadvancedtab.ui:197
 msgid "Local port:"
-msgstr ""
+msgstr "Lokalni port:"
 
 #: ui/accountadvancedtab.ui:223
 msgid "<b>Network Interface</b>"
-msgstr ""
+msgstr "<b>Mrežno sučelje</b>"
 
 #: ui/accountadvancedtab.ui:249
 msgid "Same as local parameters"
-msgstr ""
+msgstr "Isto kao i lokalni parametri"
 
 #: ui/accountadvancedtab.ui:264
 msgid "Set published address and port:"
@@ -312,23 +313,23 @@ msgstr "Port"
 
 #: ui/accountadvancedtab.ui:336
 msgid "Use STUN"
-msgstr ""
+msgstr "Koristi STUN"
 
 #: ui/accountadvancedtab.ui:359 ui/accountadvancedtab.ui:408
 msgid "server URL"
-msgstr ""
+msgstr "URL poslužitelja"
 
 #: ui/accountadvancedtab.ui:385
 msgid "Use TURN"
-msgstr ""
+msgstr "Koristi TURN"
 
 #: ui/accountadvancedtab.ui:430
 msgid "username"
-msgstr ""
+msgstr "korisničko ime"
 
 #: ui/accountadvancedtab.ui:451
 msgid "password"
-msgstr ""
+msgstr "lozinka"
 
 #: ui/accountadvancedtab.ui:475
 msgid "realm"
@@ -374,15 +375,15 @@ msgstr "Dolje"
 
 #: ui/accountaudiotab.ui:77 ui/accountvideotab.ui:77
 msgid "<b>Codecs</b>"
-msgstr ""
+msgstr "<b>Kodeci</b>"
 
 #: ui/accountgeneraltab.ui:42
 msgid "<b>Account</b>"
-msgstr ""
+msgstr "<b>Račun</b>"
 
 #: ui/accountgeneraltab.ui:80
 msgid "<b>Parameters</b>"
-msgstr ""
+msgstr "<b>Parametri</b>"
 
 #: ui/accountsecuritytab.ui:37
 msgid "Encrypt media streams (SRTP)"
@@ -414,19 +415,19 @@ msgstr ""
 
 #: ui/accountsecuritytab.ui:220
 msgid "Private key"
-msgstr ""
+msgstr "Privatni ključ"
 
 #: ui/accountsecuritytab.ui:243
 msgid "Private key password"
-msgstr ""
+msgstr "Lozinka privatnog ključa"
 
 #: ui/accountsecuritytab.ui:290
 msgid "TLS protocol method"
-msgstr ""
+msgstr "Metoda TSL protokola"
 
 #: ui/accountsecuritytab.ui:313
 msgid "Outgoing TLS server name"
-msgstr ""
+msgstr "Ime odlaznoga TSL poslužitelja"
 
 #: ui/accountsecuritytab.ui:335
 msgid "Negotiation timeout (seconds)"
@@ -458,31 +459,31 @@ msgstr ""
 
 #: ui/accountvideotab.ui:90
 msgid "Enable Video"
-msgstr ""
+msgstr "Omogući video"
 
 #: ui/accountview.ui:59
 msgid "<b>−</b>"
-msgstr ""
+msgstr "<b>−</b>"
 
 #: ui/accountview.ui:83
 msgid "<b>+</b>"
-msgstr ""
+msgstr "<b>+</b>"
 
 #: ui/choosecontactview.ui:34
 msgid "Create New"
-msgstr ""
+msgstr "Napravi novi"
 
 #: ui/currentcallview.ui:73
 msgid "Send"
-msgstr ""
+msgstr "Pošalji"
 
 #: ui/currentcallview.ui:191
 msgid "End this call"
-msgstr ""
+msgstr "Završi ovaj poziv"
 
 #: ui/currentcallview.ui:195 ui/currentcallview.ui:356
 msgid "End call"
-msgstr ""
+msgstr "Završi poziv"
 
 #: ui/currentcallview.ui:213
 msgid "Toggle hold"
@@ -511,7 +512,7 @@ msgstr ""
 
 #: ui/currentcallview.ui:283
 msgid "Record audio"
-msgstr ""
+msgstr "Snimaj audio"
 
 #: ui/currentcallview.ui:299
 msgid "Toggle show chat"
@@ -519,7 +520,7 @@ msgstr ""
 
 #: ui/currentcallview.ui:303 ui/currentcallview.ui:320
 msgid "Chat"
-msgstr ""
+msgstr "Čavrljanje"
 
 #: ui/currentcallview.ui:329
 msgid "Mute audio"
@@ -527,27 +528,27 @@ msgstr ""
 
 #: ui/currentcallview.ui:365
 msgid "Record"
-msgstr ""
+msgstr "Snimaj"
 
 #: ui/editcontactview.ui:12
 msgid "Select addressbook"
-msgstr ""
+msgstr "Odaberi adresar"
 
 #: ui/editcontactview.ui:15
 msgid "Addressbook"
-msgstr ""
+msgstr "Adresar"
 
 #: ui/editcontactview.ui:29
 msgid "Name"
-msgstr ""
+msgstr "Ime"
 
 #: ui/editcontactview.ui:32
 msgid "Contact name"
-msgstr ""
+msgstr "Ime kontakta"
 
 #: ui/editcontactview.ui:47
 msgid "Select how this number will be categorized"
-msgstr ""
+msgstr "Odaberite kako će ovaj broj biti kategoriziran"
 
 #: ui/editcontactview.ui:50
 msgid "Number category"
@@ -563,11 +564,11 @@ msgstr ""
 
 #: ui/editcontactview.ui:83
 msgid "Save"
-msgstr ""
+msgstr "Spremi"
 
 #: ui/generalsettingsview.ui:32
 msgid "<b>Ring Settings</b>"
-msgstr ""
+msgstr "<b>Ring postavke</b>"
 
 #: ui/generalsettingsview.ui:46
 msgid "Start Ring on login"
@@ -591,19 +592,19 @@ msgstr ""
 
 #: ui/generalsettingsview.ui:110
 msgid "<b>History Settings</b>"
-msgstr ""
+msgstr "<b>Postavke povijesti</b>"
 
 #: ui/generalsettingsview.ui:128
 msgid "Keep history for (days):"
-msgstr ""
+msgstr "Zadrži povijest (dana):"
 
 #: ui/generalsettingsview.ui:151
 msgid "(set to 0 for unlimited history)"
-msgstr ""
+msgstr "(postavi na 0 za neograničenu povijest)"
 
 #: ui/generalsettingsview.ui:160
 msgid "Clear all history"
-msgstr ""
+msgstr "Očisti svu povijest"
 
 #: ui/incomingcallview.ui:88
 msgid "Incoming..."
@@ -611,11 +612,11 @@ msgstr ""
 
 #: ui/incomingcallview.ui:122
 msgid "   Accept"
-msgstr ""
+msgstr "Prihvati"
 
 #: ui/incomingcallview.ui:137
 msgid "   Reject"
-msgstr ""
+msgstr "Odbij"
 
 #: ui/incomingcallview.ui:152
 msgid "   Hang-up"
@@ -627,11 +628,11 @@ msgstr ""
 
 #: ui/mediasettingsview.ui:48
 msgid "Ringtone device:"
-msgstr ""
+msgstr "Uređaj melodija zvona:"
 
 #: ui/mediasettingsview.ui:60
 msgid "Output device:"
-msgstr ""
+msgstr "Izlazni uređaj:"
 
 #: ui/mediasettingsview.ui:72
 msgid "Input device:"
@@ -639,19 +640,19 @@ msgstr ""
 
 #: ui/mediasettingsview.ui:127
 msgid "<b>Audio Settings</b>"
-msgstr ""
+msgstr "<b>Audio postavke</b>"
 
 #: ui/mediasettingsview.ui:163
 msgid "Device:"
-msgstr ""
+msgstr "Uređaj:"
 
 #: ui/mediasettingsview.ui:175
 msgid "Channel:"
-msgstr ""
+msgstr "Kanal:"
 
 #: ui/mediasettingsview.ui:187
 msgid "Resolution:"
-msgstr ""
+msgstr "Razlučivost:"
 
 #: ui/mediasettingsview.ui:199
 msgid "Frame rate:"
@@ -659,19 +660,19 @@ msgstr ""
 
 #: ui/mediasettingsview.ui:258
 msgid "<b>Camera Settings</b>"
-msgstr ""
+msgstr "<b>Postavke kamere</b>"
 
 #: ui/ringgearsmenu.ui:13
 msgid "_About"
-msgstr ""
+msgstr "_O programu"
 
 #: ui/ringgearsmenu.ui:19
 msgid "_Quit"
-msgstr ""
+msgstr "_Prekini"
 
 #: ui/ringmainwindow.ui:20
 msgid "Menu"
-msgstr ""
+msgstr "Izbornik"
 
 #: ui/ringmainwindow.ui:54
 msgid "General"
@@ -679,7 +680,7 @@ msgstr "Opće"
 
 #: ui/ringmainwindow.ui:64
 msgid "Media"
-msgstr ""
+msgstr "Medij"
 
 #: ui/ringmainwindow.ui:75
 msgid "Accounts"
@@ -691,11 +692,11 @@ msgstr "Postavke"
 
 #: ui/ringmainwindow.ui:192
 msgid "Conversations"
-msgstr ""
+msgstr "Razgovori"
 
 #: ui/ringmainwindow.ui:211
 msgid "Contacts"
-msgstr ""
+msgstr "Kontakti"
 
 #: ui/ringmainwindow.ui:230
 msgid "History"
@@ -703,7 +704,7 @@ msgstr "Povijest"
 
 #: ui/ringmainwindow.ui:290
 msgid "Welcome to  "
-msgstr ""
+msgstr "Dobrodošli u"
 
 #: ui/ringmainwindow.ui:307
 msgid "Enter your alias to get started:"
@@ -715,7 +716,7 @@ msgstr ""
 
 #: ui/ringmainwindow.ui:338
 msgid "Next"
-msgstr ""
+msgstr "Slijedeće"
 
 #: ui/ringmainwindow.ui:360
 msgid "Your Ring account has been created with the following Ring ID:"
@@ -723,8 +724,8 @@ msgstr ""
 
 #: ui/ringmainwindow.ui:375
 msgid "Share it with your friends so they can contact you via Ring!"
-msgstr ""
+msgstr "Podijelite sa vašim prijateljima da vas mogu kontaktirati putem Ringa!"
 
 #: ui/ringmainwindow.ui:380
 msgid "Done"
-msgstr ""
+msgstr "Učinjeno"
diff --git a/client-gnome/po/nl.po b/client-gnome/po/nl.po
index 3cdd9e3..3e0d85f 100644
--- a/client-gnome/po/nl.po
+++ b/client-gnome/po/nl.po
@@ -3,13 +3,14 @@
 # This file is distributed under the same license as the Ring package.
 # 
 # Translators:
+# Niels van Duijkeren <nielsvanduijkeren at gmail.com>, 2016
 msgid ""
 msgstr ""
 "Project-Id-Version: Ring\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2015-11-13 09:43-0500\n"
-"PO-Revision-Date: 2016-03-24 20:09+0000\n"
-"Last-Translator: Guillaume Roguez\n"
+"PO-Revision-Date: 2016-05-30 14:33+0000\n"
+"Last-Translator: Niels van Duijkeren <nielsvanduijkeren at gmail.com>\n"
 "Language-Team: Dutch (http://www.transifex.com/savoirfairelinux/ring/language/nl/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
@@ -19,20 +20,20 @@ msgstr ""
 
 #: src/accountaudiotab.cpp:185 src/accountvideotab.cpp:194
 msgid "Enabled"
-msgstr ""
+msgstr "Ingeschakeld"
 
 #: src/accountaudiotab.cpp:191
 msgctxt "Name of the codec"
 msgid "Name"
-msgstr ""
+msgstr "Naam"
 
 #: src/accountaudiotab.cpp:195 src/accountvideotab.cpp:204
 msgid "Bitrate"
-msgstr ""
+msgstr "Bitrate"
 
 #: src/accountaudiotab.cpp:199
 msgid "Samplerate"
-msgstr ""
+msgstr "Samplerate"
 
 #: src/accountgeneraltab.cpp:210
 msgid "Alias"
@@ -40,11 +41,11 @@ msgstr "Alias"
 
 #: src/accountgeneraltab.cpp:221
 msgid "Type"
-msgstr ""
+msgstr "Type"
 
 #: src/accountgeneraltab.cpp:250
 msgid "auto-generating..."
-msgstr ""
+msgstr "automatisch genereren..."
 
 #: src/accountgeneraltab.cpp:269
 msgid "Hostname"
@@ -60,76 +61,76 @@ msgstr "Wachtwoord"
 
 #: src/accountgeneraltab.cpp:302
 msgid "Show password"
-msgstr ""
+msgstr "Wachtwoord tonen"
 
 #: src/accountgeneraltab.cpp:308
 msgid "Proxy"
-msgstr ""
+msgstr "Proxy"
 
 #: src/accountgeneraltab.cpp:318
 msgid "Voicemail number"
-msgstr ""
+msgstr "Voicemail nummer"
 
 #: src/accountgeneraltab.cpp:330
 msgctxt "The DHT bootstrap server url"
 msgid "Bootstrap"
-msgstr ""
+msgstr "Bootstrap"
 
 #: src/accountgeneraltab.cpp:342
 msgid "Auto-answer calls"
-msgstr ""
+msgstr "Oproepen automatisch beantwoorden"
 
 #: src/accountgeneraltab.cpp:350
 msgid "UPnP enabled"
-msgstr ""
+msgstr "UPnP ingeschakeld"
 
 #: src/accountgeneraltab.cpp:358
 msgid "DTMF tone type:"
-msgstr ""
+msgstr "Type kiestoon (DTMF):"
 
 #: src/accountvideotab.cpp:200
 msgctxt "The name of the codec"
 msgid "Name"
-msgstr ""
+msgstr "Naam"
 
 #: src/accountview.cpp:159
 msgctxt "Account settings"
 msgid "General"
-msgstr ""
+msgstr "Algemeen"
 
 #: src/accountview.cpp:163
 msgctxt "Account settings"
 msgid "Audio"
-msgstr ""
+msgstr "Geluid"
 
 #: src/accountview.cpp:167
 msgctxt "Account settings"
 msgid "Video"
-msgstr ""
+msgstr "Video"
 
 #: src/accountview.cpp:171
 msgctxt "Account settings"
 msgid "Advanced"
-msgstr ""
+msgstr "Geavanceerd"
 
 #: src/accountview.cpp:175
 msgctxt "Account settings"
 msgid "Security"
-msgstr ""
+msgstr "Beveiliging"
 
 #: src/accountview.cpp:229
 #, c-format
 msgid "Are you sure you want to delete account \"%s\"?"
-msgstr ""
+msgstr "Weet u zeker dat u het account \"%s\" wilt verwijderen?"
 
 #: src/accountview.cpp:313 src/accountview.cpp:315
 msgid "New Account"
-msgstr ""
+msgstr "Account aanmaken"
 
 #: src/accountview.cpp:399
 msgctxt "Account state column"
 msgid "Enabled"
-msgstr ""
+msgstr "Ingeschakeld"
 
 #: src/accountview.cpp:405
 msgctxt "Account alias (name) column"
@@ -139,19 +140,19 @@ msgstr "Alias"
 #: src/accountview.cpp:409
 msgctxt "Account status column"
 msgid "Status"
-msgstr ""
+msgstr "Status"
 
 #: src/contactsview.cpp:305
 msgid "_Copy name"
-msgstr ""
+msgstr "_Naam kopiëren"
 
 #: src/contactsview.cpp:316 src/contactsview.cpp:331
 msgid "_Copy number"
-msgstr ""
+msgstr "_Nummer kopiëren"
 
 #: src/dialogs.c:53
 msgid "Working..."
-msgstr ""
+msgstr "Bezig..."
 
 #: src/dialogs.c:84
 #, c-format
@@ -159,572 +160,572 @@ msgctxt "Do not translate the release name"
 msgid ""
 "release: Louis-Joseph Papineau\n"
 "v%d.%d.%d - %.10s"
-msgstr ""
+msgstr "release: Louis-Joseph Papineau\nv%d.%d.%d - %.10s"
 
 #: src/dialogs.c:111
 msgid ""
 "The GNOME client for Ring.\n"
 "Ring is a secured and distributed communication software."
-msgstr ""
+msgstr "De GNOME client voor Ring.\nRing is software voor beveiligde en gedistribueerde communicatie."
 
 #: src/editcontactview.cpp:196
 msgctxt "Phone number category"
 msgid "home"
-msgstr ""
+msgstr "thuis"
 
 #: src/generalsettingsview.cpp:94
 msgid ""
 "Are you sure you want to clear all your history?\n"
 "This operation will also reset the Frequent Contacts list"
-msgstr ""
+msgstr "Weet u zeker dat u de geschiedenis wilt wissen?\nDeze actie zal ook de Frequente Contacten lijst resetten."
 
 #: src/historyview.cpp:184
 msgid "_Copy"
-msgstr ""
+msgstr "_Kopiëren"
 
 #: src/historyview.cpp:402
 msgctxt "Call history"
 msgid "Call"
-msgstr ""
+msgstr "Oproep"
 
 #: src/historyview.cpp:447
 msgctxt "Call history"
 msgid "Date"
-msgstr ""
+msgstr "Datum"
 
 #: src/ringnotify.cpp:86
 msgid "Incoming call"
-msgstr ""
+msgstr "Binnenkomende oproep"
 
 #: src/ringnotify.cpp:169
 #, c-format
 msgctxt "Text message notification"
 msgid "%s says:"
-msgstr ""
+msgstr "%s schrijft:"
 
 #: src/ring_client_options.c:65
 msgid "Enable debug"
-msgstr ""
+msgstr "Foutopsporing inschakelen"
 
 #: src/ring_client_options.c:67
 msgid ""
 "Restores the hidden state of the main window (only applicable to the primary"
 " instance)"
-msgstr ""
+msgstr "Herstelt de verborgen status van het hoofdscherm (alleen van toepassing op het primaire proces)"
 
 #: src/ring_client_options.c:84
 msgid "- GNOME client for Ring"
-msgstr ""
+msgstr "- GNOME client voor Ring"
 
 #: src/backends/edscontactbackend.cpp:201
 msgid "Unknown EDS addressbook"
-msgstr ""
+msgstr "Onbekend EDS adresboek"
 
 #: src/backends/edscontactbackend.cpp:221
 msgctxt "Backend type"
 msgid "Contacts"
-msgstr ""
+msgstr "Contacten"
 
 #: src/utils/menus.cpp:67
 msgid "_Add to contact"
-msgstr ""
+msgstr "_Aan contact toevoegen"
 
 #: src/ringmainwindow.cpp:944
 msgctxt ""
 "Please try to make the translation 50 chars or less so that it fits into the"
 " layout"
 msgid "Search contacts or enter number"
-msgstr ""
+msgstr "Zoek contacten of geef nummer in"
 
 #: src/ringwelcomeview.cpp:61
 msgid "fetching RingID..."
-msgstr ""
+msgstr "RingID ophalen..."
 
 #: src/ringwelcomeview.cpp:92
 msgid ""
 "Ring is a secure and distributed voice, video, and chat communication "
 "platform that requires no centralized server and leaves the power of privacy"
 " in the hands of the user."
-msgstr ""
+msgstr "Ring is een veilige en gedistribueerde spraak, video en chat communicatie platform dat geen centrale server vereist en laat de kracht van privacy in handen van de gebruiker."
 
 #: src/ringwelcomeview.cpp:102
 msgctxt "Do not translate \"RingID\""
 msgid ""
 "This is your RingID.\n"
 "Copy and share it with your friends!"
-msgstr ""
+msgstr "Dit is uw RingID.\nDeel hem met uw vrienden!"
 
 #: src/video/video_widget.cpp:478
 msgid "Share screen area"
-msgstr ""
+msgstr "Schermruimte delen"
 
 #: src/video/video_widget.cpp:484
 msgid "Share file"
-msgstr ""
+msgstr "Bestand delen"
 
 #: ui/accountadvancedtab.ui:81
 msgid "Registration expire timeout (seconds):"
-msgstr ""
+msgstr "Registratie verval time-out (seconden):"
 
 #: ui/accountadvancedtab.ui:103
 msgid "Allow calls from unknown peers"
-msgstr ""
+msgstr "Oproepen accepteren van onbekende gebruikers"
 
 #: ui/accountadvancedtab.ui:117
 msgid "Allow calls from peers in your call history"
-msgstr ""
+msgstr "Oproepen accepteren van gebruikers in de oproepgeschiedenis"
 
 #: ui/accountadvancedtab.ui:131
 msgid "Allow calls from peers in your contacts list"
-msgstr ""
+msgstr "Oproepen accepteren van gebruikers in de contactenlijst"
 
 #: ui/accountadvancedtab.ui:149
 msgid "<b>Registration</b>"
-msgstr ""
+msgstr "<b>Registratie</b>"
 
 #: ui/accountadvancedtab.ui:176
 msgid "Use random port"
-msgstr ""
+msgstr "Willekeurige poort gebruiken"
 
 #: ui/accountadvancedtab.ui:197
 msgid "Local port:"
-msgstr ""
+msgstr "Lokale poort:"
 
 #: ui/accountadvancedtab.ui:223
 msgid "<b>Network Interface</b>"
-msgstr ""
+msgstr "<b>Netwerkinterface</b>"
 
 #: ui/accountadvancedtab.ui:249
 msgid "Same as local parameters"
-msgstr ""
+msgstr "Gelijk aan lokale parameters"
 
 #: ui/accountadvancedtab.ui:264
 msgid "Set published address and port:"
-msgstr ""
+msgstr "Gepubliceerde adres en poort:"
 
 #: ui/accountadvancedtab.ui:288
 msgid "Address"
-msgstr ""
+msgstr "Adres"
 
 #: ui/accountadvancedtab.ui:310
 msgid "Port"
-msgstr ""
+msgstr "Poort"
 
 #: ui/accountadvancedtab.ui:336
 msgid "Use STUN"
-msgstr ""
+msgstr "STUN gebruiken"
 
 #: ui/accountadvancedtab.ui:359 ui/accountadvancedtab.ui:408
 msgid "server URL"
-msgstr ""
+msgstr "server URL"
 
 #: ui/accountadvancedtab.ui:385
 msgid "Use TURN"
-msgstr ""
+msgstr "TURN gebruiken"
 
 #: ui/accountadvancedtab.ui:430
 msgid "username"
-msgstr ""
+msgstr "gebruikersnaam"
 
 #: ui/accountadvancedtab.ui:451
 msgid "password"
-msgstr ""
+msgstr "wachtwoord"
 
 #: ui/accountadvancedtab.ui:475
 msgid "realm"
-msgstr ""
+msgstr "realm"
 
 #: ui/accountadvancedtab.ui:504
 msgid "<b>Published Address</b>"
-msgstr ""
+msgstr "<b>Gepubliceerd Adres</b>"
 
 #: ui/accountadvancedtab.ui:533
 msgid ""
 "These settings are only used during SDP session negotiation in case ICE is "
 "not supported by the server or peer."
-msgstr ""
+msgstr "Deze instellingen worden enkel gebruikt tijdens SDP sessie onderhandelingen in geval ICE niet ondersteund wordt door de server of de gebruiker."
 
 #: ui/accountadvancedtab.ui:558 ui/accountadvancedtab.ui:632
 msgid "Min"
-msgstr ""
+msgstr "Min"
 
 #: ui/accountadvancedtab.ui:581 ui/accountadvancedtab.ui:655
 msgid "Max"
-msgstr ""
+msgstr "Max"
 
 #: ui/accountadvancedtab.ui:605
 msgid "<b>Audio RTP Port Range</b>"
-msgstr ""
+msgstr "<b>Audio RTP Poortenreeks</b>"
 
 #: ui/accountadvancedtab.ui:679
 msgid "<b>Video RTP Port Range</b>"
-msgstr ""
+msgstr "<b>Video RTP Poortenreeks</b>"
 
 #: ui/accountadvancedtab.ui:695
 msgid "<b>SDP Session Negotiation (ICE Fallback)</b>"
-msgstr ""
+msgstr "<b>SDP Sessie Onderhandeling (ICE Terugvaloptie)</b>"
 
 #: ui/accountaudiotab.ui:59 ui/accountvideotab.ui:59
 msgid "Up"
-msgstr ""
+msgstr "Hoger"
 
 #: ui/accountaudiotab.ui:66 ui/accountvideotab.ui:66
 msgid "Down"
-msgstr ""
+msgstr "Lager"
 
 #: ui/accountaudiotab.ui:77 ui/accountvideotab.ui:77
 msgid "<b>Codecs</b>"
-msgstr ""
+msgstr "<b>Codecs</b>"
 
 #: ui/accountgeneraltab.ui:42
 msgid "<b>Account</b>"
-msgstr ""
+msgstr "<b>Account</b>"
 
 #: ui/accountgeneraltab.ui:80
 msgid "<b>Parameters</b>"
-msgstr ""
+msgstr "<b>Parameters</b>"
 
 #: ui/accountsecuritytab.ui:37
 msgid "Encrypt media streams (SRTP)"
-msgstr ""
+msgstr "Mediastreams versleutelen (SRTP)"
 
 #: ui/accountsecuritytab.ui:58
 msgid "Key exchange protocol"
-msgstr ""
+msgstr "Sleuteluitwisselingsprotocol"
 
 #: ui/accountsecuritytab.ui:76
 msgid "Fallback on RTP on encryption failure"
-msgstr ""
+msgstr "RTP gebruiken bij mislukte versleuteling"
 
 #: ui/accountsecuritytab.ui:94
 msgid "<b>Media Stream Encryption</b>"
-msgstr ""
+msgstr "<b>Mediastream Versleuteling</b>"
 
 #: ui/accountsecuritytab.ui:121
 msgid "Encrypt negotiation (TLS)"
-msgstr ""
+msgstr "Onderhandeling versleutelen (TLS)"
 
 #: ui/accountsecuritytab.ui:146
 msgid "CA certificate"
-msgstr ""
+msgstr "CA certificaat"
 
 #: ui/accountsecuritytab.ui:183
 msgid "User certificate"
-msgstr ""
+msgstr "Gebruikerscertificaat"
 
 #: ui/accountsecuritytab.ui:220
 msgid "Private key"
-msgstr ""
+msgstr "Persoonlijke sleutel"
 
 #: ui/accountsecuritytab.ui:243
 msgid "Private key password"
-msgstr ""
+msgstr "Wachtwoord persoonlijke sleutel"
 
 #: ui/accountsecuritytab.ui:290
 msgid "TLS protocol method"
-msgstr ""
+msgstr "TLS protocol methode"
 
 #: ui/accountsecuritytab.ui:313
 msgid "Outgoing TLS server name"
-msgstr ""
+msgstr "Uitgaande TLS servernaam"
 
 #: ui/accountsecuritytab.ui:335
 msgid "Negotiation timeout (seconds)"
-msgstr ""
+msgstr "Tijdslimiet onderhandeling (seconden)"
 
 #: ui/accountsecuritytab.ui:369
 msgid "Use default ciphers"
-msgstr ""
+msgstr "Standaard codering gebruiken"
 
 #: ui/accountsecuritytab.ui:385
 msgid "Use custom cipher list"
-msgstr ""
+msgstr "Aangepaste codering gebruiken"
 
 #: ui/accountsecuritytab.ui:442
 msgid "Verify incoming certificates (server side)"
-msgstr ""
+msgstr "Binnenkomende certificaten verifiëren (serverzijde)"
 
 #: ui/accountsecuritytab.ui:457
 msgid "Verify answer certificates (client side)"
-msgstr ""
+msgstr "Uitgaande certificaten verifiëren (clientzijde)"
 
 #: ui/accountsecuritytab.ui:472
 msgid "Require a certificate for incoming TLS connections"
-msgstr ""
+msgstr "Certificaat voor binnenkomende TLS verbindingen vereisen"
 
 #: ui/accountsecuritytab.ui:491
 msgid "<b>Negotiation Encryption</b>"
-msgstr ""
+msgstr "<b>Onderhandeling Versleuteling</b>"
 
 #: ui/accountvideotab.ui:90
 msgid "Enable Video"
-msgstr ""
+msgstr "Video inschakelen"
 
 #: ui/accountview.ui:59
 msgid "<b>−</b>"
-msgstr ""
+msgstr "<b>−</b>"
 
 #: ui/accountview.ui:83
 msgid "<b>+</b>"
-msgstr ""
+msgstr "<b>+</b>"
 
 #: ui/choosecontactview.ui:34
 msgid "Create New"
-msgstr ""
+msgstr "Nieuw Aanmaken"
 
 #: ui/currentcallview.ui:73
 msgid "Send"
-msgstr ""
+msgstr "Versturen"
 
 #: ui/currentcallview.ui:191
 msgid "End this call"
-msgstr ""
+msgstr "Deze oproep beëindigen "
 
 #: ui/currentcallview.ui:195 ui/currentcallview.ui:356
 msgid "End call"
-msgstr ""
+msgstr "Oproep beëindigen"
 
 #: ui/currentcallview.ui:213
 msgid "Toggle hold"
-msgstr ""
+msgstr "Wacht in/uitschakelen"
 
 #: ui/currentcallview.ui:217 ui/currentcallview.ui:239
 #: ui/currentcallview.ui:347
 msgid "Hold"
-msgstr ""
+msgstr "In wacht zetten"
 
 #: ui/currentcallview.ui:235
 msgid "Toggle mute audio"
-msgstr ""
+msgstr "Geluid in/uitschakelen"
 
 #: ui/currentcallview.ui:257
 msgid "Toggle mute video"
-msgstr ""
+msgstr "Video in/uitschakelen"
 
 #: ui/currentcallview.ui:261 ui/currentcallview.ui:338
 msgid "Mute video"
-msgstr ""
+msgstr "Video uitschakelen"
 
 #: ui/currentcallview.ui:280
 msgid "Toggle record audio"
-msgstr ""
+msgstr "Geluid opname in/uitschakelen"
 
 #: ui/currentcallview.ui:283
 msgid "Record audio"
-msgstr ""
+msgstr "Geluid opnemen"
 
 #: ui/currentcallview.ui:299
 msgid "Toggle show chat"
-msgstr ""
+msgstr "Chat tonen/verbergen"
 
 #: ui/currentcallview.ui:303 ui/currentcallview.ui:320
 msgid "Chat"
-msgstr ""
+msgstr "Chat"
 
 #: ui/currentcallview.ui:329
 msgid "Mute audio"
-msgstr ""
+msgstr "Geluid dempen"
 
 #: ui/currentcallview.ui:365
 msgid "Record"
-msgstr ""
+msgstr "Opnemen"
 
 #: ui/editcontactview.ui:12
 msgid "Select addressbook"
-msgstr ""
+msgstr "Adresboek selecteren"
 
 #: ui/editcontactview.ui:15
 msgid "Addressbook"
-msgstr ""
+msgstr "Adresboek"
 
 #: ui/editcontactview.ui:29
 msgid "Name"
-msgstr ""
+msgstr "Naam"
 
 #: ui/editcontactview.ui:32
 msgid "Contact name"
-msgstr ""
+msgstr "Contactnaam"
 
 #: ui/editcontactview.ui:47
 msgid "Select how this number will be categorized"
-msgstr ""
+msgstr "Wijze van categorisatie voor dit nummer selecteren"
 
 #: ui/editcontactview.ui:50
 msgid "Number category"
-msgstr ""
+msgstr "Nummer categorie"
 
 #: ui/editcontactview.ui:66
 msgid "Number or Ring ID to be added"
-msgstr ""
+msgstr "Toe te voegen nummer of Ring ID"
 
 #: ui/editcontactview.ui:72
 msgid "Number or Ring ID"
-msgstr ""
+msgstr "Nummer of Ring ID"
 
 #: ui/editcontactview.ui:83
 msgid "Save"
-msgstr ""
+msgstr "Opslaan"
 
 #: ui/generalsettingsview.ui:32
 msgid "<b>Ring Settings</b>"
-msgstr ""
+msgstr "<b>Ring-instellingen</b>"
 
 #: ui/generalsettingsview.ui:46
 msgid "Start Ring on login"
-msgstr ""
+msgstr "Ring opstarten bij het aanmelden"
 
 #: ui/generalsettingsview.ui:55
 msgid "Hide Ring on close instead of quitting."
-msgstr ""
+msgstr "Ring verbergen in plaats van afsluiten."
 
 #: ui/generalsettingsview.ui:64
 msgid "Bring Ring to the foreground on incoming calls."
-msgstr ""
+msgstr "Ring naar voorgrond brengen bij binnenkomende oproepen."
 
 #: ui/generalsettingsview.ui:79
 msgid "Show chat on the right."
-msgstr ""
+msgstr "Chat rechts weergeven"
 
 #: ui/generalsettingsview.ui:86
 msgid "Show chat on the bottom."
-msgstr ""
+msgstr "Chat onderaan weergeven"
 
 #: ui/generalsettingsview.ui:110
 msgid "<b>History Settings</b>"
-msgstr ""
+msgstr "<b>Geschiedenisinstellingen</b>"
 
 #: ui/generalsettingsview.ui:128
 msgid "Keep history for (days):"
-msgstr ""
+msgstr "Geschiedenis bewaren voor (dagen):"
 
 #: ui/generalsettingsview.ui:151
 msgid "(set to 0 for unlimited history)"
-msgstr ""
+msgstr "(kies 0 voor onbeperkte geschiedenis)"
 
 #: ui/generalsettingsview.ui:160
 msgid "Clear all history"
-msgstr ""
+msgstr "Geschiedenis wissen"
 
 #: ui/incomingcallview.ui:88
 msgid "Incoming..."
-msgstr ""
+msgstr "Binnenkomend..."
 
 #: ui/incomingcallview.ui:122
 msgid "   Accept"
-msgstr ""
+msgstr "Accepteren"
 
 #: ui/incomingcallview.ui:137
 msgid "   Reject"
-msgstr ""
+msgstr "Afwijzen"
 
 #: ui/incomingcallview.ui:152
 msgid "   Hang-up"
-msgstr ""
+msgstr "Ophangen"
 
 #: ui/mediasettingsview.ui:36
 msgid "Audio manager:"
-msgstr ""
+msgstr "Geluidsbeheerder:"
 
 #: ui/mediasettingsview.ui:48
 msgid "Ringtone device:"
-msgstr ""
+msgstr "Beltoonapparaat:"
 
 #: ui/mediasettingsview.ui:60
 msgid "Output device:"
-msgstr ""
+msgstr "Uitvoerapparaat:"
 
 #: ui/mediasettingsview.ui:72
 msgid "Input device:"
-msgstr ""
+msgstr "Invoerapparaat:"
 
 #: ui/mediasettingsview.ui:127
 msgid "<b>Audio Settings</b>"
-msgstr ""
+msgstr "<b>Geluidinstellingen</b>"
 
 #: ui/mediasettingsview.ui:163
 msgid "Device:"
-msgstr ""
+msgstr "Apparaat:"
 
 #: ui/mediasettingsview.ui:175
 msgid "Channel:"
-msgstr ""
+msgstr "Kanaal:"
 
 #: ui/mediasettingsview.ui:187
 msgid "Resolution:"
-msgstr ""
+msgstr "Resolutie:"
 
 #: ui/mediasettingsview.ui:199
 msgid "Frame rate:"
-msgstr ""
+msgstr "Framesnelheid:"
 
 #: ui/mediasettingsview.ui:258
 msgid "<b>Camera Settings</b>"
-msgstr ""
+msgstr "<b>Camera-instellingen</b>"
 
 #: ui/ringgearsmenu.ui:13
 msgid "_About"
-msgstr ""
+msgstr "_Over"
 
 #: ui/ringgearsmenu.ui:19
 msgid "_Quit"
-msgstr ""
+msgstr "_Afsluiten"
 
 #: ui/ringmainwindow.ui:20
 msgid "Menu"
-msgstr ""
+msgstr "Menu"
 
 #: ui/ringmainwindow.ui:54
 msgid "General"
-msgstr ""
+msgstr "Algemeen"
 
 #: ui/ringmainwindow.ui:64
 msgid "Media"
-msgstr ""
+msgstr "Media"
 
 #: ui/ringmainwindow.ui:75
 msgid "Accounts"
-msgstr ""
+msgstr "Accounts"
 
 #: ui/ringmainwindow.ui:93
 msgid "Settings"
-msgstr ""
+msgstr "Instellingen"
 
 #: ui/ringmainwindow.ui:192
 msgid "Conversations"
-msgstr ""
+msgstr "Conversaties"
 
 #: ui/ringmainwindow.ui:211
 msgid "Contacts"
-msgstr ""
+msgstr "Contacten"
 
 #: ui/ringmainwindow.ui:230
 msgid "History"
-msgstr ""
+msgstr "Geschiedenis"
 
 #: ui/ringmainwindow.ui:290
 msgid "Welcome to  "
-msgstr ""
+msgstr "Welkom bij"
 
 #: ui/ringmainwindow.ui:307
 msgid "Enter your alias to get started:"
-msgstr ""
+msgstr "Kies een alias om te beginnen:"
 
 #: ui/ringmainwindow.ui:324
 msgid "Generating your Ring account..."
-msgstr ""
+msgstr "Uw Ring account wordt gegenereerd..."
 
 #: ui/ringmainwindow.ui:338
 msgid "Next"
-msgstr ""
+msgstr "Volgende"
 
 #: ui/ringmainwindow.ui:360
 msgid "Your Ring account has been created with the following Ring ID:"
-msgstr ""
+msgstr "Uw Ring account is aangemaakt met het volgende Ring ID:"
 
 #: ui/ringmainwindow.ui:375
 msgid "Share it with your friends so they can contact you via Ring!"
-msgstr ""
+msgstr "Deel deze met uw vrienden zodat zij u kunnen bereiken via Ring!"
 
 #: ui/ringmainwindow.ui:380
 msgid "Done"
-msgstr ""
+msgstr "Klaar"
diff --git a/client-gnome/po/ca.po b/client-gnome/po/nl_NL.po
similarity index 96%
copy from client-gnome/po/ca.po
copy to client-gnome/po/nl_NL.po
index 280e138..e31789d 100644
--- a/client-gnome/po/ca.po
+++ b/client-gnome/po/nl_NL.po
@@ -3,29 +3,28 @@
 # This file is distributed under the same license as the Ring package.
 # 
 # Translators:
-# David <stakewinner00 at mykolab.com>, 2015
 msgid ""
 msgstr ""
 "Project-Id-Version: Ring\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2015-11-13 09:43-0500\n"
-"PO-Revision-Date: 2016-03-24 20:09+0000\n"
+"PO-Revision-Date: 2016-06-02 13:45+0000\n"
 "Last-Translator: Guillaume Roguez\n"
-"Language-Team: Catalan (http://www.transifex.com/savoirfairelinux/ring/language/ca/)\n"
+"Language-Team: Dutch (Netherlands) (http://www.transifex.com/savoirfairelinux/ring/language/nl_NL/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Language: ca\n"
+"Language: nl_NL\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
 #: src/accountaudiotab.cpp:185 src/accountvideotab.cpp:194
 msgid "Enabled"
-msgstr "Habilitat"
+msgstr ""
 
 #: src/accountaudiotab.cpp:191
 msgctxt "Name of the codec"
 msgid "Name"
-msgstr "Nom"
+msgstr "Naam"
 
 #: src/accountaudiotab.cpp:195 src/accountvideotab.cpp:204
 msgid "Bitrate"
@@ -41,7 +40,7 @@ msgstr ""
 
 #: src/accountgeneraltab.cpp:221
 msgid "Type"
-msgstr ""
+msgstr "Type"
 
 #: src/accountgeneraltab.cpp:250
 msgid "auto-generating..."
@@ -91,32 +90,32 @@ msgstr ""
 #: src/accountvideotab.cpp:200
 msgctxt "The name of the codec"
 msgid "Name"
-msgstr "Nom"
+msgstr "Naam"
 
 #: src/accountview.cpp:159
 msgctxt "Account settings"
 msgid "General"
-msgstr ""
+msgstr "Algemeen"
 
 #: src/accountview.cpp:163
 msgctxt "Account settings"
 msgid "Audio"
-msgstr ""
+msgstr "Geluid"
 
 #: src/accountview.cpp:167
 msgctxt "Account settings"
 msgid "Video"
-msgstr ""
+msgstr "Video"
 
 #: src/accountview.cpp:171
 msgctxt "Account settings"
 msgid "Advanced"
-msgstr ""
+msgstr "Gevorderd"
 
 #: src/accountview.cpp:175
 msgctxt "Account settings"
 msgid "Security"
-msgstr "Seguretat"
+msgstr "Beveiliging"
 
 #: src/accountview.cpp:229
 #, c-format
@@ -130,7 +129,7 @@ msgstr ""
 #: src/accountview.cpp:399
 msgctxt "Account state column"
 msgid "Enabled"
-msgstr "Habilitat"
+msgstr ""
 
 #: src/accountview.cpp:405
 msgctxt "Account alias (name) column"
@@ -140,7 +139,7 @@ msgstr ""
 #: src/accountview.cpp:409
 msgctxt "Account status column"
 msgid "Status"
-msgstr ""
+msgstr "Staat"
 
 #: src/contactsview.cpp:305
 msgid "_Copy name"
@@ -367,11 +366,11 @@ msgstr ""
 
 #: ui/accountaudiotab.ui:59 ui/accountvideotab.ui:59
 msgid "Up"
-msgstr ""
+msgstr "Omhoog"
 
 #: ui/accountaudiotab.ui:66 ui/accountvideotab.ui:66
 msgid "Down"
-msgstr ""
+msgstr "Beneden"
 
 #: ui/accountaudiotab.ui:77 ui/accountvideotab.ui:77
 msgid "<b>Codecs</b>"
@@ -415,7 +414,7 @@ msgstr ""
 
 #: ui/accountsecuritytab.ui:220
 msgid "Private key"
-msgstr "Clau privada"
+msgstr ""
 
 #: ui/accountsecuritytab.ui:243
 msgid "Private key password"
@@ -475,7 +474,7 @@ msgstr ""
 
 #: ui/currentcallview.ui:73
 msgid "Send"
-msgstr "Enviar"
+msgstr ""
 
 #: ui/currentcallview.ui:191
 msgid "End this call"
@@ -540,7 +539,7 @@ msgstr ""
 
 #: ui/editcontactview.ui:29
 msgid "Name"
-msgstr "Nom"
+msgstr "Naam"
 
 #: ui/editcontactview.ui:32
 msgid "Contact name"
@@ -676,15 +675,15 @@ msgstr ""
 
 #: ui/ringmainwindow.ui:54
 msgid "General"
-msgstr ""
+msgstr "Algemeen"
 
 #: ui/ringmainwindow.ui:64
 msgid "Media"
-msgstr ""
+msgstr "Media"
 
 #: ui/ringmainwindow.ui:75
 msgid "Accounts"
-msgstr ""
+msgstr "Accounts"
 
 #: ui/ringmainwindow.ui:93
 msgid "Settings"
diff --git a/client-gnome/po/pt_BR.po b/client-gnome/po/pt_BR.po
index 8054af3..2d38bd5 100644
--- a/client-gnome/po/pt_BR.po
+++ b/client-gnome/po/pt_BR.po
@@ -3,6 +3,7 @@
 # This file is distributed under the same license as the Ring package.
 # 
 # Translators:
+# Cleiton Floss, 2016
 # Keven de Oliveira <keven at zenbackup.com.br>, 2015
 # Nícolas Wildner <nicolasgaucho at gmail.com>, 2015
 # Raul Dipeas <rauldipeas at outlook.com>, 2015
@@ -11,8 +12,8 @@ msgstr ""
 "Project-Id-Version: Ring\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2015-11-13 09:43-0500\n"
-"PO-Revision-Date: 2016-03-24 20:09+0000\n"
-"Last-Translator: Guillaume Roguez\n"
+"PO-Revision-Date: 2016-05-26 04:33+0000\n"
+"Last-Translator: Cleiton Floss\n"
 "Language-Team: Portuguese (Brazil) (http://www.transifex.com/savoirfairelinux/ring/language/pt_BR/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
@@ -162,7 +163,7 @@ msgctxt "Do not translate the release name"
 msgid ""
 "release: Louis-Joseph Papineau\n"
 "v%d.%d.%d - %.10s"
-msgstr ""
+msgstr "Versão: Louis-Joseph Papineau\nv%d.%d.%d - %.10s"
 
 #: src/dialogs.c:111
 msgid ""
diff --git a/client-gnome/src/accountimportexportview.cpp b/client-gnome/src/accountimportexportview.cpp
new file mode 100644
index 0000000..2523e53
--- /dev/null
+++ b/client-gnome/src/accountimportexportview.cpp
@@ -0,0 +1,411 @@
+/*
+ *  Copyright (C) 2016 Savoir-faire Linux Inc.
+ *  Author: Stepan Salenikovich <stepan.salenikovich at savoirfairelinux.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+
+#include "accountimportexportview.h"
+
+#include <gtk/gtk.h>
+#include <account.h>
+#include <accountmodel.h>
+
+#include <glib/gi18n.h>
+
+struct _AccountImportExportView
+{
+    GtkBox parent;
+};
+
+struct _AccountImportExportViewClass
+{
+    GtkBoxClass parent_class;
+};
+
+typedef struct _AccountImportExportViewPrivate AccountImportExportViewPrivate;
+
+struct _AccountImportExportViewPrivate
+{
+    Account   *account;
+
+    GtkWidget *label_export;
+    GtkWidget *label_import;
+    GtkWidget *hbox_export_location;
+    GtkWidget *label_export_location;
+    GtkWidget *button_export_location;
+    GtkWidget *filechooserbutton_import;
+    GtkWidget *button_export;
+    GtkWidget *button_import;
+    GtkWidget *button_cancel;
+    GtkWidget *entry_password;
+    GtkWidget *label_error;
+
+    GList *export_accounts_list;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE(AccountImportExportView, account_importexport_view, GTK_TYPE_BOX);
+
+#define ACCOUNT_IMPORTEXPORT_VIEW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), ACCOUNT_IMPORTEXPORT_VIEW_TYPE, AccountImportExportViewPrivate))
+
+/* signals */
+enum {
+    IMPORT_EXPORT_CANCELED,
+    IMPORT_EXPORT_COMPLETED,
+    LAST_SIGNAL
+};
+
+static guint account_importexport_view_signals[LAST_SIGNAL] = { 0 };
+
+static void
+account_importexport_view_dispose(GObject *object)
+{
+    G_OBJECT_CLASS(account_importexport_view_parent_class)->dispose(object);
+}
+
+static void
+account_importexport_view_finalize(GObject *object)
+{
+    AccountImportExportView *view = ACCOUNT_IMPORTEXPORT_VIEW(object);
+    AccountImportExportViewPrivate *priv = ACCOUNT_IMPORTEXPORT_VIEW_GET_PRIVATE(view);
+
+    if (priv->export_accounts_list)
+        g_list_free(priv->export_accounts_list);
+
+    G_OBJECT_CLASS(account_importexport_view_parent_class)->finalize(object);
+}
+
+static void
+choose_export_location(AccountImportExportView *self)
+{
+    AccountImportExportViewPrivate *priv = ACCOUNT_IMPORTEXPORT_VIEW_GET_PRIVATE(self);
+
+    // clear any existing error
+    gtk_label_set_text(GTK_LABEL(priv->label_error), "");
+
+    // create filechooser dialog and get export location
+    auto dialog = gtk_file_chooser_dialog_new(_("Select account export location"),
+                                              GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(self))),
+                                              GTK_FILE_CHOOSER_ACTION_SAVE,
+                                              _("Cancel"),
+                                              GTK_RESPONSE_CANCEL,
+                                              _("Select"),
+                                              GTK_RESPONSE_ACCEPT,
+                                              NULL);
+
+    gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE);
+    gtk_file_chooser_set_create_folders(GTK_FILE_CHOOSER(dialog), TRUE);
+
+    if (!priv->export_accounts_list->next) {
+        auto name = g_strconcat(static_cast<Account *>(priv->export_accounts_list->data)->alias().toUtf8().constData(), ".ring", NULL);
+        gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), name);
+        g_free(name);
+    } else {
+        // TODO: handle multiple account export
+    }
+
+    /* start the file chooser */
+    if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
+        if (auto filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog))) {
+            gtk_label_set_text(GTK_LABEL(priv->label_export_location), filename);
+
+            // if accounts and password are set then we're ready for export
+            auto password = gtk_entry_get_text(GTK_ENTRY(priv->entry_password));
+            if (priv->export_accounts_list && priv->export_accounts_list->data && strlen(password) > 0) {
+                gtk_widget_set_sensitive(priv->button_export, TRUE);
+            }
+            g_free (filename);
+        }
+    }
+
+    gtk_widget_destroy (dialog);
+}
+
+
+static void
+import_file_set(AccountImportExportView *self)
+{
+    AccountImportExportViewPrivate *priv = ACCOUNT_IMPORTEXPORT_VIEW_GET_PRIVATE(self);
+
+    // clear any existing error
+    gtk_label_set_text(GTK_LABEL(priv->label_error), "");
+
+    // if password is set then we're ready for import
+    auto password = gtk_entry_get_text(GTK_ENTRY(priv->entry_password));
+    if (strlen(password) > 0) {
+        gtk_widget_set_sensitive(priv->button_import, TRUE);
+    }
+}
+
+static void
+password_changed(AccountImportExportView *self)
+{
+    AccountImportExportViewPrivate *priv = ACCOUNT_IMPORTEXPORT_VIEW_GET_PRIVATE(self);
+
+    // clear any existing error
+    gtk_label_set_text(GTK_LABEL(priv->label_error), "");
+
+    // if the password and other requirements are met then enable import/export
+    auto password = gtk_entry_get_text(GTK_ENTRY(priv->entry_password));
+    if (strlen(password) > 0) {
+
+        // import
+        if (auto filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(priv->filechooserbutton_import))) {
+            gtk_widget_set_sensitive(priv->button_import, TRUE);
+            g_free(filename);
+        }
+
+        // export
+        const auto filename = gtk_label_get_text(GTK_LABEL(priv->label_export_location));
+        if (strlen(filename) > 0) {
+            if (priv->export_accounts_list && priv->export_accounts_list->data) {
+                gtk_widget_set_sensitive(priv->button_export, TRUE);
+            }
+        }
+
+    } else {
+        gtk_widget_set_sensitive(priv->button_export, FALSE);
+        gtk_widget_set_sensitive(priv->button_import, FALSE);
+    }
+}
+
+static void
+cancel_clicked(AccountImportExportView *self)
+{
+    g_signal_emit(G_OBJECT(self), account_importexport_view_signals[IMPORT_EXPORT_CANCELED], 0);
+}
+
+static void
+import_account(AccountImportExportView *self)
+{
+    g_return_if_fail(IS_ACCOUNT_IMPORTEXPORT_VIEW(self));
+
+    AccountImportExportViewPrivate *priv = ACCOUNT_IMPORTEXPORT_VIEW_GET_PRIVATE(self);
+
+    // clear any existing error
+    gtk_label_set_text(GTK_LABEL(priv->label_error), "");
+
+    if (auto filepath = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(priv->filechooserbutton_import))) {
+        const auto password = gtk_entry_get_text(GTK_ENTRY(priv->entry_password));
+        if (strlen(password) > 0) {
+            auto ret = AccountModel::instance().importAccounts(filepath, password);
+            switch(ret) {
+                case 0:
+                    // done
+                    g_signal_emit(G_OBJECT(self), account_importexport_view_signals[IMPORT_EXPORT_COMPLETED], 0);
+                break;
+                default:
+                    //failed
+                    gtk_label_set_text(GTK_LABEL(priv->label_error), _("Error importing account(s)"));
+                    g_warning("failed to import account(s), err: %d", ret);
+                break;
+            }
+        } else {
+            g_warning("no password set for account import");
+        }
+        g_free(filepath);
+    } else {
+        g_warning("no file selected for account import");
+    }
+}
+
+static void
+export_account(AccountImportExportView *self)
+{
+    g_return_if_fail(IS_ACCOUNT_IMPORTEXPORT_VIEW(self));
+
+    AccountImportExportViewPrivate *priv = ACCOUNT_IMPORTEXPORT_VIEW_GET_PRIVATE(self);
+
+    // clear any existing error
+    gtk_label_set_text(GTK_LABEL(priv->label_error), "");
+
+    // check that we have some accounts to export
+    if ( !(priv->export_accounts_list && priv->export_accounts_list->data)) {
+        g_warning("no accounts are selected for export");
+        return;
+    }
+
+    const auto filepath = gtk_label_get_text(GTK_LABEL(priv->label_export_location));
+    // validate filepath
+    if (strlen(filepath)) {
+        const auto password = gtk_entry_get_text(GTK_ENTRY(priv->entry_password));
+        if (strlen(password) > 0) {
+
+            // get account id strings
+            auto account_ids = QStringList();
+            auto list = priv->export_accounts_list;
+            while (list != nullptr) {
+                auto account = static_cast<Account *>(list->data);
+                account_ids << account->id();
+                list = g_list_next(list);
+            }
+
+            auto ret = AccountModel::instance().exportAccounts(account_ids, filepath, password);
+            switch (ret) {
+                case 0:
+                    // done
+                    g_signal_emit(G_OBJECT(self), account_importexport_view_signals[IMPORT_EXPORT_COMPLETED], 0);
+                break;
+                default:
+                    //failed
+                    gtk_label_set_text(GTK_LABEL(priv->label_error), _("Error exporting account(s)"));
+                    g_warning("failed to export account(s), err: %d", ret);
+                break;
+            }
+        } else {
+            g_warning("no password set for account export");
+        }
+    } else {
+        g_warning("no file selected for account export");
+    }
+}
+
+static void
+account_importexport_view_init(AccountImportExportView *self)
+{
+    gtk_widget_init_template(GTK_WIDGET(self));
+
+    AccountImportExportViewPrivate *priv = ACCOUNT_IMPORTEXPORT_VIEW_GET_PRIVATE(self);
+
+    g_signal_connect_swapped(priv->button_export_location, "clicked", G_CALLBACK(choose_export_location), self);
+    g_signal_connect_swapped(priv->filechooserbutton_import, "file-set", G_CALLBACK(import_file_set), self);
+    g_signal_connect_swapped(priv->entry_password, "changed", G_CALLBACK(password_changed), self);
+    g_signal_connect_swapped(priv->button_cancel, "clicked", G_CALLBACK(cancel_clicked), self);
+    g_signal_connect_swapped(priv->button_import, "clicked", G_CALLBACK(import_account), self);
+    g_signal_connect_swapped(priv->button_export, "clicked", G_CALLBACK(export_account), self);
+}
+
+static void
+account_importexport_view_class_init(AccountImportExportViewClass *klass)
+{
+    GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+
+    gobject_class->dispose = account_importexport_view_dispose;
+    gobject_class->finalize = account_importexport_view_finalize;
+
+    gtk_widget_class_set_template_from_resource(GTK_WIDGET_CLASS (klass),
+                                                "/cx/ring/RingGnome/accountimportexportview.ui");
+
+    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountImportExportView, label_export);
+    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountImportExportView, label_import);
+    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountImportExportView, hbox_export_location);
+    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountImportExportView, label_export_location);
+    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountImportExportView, button_export_location);
+    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountImportExportView, filechooserbutton_import);
+    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountImportExportView, button_export);
+    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountImportExportView, button_import);
+    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountImportExportView, button_cancel);
+    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountImportExportView, entry_password);
+    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountImportExportView, label_error);
+
+    /* add signals */
+    account_importexport_view_signals[IMPORT_EXPORT_CANCELED] = g_signal_new("import-export-canceled",
+                 G_TYPE_FROM_CLASS(klass),
+                 (GSignalFlags) (G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION),
+                 0,
+                 nullptr,
+                 nullptr,
+                 g_cclosure_marshal_VOID__VOID,
+                 G_TYPE_NONE, 0);
+
+    account_importexport_view_signals[IMPORT_EXPORT_COMPLETED] = g_signal_new("import-export-completed",
+                 G_TYPE_FROM_CLASS(klass),
+                 (GSignalFlags) (G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION),
+                 0,
+                 nullptr,
+                 nullptr,
+                 g_cclosure_marshal_VOID__VOID,
+                 G_TYPE_NONE, 0);
+}
+
+static void
+build_import_view(AccountImportExportView *self)
+{
+    g_return_if_fail(self);
+
+    AccountImportExportViewPrivate *priv = ACCOUNT_IMPORTEXPORT_VIEW_GET_PRIVATE(self);
+
+    gtk_widget_hide(priv->label_export);
+    gtk_widget_hide(priv->hbox_export_location);
+    gtk_widget_hide(priv->button_export);
+
+    gtk_widget_show(priv->label_import);
+    gtk_widget_show(priv->filechooserbutton_import);
+    gtk_widget_show(priv->button_import);
+}
+
+static void
+build_export_view(AccountImportExportView *self)
+{
+    g_return_if_fail(self);
+
+    AccountImportExportViewPrivate *priv = ACCOUNT_IMPORTEXPORT_VIEW_GET_PRIVATE(self);
+
+    gtk_widget_show(priv->label_export);
+    gtk_widget_show(priv->hbox_export_location);
+    gtk_widget_show(priv->button_export);
+
+    gtk_widget_hide(priv->label_import);
+    gtk_widget_hide(priv->filechooserbutton_import);
+    gtk_widget_hide(priv->button_import);
+}
+
+GtkWidget *
+account_import_view_new()
+{
+    gpointer view = g_object_new(ACCOUNT_IMPORTEXPORT_VIEW_TYPE, NULL);
+
+    build_import_view(ACCOUNT_IMPORTEXPORT_VIEW(view));
+
+    return (GtkWidget *)view;
+}
+
+GtkWidget *
+account_export_view_new()
+{
+    gpointer view = g_object_new(ACCOUNT_IMPORTEXPORT_VIEW_TYPE, NULL);
+
+    build_export_view(ACCOUNT_IMPORTEXPORT_VIEW(view));
+
+    return (GtkWidget *)view;
+}
+
+void
+account_export_view_set_accounts(AccountImportExportView *self, GList *accounts)
+{
+    g_return_if_fail(self);
+    AccountImportExportViewPrivate *priv = ACCOUNT_IMPORTEXPORT_VIEW_GET_PRIVATE(self);
+
+    // replace current list
+    if (priv->export_accounts_list) {
+        g_list_free(priv->export_accounts_list);
+        priv->export_accounts_list = nullptr;
+    }
+
+    // make sure the new list isn't empty
+    if (accounts && accounts->data) {
+        priv->export_accounts_list = g_list_copy(accounts);
+
+        if (!accounts->next) {
+            auto location = g_strconcat(g_get_home_dir(), "/", static_cast<Account *>(priv->export_accounts_list->data)->alias().toUtf8().constData(), ".ring", NULL);
+            gtk_label_set_text(GTK_LABEL(priv->label_export_location), location);
+            g_free(location);
+        } else {
+            // TODO: handle multiple account export
+        }
+    } else {
+        // no accounts are selected... this case should not normally be ever displayed
+    }
+}
diff --git a/client-gnome/src/accountimportexportview.h b/client-gnome/src/accountimportexportview.h
new file mode 100644
index 0000000..f2b9324
--- /dev/null
+++ b/client-gnome/src/accountimportexportview.h
@@ -0,0 +1,40 @@
+/*
+ *  Copyright (C) 2016 Savoir-faire Linux Inc.
+ *  Author: Stepan Salenikovich <stepan.salenikovich at savoirfairelinux.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+
+#pragma once
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define ACCOUNT_IMPORTEXPORT_VIEW_TYPE            (account_importexport_view_get_type ())
+#define ACCOUNT_IMPORTEXPORT_VIEW(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), ACCOUNT_IMPORTEXPORT_VIEW_TYPE, AccountImportExportView))
+#define ACCOUNT_IMPORTEXPORT_VIEW_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), ACCOUNT_IMPORTEXPORT_VIEW_TYPE, AccountImportExportViewClass))
+#define IS_ACCOUNT_IMPORTEXPORT_VIEW(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), ACCOUNT_IMPORTEXPORT_VIEW_TYPE))
+#define IS_ACCOUNT_IMPORTEXPORT_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), ACCOUNT_IMPORTEXPORT_VIEW_TYPE))
+
+typedef struct _AccountImportExportView      AccountImportExportView;
+typedef struct _AccountImportExportViewClass AccountImportExportViewClass;
+
+GType      account_importexport_view_get_type      (void) G_GNUC_CONST;
+GtkWidget *account_import_view_new                 (void);
+GtkWidget *account_export_view_new                 (void);
+void       account_export_view_set_accounts        (AccountImportExportView* self, GList *accounts);
+
+G_END_DECLS
diff --git a/client-gnome/src/accountview.cpp b/client-gnome/src/accountview.cpp
index 5ca2fa9..30ef947 100644
--- a/client-gnome/src/accountview.cpp
+++ b/client-gnome/src/accountview.cpp
@@ -36,6 +36,7 @@
 #include "dialogs.h"
 #include <glib/gprintf.h>
 #include "utils/models.h"
+#include "accountimportexportview.h"
 
 struct _AccountView
 {
@@ -52,11 +53,14 @@ typedef struct _AccountViewPrivate AccountViewPrivate;
 struct _AccountViewPrivate
 {
     GtkWidget *treeview_account_list;
+    GtkWidget *account_import_view;
+    GtkWidget *account_export_view;
     GtkWidget *stack_account;
-    GtkWidget *current_account_notebook;
     GtkWidget *button_remove_account;
     GtkWidget *button_add_account;
     GtkWidget *combobox_account_type;
+    GtkWidget *button_import_account;
+    GtkWidget *button_export_account;
 
     gint current_page; /* keeps track of current notebook page displayed */
 
@@ -109,19 +113,24 @@ create_scrolled_account_view(GtkWidget *account_view)
 }
 
 static void
-account_selection_changed(GtkTreeSelection *selection, AccountView *view)
+tab_selection_changed(G_GNUC_UNUSED GtkNotebook *notebook,
+                      G_GNUC_UNUSED GtkWidget   *page,
+                                    guint        page_num,
+                                    AccountView *self)
 {
-    g_return_if_fail(IS_ACCOUNT_VIEW(view));
-    AccountViewPrivate *priv = ACCOUNT_VIEW_GET_PRIVATE(view);
+    g_return_if_fail(IS_ACCOUNT_VIEW(self));
+    AccountViewPrivate *priv = ACCOUNT_VIEW_GET_PRIVATE(self);
 
-    GtkWidget *old_account_view = gtk_stack_get_visible_child(GTK_STACK(priv->stack_account));
+    priv->current_page = page_num;
+}
 
-    /* keep track of the last tab displayed */
-    if (priv->current_account_notebook)
-        priv->current_page = gtk_notebook_get_current_page(GTK_NOTEBOOK(priv->current_account_notebook));
+static void
+account_selection_changed(GtkTreeSelection *selection, AccountView *self)
+{
+    g_return_if_fail(IS_ACCOUNT_VIEW(self));
+    AccountViewPrivate *priv = ACCOUNT_VIEW_GET_PRIVATE(self);
 
-    if (priv->current_page < 0)
-        priv->current_page = 0;
+    auto old_view = gtk_stack_get_visible_child(GTK_STACK(priv->stack_account));
 
     QModelIndex account_idx = get_index_from_selection(selection);
     if (!account_idx.isValid()) {
@@ -130,7 +139,10 @@ account_selection_changed(GtkTreeSelection *selection, AccountView *view)
         gtk_widget_show(empty_box);
         gtk_stack_add_named(GTK_STACK(priv->stack_account), empty_box, "placeholder");
         gtk_stack_set_visible_child(GTK_STACK(priv->stack_account), empty_box);
-        priv->current_account_notebook = NULL;
+
+        /* cannot delete nor export accounts */
+        gtk_widget_set_sensitive(priv->button_remove_account, FALSE);
+        gtk_widget_set_sensitive(priv->button_export_account, FALSE);
     } else {
         Account *account = AccountModel::instance().getAccountByModelIndex(account_idx);
 
@@ -138,48 +150,53 @@ account_selection_changed(GtkTreeSelection *selection, AccountView *view)
         GtkWidget *hbox_account = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10);
 
         /* create account notebook */
-        priv->current_account_notebook = gtk_notebook_new();
-        gtk_notebook_set_scrollable(GTK_NOTEBOOK(priv->current_account_notebook), TRUE);
-        gtk_notebook_set_show_border(GTK_NOTEBOOK(priv->current_account_notebook), FALSE);
-        gtk_box_pack_start(GTK_BOX(hbox_account), priv->current_account_notebook, TRUE, TRUE, 0);
+        auto account_notebook = gtk_notebook_new();
+        gtk_notebook_set_scrollable(GTK_NOTEBOOK(account_notebook), TRUE);
+        gtk_notebook_set_show_border(GTK_NOTEBOOK(account_notebook), FALSE);
+        gtk_box_pack_start(GTK_BOX(hbox_account), account_notebook, TRUE, TRUE, 0);
 
         /* customize account view based on account */
         auto general_tab = create_scrolled_account_view(account_general_tab_new(account));
-        gtk_notebook_append_page(GTK_NOTEBOOK(priv->current_account_notebook),
+        gtk_notebook_append_page(GTK_NOTEBOOK(account_notebook),
                                  general_tab,
                                  gtk_label_new(C_("Account settings", "General")));
         auto audio_tab = create_scrolled_account_view(account_audio_tab_new(account));
-        gtk_notebook_append_page(GTK_NOTEBOOK(priv->current_account_notebook),
+        gtk_notebook_append_page(GTK_NOTEBOOK(account_notebook),
                                  audio_tab,
                                  gtk_label_new(C_("Account settings", "Audio")));
         auto video_tab = create_scrolled_account_view(account_video_tab_new(account));
-        gtk_notebook_append_page(GTK_NOTEBOOK(priv->current_account_notebook),
+        gtk_notebook_append_page(GTK_NOTEBOOK(account_notebook),
                                  video_tab,
                                  gtk_label_new(C_("Account settings", "Video")));
         auto advanced_tab = create_scrolled_account_view(account_advanced_tab_new(account));
-        gtk_notebook_append_page(GTK_NOTEBOOK(priv->current_account_notebook),
+        gtk_notebook_append_page(GTK_NOTEBOOK(account_notebook),
                                  advanced_tab,
                                  gtk_label_new(C_("Account settings", "Advanced")));
         auto security_tab = create_scrolled_account_view(account_security_tab_new(account));
-        gtk_notebook_append_page(GTK_NOTEBOOK(priv->current_account_notebook),
+        gtk_notebook_append_page(GTK_NOTEBOOK(account_notebook),
                                  security_tab,
                                  gtk_label_new(C_("Account settings", "Security")));
 
-        /* set the tab displayed to the same as the prev account selected */
-        gtk_notebook_set_current_page(GTK_NOTEBOOK(priv->current_account_notebook), priv->current_page);
-
         gtk_widget_show_all(hbox_account);
+        /* set the tab displayed to the same as the prev account selected */
+        gtk_notebook_set_current_page(GTK_NOTEBOOK(account_notebook), priv->current_page);
+        /* now connect to the tab changed signal */
+        g_signal_connect(account_notebook, "switch-page", G_CALLBACK(tab_selection_changed), self);
 
         /* set the new account view as visible */
         char *account_view_name = g_strdup_printf("%p_account", account);
         gtk_stack_add_named(GTK_STACK(priv->stack_account), hbox_account, account_view_name);
         gtk_stack_set_visible_child(GTK_STACK(priv->stack_account), hbox_account);
         g_free(account_view_name);
+
+        /* can delete and export accounts */
+        gtk_widget_set_sensitive(priv->button_remove_account, TRUE);
+        gtk_widget_set_sensitive(priv->button_export_account, TRUE);
     }
 
-    /* remove the old account view */
-    if (old_account_view)
-        gtk_container_remove(GTK_CONTAINER(priv->stack_account), old_account_view);
+    /* remove the old view */
+    if (old_view)
+        gtk_container_remove(GTK_CONTAINER(priv->stack_account), old_view);
 }
 
 static void
@@ -367,6 +384,69 @@ state_to_string(G_GNUC_UNUSED GtkTreeViewColumn *tree_column,
 }
 
 static void
+close_import_export_view(AccountView *self)
+{
+    g_return_if_fail(IS_ACCOUNT_VIEW(self));
+    AccountViewPrivate *priv = ACCOUNT_VIEW_GET_PRIVATE(self);
+
+    auto selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(priv->treeview_account_list));
+    account_selection_changed(selection, self);
+}
+
+static void
+import_account(AccountView* self)
+{
+    g_return_if_fail(IS_ACCOUNT_VIEW(self));
+    AccountViewPrivate *priv = ACCOUNT_VIEW_GET_PRIVATE(self);
+
+    auto old_view = gtk_stack_get_visible_child(GTK_STACK(priv->stack_account));
+
+    auto import_account = account_import_view_new();
+    g_signal_connect_swapped(import_account, "import-export-canceled", G_CALLBACK(close_import_export_view), self);
+    g_signal_connect_swapped(import_account, "import-export-completed", G_CALLBACK(close_import_export_view), self);
+    auto scrolled_view = create_scrolled_account_view(import_account);
+    gtk_widget_show_all(scrolled_view);
+    gtk_stack_add_named(GTK_STACK(priv->stack_account), scrolled_view, "import_account");
+    gtk_stack_set_visible_child(GTK_STACK(priv->stack_account), scrolled_view);
+
+    /* remove the old view */
+    if (old_view)
+        gtk_container_remove(GTK_CONTAINER(priv->stack_account), old_view);
+}
+
+static void
+export_account(AccountView* self)
+{
+    g_return_if_fail(IS_ACCOUNT_VIEW(self));
+    AccountViewPrivate *priv = ACCOUNT_VIEW_GET_PRIVATE(self);
+
+    auto selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(priv->treeview_account_list));
+    auto idx = get_index_from_selection(selection);
+    if (idx.isValid()) {
+        auto old_view = gtk_stack_get_visible_child(GTK_STACK(priv->stack_account));
+
+        auto account = AccountModel::instance().getAccountByModelIndex(idx);
+        auto export_account = account_export_view_new();
+        g_signal_connect_swapped(export_account, "import-export-canceled", G_CALLBACK(close_import_export_view), self);
+        g_signal_connect_swapped(export_account, "import-export-completed", G_CALLBACK(close_import_export_view), self);
+        GList *account_list = nullptr;
+        account_list = g_list_append(account_list, account);
+        account_export_view_set_accounts(ACCOUNT_IMPORTEXPORT_VIEW(export_account), account_list);
+        g_list_free(account_list);
+        auto scrolled_view = create_scrolled_account_view(export_account);
+        gtk_widget_show_all(scrolled_view);
+        gtk_stack_add_named(GTK_STACK(priv->stack_account), scrolled_view, "export_account");
+        gtk_stack_set_visible_child(GTK_STACK(priv->stack_account), scrolled_view);
+
+        /* remove the old view */
+        if (old_view)
+            gtk_container_remove(GTK_CONTAINER(priv->stack_account), old_view);
+
+    }
+
+}
+
+static void
 account_view_init(AccountView *view)
 {
     gtk_widget_init_template(GTK_WIDGET(view));
@@ -475,6 +555,10 @@ account_view_init(AccountView *view)
     /* connect signals to add/remove accounts */
     g_signal_connect(priv->button_remove_account, "clicked", G_CALLBACK(remove_account), view);
     g_signal_connect(priv->button_add_account, "clicked", G_CALLBACK(add_account), view);
+
+    /* signals to import/export acounts */
+    g_signal_connect_swapped(priv->button_import_account, "clicked", G_CALLBACK(import_account), view);
+    g_signal_connect_swapped(priv->button_export_account, "clicked", G_CALLBACK(export_account), view);
 }
 
 static void
@@ -491,6 +575,8 @@ account_view_class_init(AccountViewClass *klass)
     gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountView, button_remove_account);
     gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountView, button_add_account);
     gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountView, combobox_account_type);
+    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountView, button_import_account);
+    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountView, button_export_account);
 }
 
 GtkWidget *
diff --git a/client-gnome/src/ring_client.cpp b/client-gnome/src/ring_client.cpp
index 15c5a5d..fb6c3be 100644
--- a/client-gnome/src/ring_client.cpp
+++ b/client-gnome/src/ring_client.cpp
@@ -258,15 +258,23 @@ init_systray(RingClient *client)
 
     // init menu
     if (!priv->icon_menu) {
-        auto builder = gtk_builder_new_from_resource("/cx/ring/RingGnome/ringiconmenu.ui");
-        auto menu_model = G_MENU_MODEL(gtk_builder_get_object(builder, "menu"));
-        priv->icon_menu = gtk_menu_new_from_model(menu_model);
 
-        /* enable the menu actions */
-        gtk_widget_insert_action_group(priv->icon_menu, "app", G_ACTION_GROUP(client));
-        g_object_unref(builder);
-        g_object_unref(menu_model);
+        /* for some reason AppIndicator doesn't like the menu being built from a GMenuModel and/or
+         * the GMenuModel being built from an xml resource. So we build the menu in code.
+         */
+        priv->icon_menu = gtk_menu_new();
         g_object_ref_sink(priv->icon_menu);
+
+        auto item = gtk_check_menu_item_new_with_label(C_("In the status icon menu, toggle action to show or hide the Ring main window", "Show Ring"));
+        gtk_actionable_set_action_name(GTK_ACTIONABLE(item), "app.show-main-window");
+        gtk_menu_shell_append(GTK_MENU_SHELL(priv->icon_menu), item);
+
+        item = gtk_menu_item_new_with_label(_("Quit"));
+        gtk_actionable_set_action_name(GTK_ACTIONABLE(item), "app.quit");
+        gtk_menu_shell_append(GTK_MENU_SHELL(priv->icon_menu), item);
+
+        gtk_widget_insert_action_group(priv->icon_menu, "app", G_ACTION_GROUP(client));
+        gtk_widget_show_all(priv->icon_menu);
     }
 
 #if USE_APPINDICATOR
diff --git a/client-gnome/ui/accountimportexportview.ui b/client-gnome/ui/accountimportexportview.ui
new file mode 100644
index 0000000..1a7f4db
--- /dev/null
+++ b/client-gnome/ui/accountimportexportview.ui
@@ -0,0 +1,211 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <requires lib="gtk+" version="3.10"/>
+  <template class="AccountImportExportView" parent="GtkBox">
+    <property name="visible">True</property>
+    <property name="orientation">vertical</property>
+    <property name="spacing">10</property>
+    <property name="border-width">10</property>
+
+    <!-- export or import label, depending on whats  being done -->
+    <child>
+      <object class="GtkLabel" id="label_export">
+        <property name="visible">False</property>
+        <property name="label" translatable="yes">Export selected account</property>
+        <property name="halign">center</property>
+        <property name="valign">start</property>
+        <property name="no-show-all">True</property>
+        <attributes>
+          <attribute name="weight" value="bold"/>
+        </attributes>
+      </object>
+    </child>
+    <child>
+      <object class="GtkLabel" id="label_import">
+        <property name="visible">False</property>
+        <property name="label" translatable="yes">Import accounts</property>
+        <property name="halign">center</property>
+        <property name="valign">start</property>
+        <property name="no-show-all">True</property>
+        <attributes>
+          <attribute name="weight" value="bold"/>
+        </attributes>
+      </object>
+    </child>
+    <!-- end import/export label -->
+
+    <child>
+      <object class="GtkGrid" id="grid_ipmort_export">
+        <property name="visible">True</property>
+        <property name="column-spacing">10</property>
+        <property name="row-spacing">10</property>
+        <property name="halign">center</property>
+        <property name="valign">center</property>
+
+        <!-- location selection row -->
+        <child>
+          <object class="GtkLabel" id="label_location">
+            <property name="visible">True</property>
+            <property name="label" translatable="yes">Location:</property>
+            <property name="halign">end</property>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">1</property>
+          </packing>
+        </child>
+
+        <!-- filechooser for export -->
+        <child>
+          <object class="GtkBox" id="hbox_export_location">
+            <property name="visible">False</property>
+            <property name="orientation">horizontal</property>
+            <property name="spacing">5</property>
+            <property name="no-show-all">True</property>
+            <child>
+              <object class="GtkLabel" id="label_export_location">
+                <property name="visible">True</property>
+                <property name="ellipsize">start</property>
+                <property name="selectable">True</property>
+                <property name="label" translatable="yes">choose location</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkButton" id="button_export_location">
+                <property name="visible">True</property>
+                <property name="tooltip-text" translatable="yes">Choose export location</property>
+                <property name="image">image_choose_file</property>
+                <property name="halign">end</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">1</property>
+          </packing>
+        </child>
+        <!-- end filechooser for export -->
+
+        <!-- filechooser for import -->
+        <child>
+          <object class="GtkFileChooserButton" id="filechooserbutton_import">
+            <property name="visible">False</property>
+            <property name="create_folders">False</property>
+            <property name="action">open</property>
+            <property name="tooltip-text" translatable="yes">Choose archive location</property>
+            <property name="no-show-all">True</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">1</property>
+          </packing>
+        </child>
+        <!-- end filechooser for import -->
+
+        <!-- end location selection row -->
+
+        <!-- password row -->
+        <child>
+          <object class="GtkLabel" id="label_password">
+            <property name="visible">True</property>
+            <property name="label" translatable="yes">Password (required):</property>
+            <property name="halign">end</property>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">2</property>
+          </packing>
+        </child>
+
+        <child>
+          <object class="GtkEntry" id="entry_password">
+            <property name="visible">True</property>
+            <property name="visibility">False</property>
+            <property name="primary_icon_stock">gtk-dialog-authentication</property>
+            <property name="input_purpose">password</property>
+            <property name="tooltip-text" translatable="yes">Enter archive password</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">2</property>
+          </packing>
+        </child>
+        <!-- end password row -->
+
+        <!-- error message label -->
+        <child>
+          <object class="GtkLabel" id="label_error">
+            <property name="visible">True</property>
+            <attributes>
+              <attribute name="foreground" value="red"/>
+            </attributes>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">3</property>
+            <property name="width">2</property>
+          </packing>
+        </child>
+        <!-- end error message label -->
+
+        <child>
+          <object class="GtkButtonBox" id="buttonbox_confirm">
+            <property name="visible">True</property>
+            <property name="layout-style">spread</property>
+            <!-- <property name="valign">end</property> -->
+            <property name="spacing">10</property>
+
+            <child>
+              <object class="GtkButton" id="button_cancel">
+                <property name="visible">True</property>
+                <property name="label" translatable="yes">Cancel</property>
+              </object>
+            </child>
+
+            <child>
+              <object class="GtkButton" id="button_export">
+                <property name="visible">False</property>
+                <property name="sensitive">False</property>
+                <property name="label" translatable="yes">Export</property>
+                <property name="no-show-all">True</property>
+                <style>
+                  <class name="suggested-action"/>
+                </style>
+              </object>
+            </child>
+
+            <child>
+              <object class="GtkButton" id="button_import">
+                <property name="visible">False</property>
+                <property name="sensitive">False</property>
+                <property name="label" translatable="yes">Import</property>
+                <property name="no-show-all">True</property>
+                <style>
+                  <class name="suggested-action"/>
+                </style>
+              </object>
+            </child>
+
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">4</property>
+            <property name="width">2</property>
+          </packing>
+        </child>
+
+      </object>
+      <packing>
+        <property name="fill">True</property>
+        <property name="expand">True</property>
+      </packing>
+    </child>
+
+  </template>
+
+  <object class="GtkImage" id="image_choose_file">
+    <property name="visible">True</property>
+    <property name="icon-name">list-add-symbolic</property>
+  </object>
+
+</interface>
diff --git a/client-gnome/ui/accountview.ui b/client-gnome/ui/accountview.ui
index d2641c4..f3c15c9 100644
--- a/client-gnome/ui/accountview.ui
+++ b/client-gnome/ui/accountview.ui
@@ -30,7 +30,7 @@
         <child>
           <object class="GtkBox" id="hbox_addremove_account">
             <property name="visible">True</property>
-s            <property name="orientation">horizontal</property>
+            <property name="orientation">horizontal</property>
             <property name="spacing">5</property>
             <property name="halign">GTK_ALIGN_CENTER</property>
             <!-- remove account -->
@@ -38,6 +38,7 @@ s            <property name="orientation">horizontal</property>
               <object class="GtkButton" id="button_remove_account">
                 <property name="visible">True</property>
                 <property name="image">image_remove</property>
+                <property name="sensitive">False</property>
                 <property name="tooltip-text" translatable="yes">Remove selected account</property>
                 <child internal-child="accessible">
                   <object class="AtkObject" id="button_remove_account-atkobject">
@@ -85,6 +86,31 @@ s            <property name="orientation">horizontal</property>
           </object>
         </child>
         <!-- end add remove accounts -->
+
+        <!-- import/export account -->
+        <child>
+          <object class="GtkButtonBox" id="buttonbox_import_export">
+            <property name="visible">True</property>
+            <property name="orientation">horizontal</property>
+            <property name="layout-style">spread</property>
+            <property name="margin-top">5</property>
+            <child>
+              <object class="GtkButton" id="button_import_account">
+                <property name="visible">True</property>
+                <property name="label" translatable="yes">Import</property>
+                <property name="tooltip-text" translatable="yes">Import archived account(s)</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkButton" id="button_export_account">
+                <property name="visible">True</property>
+                <property name="label" translatable="yes">Export</property>
+                <property name="sensitive">False</property>
+                <property name="tooltip-text" translatable="yes">Export selected account(s)</property>
+              </object>
+            </child>
+          </object>
+        </child>
       </object>
       <!-- <packing>
       </packing> -->
diff --git a/client-gnome/ui/ringiconmenu.ui b/client-gnome/ui/ringiconmenu.ui
deleted file mode 100644
index a5b439d..0000000
--- a/client-gnome/ui/ringiconmenu.ui
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0"?>
-<interface>
-  <!-- interface-requires gtk+ 3.0 -->
-  <menu id="menu">
-    <section>
-      <item>
-        <attribute name="label" translatable="yes">Show Ring</attribute>
-        <attribute name="action">app.show-main-window</attribute>
-      </item>
-    </section>
-    <section>
-      <item>
-        <attribute name="label" translatable="yes">Quit</attribute>
-        <attribute name="action">app.quit</attribute>
-      </item>
-    </section>
-  </menu>
-</interface>
diff --git a/client-gnome/ui/ui.gresource.xml b/client-gnome/ui/ui.gresource.xml
index 59fb41a..aded6f6 100644
--- a/client-gnome/ui/ui.gresource.xml
+++ b/client-gnome/ui/ui.gresource.xml
@@ -17,6 +17,6 @@
     <file preprocess="xml-stripblanks">choosecontactview.ui</file>
     <file preprocess="xml-stripblanks">chatview.ui</file>
     <file preprocess="xml-stripblanks">avatarmanipulation.ui</file>
-    <file preprocess="xml-stripblanks">ringiconmenu.ui</file>
+    <file preprocess="xml-stripblanks">accountimportexportview.ui</file>
   </gresource>
 </gresources>
diff --git a/daemon/configure.ac b/daemon/configure.ac
index 3e2381d..ab744a1 100644
--- a/daemon/configure.ac
+++ b/daemon/configure.ac
@@ -102,7 +102,7 @@ AM_CONDITIONAL(HAVE_IOS,   test "${HAVE_IOS}" = "1")
 
 dnl FIXME this should be deduced automatically
 AC_DEFINE_UNQUOTED([HAVE_COREAUDIO],
-                    `if test "${HAVE_OSX}" = "1"; then echo 1; else echo 0; fi`,
+                    `if test "${HAVE_OSX}" = "1" || test "${HAVE_IOS}" = "1"; then echo 1; else echo 0; fi`,
                     [Define if you have CoreAudio])
 
 dnl Android is linux, but a bit different
@@ -413,28 +413,8 @@ AS_IF([test "x$enable_video" != "xno"],
      AM_CONDITIONAL(RING_VIDEO, false)
      ]);
 
-dnl TLS support is enabled if it's installed and up to date
-AC_ARG_WITH([tls],
-  [AS_HELP_STRING([--with-tls],
-    [support tls @<:@default=check@:>@])],
-  [],
-  [with_tls=check])
-AS_CASE(["$with_tls"],
-  [yes], [PKG_CHECK_MODULES([GNUTLS], [gnutls >= 3.3], [HAVE_GNUTLS=1])],
-  [no], [HAVE_GNUTLS=0],
-  [PKG_CHECK_MODULES([GNUTLS], [gnutls >= 3.3], [HAVE_GNUTLS=1], [HAVE_GNUTLS=0])])
-
-AC_DEFINE_UNQUOTED([HAVE_TLS], `if test $HAVE_GNUTLS -eq 1; then echo 1; else echo 0; fi`, [Define if you have tls support])
-AM_CONDITIONAL(BUILD_TLS, test "$HAVE_GNUTLS" -eq 1)
-
-# Instant Messaging
-AC_ARG_WITH([instant_messaging],
-    [AS_HELP_STRING([--without-instant_messaging], [disable support for instant-messaging])],
-    [],
-    [with_instant_messaging=yes])
-
-AC_DEFINE_UNQUOTED([HAVE_INSTANT_MESSAGING], `if test "x$with_instant_messaging" = "xyes"; then echo 1; else echo 0; fi`, [Define if you have instant messaging support])
-AM_CONDITIONAL(BUILD_INSTANT_MESSAGING, test "x$with_instant_messaging" = "xyes" )
+dnl check for GnuTLS
+PKG_CHECK_MODULES([GNUTLS], [gnutls >= 3.4.14], [HAVE_GNUTLS=1], [HAVE_GNUTLS=0])
 
 
 # PTHREAD
@@ -530,20 +510,8 @@ AS_CASE(["$with_opus"],
   [PKG_CHECK_MODULES([opus], [opus], [HAVE_OPUS=1], [HAVE_OPUS=0])])
 AM_CONDITIONAL([BUILD_OPUS], [test "$HAVE_OPUS" -eq 1])
 
-# dht is default-enabled, but requires gnutls
-AC_ARG_ENABLE([dht],
-  AS_HELP_STRING([--disable-dht], [disable support for dht]))
-
-AS_IF([test "x$enable_dht" != "xno" -a "$HAVE_GNUTLS" -eq 1],
-      [AC_DEFINE([HAVE_DHT], 1, [Define to enable dht])
-       PKG_CHECK_MODULES([OPENDHT], opendht,
-                         AC_DEFINE([HAVE_DHT], 1, [Define to enable dht])
-                         AM_CONDITIONAL(USE_DHT, true),
-                         AC_DEFINE([HAVE_DHT], 0, [Define to enable dht])
-                         AM_CONDITIONAL(USE_DHT, false)
-                         AC_MSG_WARN([Missing OpenDHT]))],
-      [AC_DEFINE([HAVE_DHT], 0, [Define to enable dht])
-       AM_CONDITIONAL(USE_DHT, false)])
+dnl check for openDHT
+PKG_CHECK_MODULES([OPENDHT], [opendht >= 0.6.1],, AC_MSG_WARN([Missing OpenDHT]))
 
 dnl IPv6 mode is default-disabled
 AC_ARG_ENABLE([ipv6], AS_HELP_STRING([--enable-ipv6], [Enable IPv6 support]))
@@ -563,6 +531,20 @@ AS_IF([test "x$with_upnp" = "xyes"],
          AC_DEFINE([HAVE_LIBUPNP], 0, [Define if you have libupnp])])
       ])
 
+# LIBNATPMP
+dnl check for libnatpmp
+AC_ARG_WITH([natpmp], [AS_HELP_STRING([--without-natpmp],
+            [disable support for NAT-PMP])], [], [with_natpmp=yes])
+
+AS_IF([test "x$with_natpmp" != xno],
+        [AC_CHECK_HEADER([natpmp.h],
+            AC_CHECK_LIB([natpmp], [initnatpmp], [], [with_natpmp=no]),
+            [AC_MSG_WARN([Unable to find the libnatpmp headers (you may need to install the dev package). You may use --without-natpmp to compile without NAT-PMP support.]);
+             with_natpmp=no])
+        ],[])
+
+AC_DEFINE_UNQUOTED([HAVE_LIBNATPMP], `if test "x$with_natpmp" != xno; then echo 1; else echo 0; fi`, [Define if you have libnatpmp])
+
 AC_DEFINE_UNQUOTED([HAVE_SHM], `if test -z "${HAVE_LINUX_TRUE}" && test -z "${HAVE_ANDROID_FALSE}" ; then echo 1; else echo 0; fi`,
 	[Define if you have shared memory support])
 
diff --git a/daemon/contrib/src/ffmpeg/rules.mak b/daemon/contrib/src/ffmpeg/rules.mak
index 34d0263..7b53ed7 100644
--- a/daemon/contrib/src/ffmpeg/rules.mak
+++ b/daemon/contrib/src/ffmpeg/rules.mak
@@ -19,7 +19,6 @@ FFMPEGCONF += \
 		--disable-programs \
 		--disable-sdl
 
-
 #enable muxers/demuxers
 FFMPEGCONF += \
 		--enable-demuxers \
@@ -83,13 +82,24 @@ FFMPEGCONF += \
 		--enable-encoder=tiff \
 		--enable-decoder=tiff
 
+ifdef HAVE_WIN32
 FFMPEGCONF += \
 	--enable-indev=dshow \
 	--enable-indev=gdigrab \
 	--enable-dxva2
+endif
 
 DEPS_ffmpeg = iconv zlib x264 vpx opus speex $(DEPS_vpx)
 
+ifdef HAVE_IOS
+FFMPEGCONF += \
+	--target-os=darwin \
+	--enable-cross-compile \
+	--arch=$(ARCH) \
+	--enable-pic \
+        --enable-indev=avfoundation
+endif
+
 # Linux
 ifdef HAVE_LINUX
 FFMPEGCONF += --target-os=linux --enable-pic
@@ -102,9 +112,11 @@ FFMPEGCONF += --disable-asm
 endif
 endif
 
+ifndef HAVE_IOS
 ifdef HAVE_CROSS_COMPILE
 FFMPEGCONF += --cross-prefix=$(HOST)-
 endif
+endif
 
 # x86 stuff
 ifeq ($(ARCH),i386)
@@ -160,6 +172,7 @@ ffmpeg: ffmpeg-$(FFMPEG_HASH).tar.xz .sum-ffmpeg
 
 .ffmpeg: ffmpeg
 	cd $< && $(HOSTVARS) ./configure \
+		--extra-cflags="$(CFLAGS)" \
 		--extra-ldflags="$(LDFLAGS)" $(FFMPEGCONF) \
                 --prefix="$(PREFIX)" --enable-static --disable-shared
 	cd $< && $(MAKE) install-libs install-headers
diff --git a/daemon/contrib/src/gmp/rules.mak b/daemon/contrib/src/gmp/rules.mak
index 4309a73..96c7980 100644
--- a/daemon/contrib/src/gmp/rules.mak
+++ b/daemon/contrib/src/gmp/rules.mak
@@ -14,7 +14,7 @@ gmp: gmp-$(GMP_VERSION).tar.bz2 .sum-gmp
 
 .gmp: gmp
 ifdef HAVE_IOS
-	cd $< && $(HOSTVARS) ./configure --disable-assembly $(HOSTCONF)
+	cd $< && $(HOSTVARS) CFLAGS="$(CFLAGS) -O3" ./configure --disable-assembly $(HOSTCONF)
 else
 	cd $< && $(HOSTVARS) ./configure $(HOSTCONF)
 endif
diff --git a/daemon/contrib/src/gnutls/SHA512SUMS b/daemon/contrib/src/gnutls/SHA512SUMS
index 5c13629..7292832 100644
--- a/daemon/contrib/src/gnutls/SHA512SUMS
+++ b/daemon/contrib/src/gnutls/SHA512SUMS
@@ -1 +1 @@
-e5cd60240ebbcac9d8f7c28fdbf023a499e3c58a352a43c24d075b248a0a903161b1745641bf263519293c0014424cc23dbb67274c8934aaf273a523ad0a2925  gnutls-3.4.10.tar.xz
+d75f6b4dea2dc742cd7f60ee0ee540d41b69991aaa937ca0138cfdf4a1e0dfaaa3863464303bfa5799e14ee02de252f71c59a7a9e57b96ff8af653e419edfd4e  gnutls-3.4.14.tar.xz
diff --git a/daemon/contrib/src/gnutls/dtls-packet-reordering.patch b/daemon/contrib/src/gnutls/dtls-packet-reordering.patch
deleted file mode 100644
index 24a474a..0000000
--- a/daemon/contrib/src/gnutls/dtls-packet-reordering.patch
+++ /dev/null
@@ -1,5 +0,0 @@
---- a/lib/gnutls_buffers.c
-+++ b/lib/gnutls_buffers.c
-@@ -1033 +1033 @@
--		    && hsk->end_offset >=
-+		    && hsk->end_offset + 1 >=
diff --git a/daemon/contrib/src/gnutls/format-security.patch b/daemon/contrib/src/gnutls/format-security.patch
deleted file mode 100644
index b0b4f32..0000000
--- a/daemon/contrib/src/gnutls/format-security.patch
+++ /dev/null
@@ -1,6 +0,0 @@
-diff -rU0 gnutls-old/lib/x509/ocsp_output.c gnutls/lib/x509/ocsp_output.c
---- gnutls-old/lib/x509/ocsp_output.c
-+++ gnutls/lib/x509/ocsp_output.c
-@@ -289 +289 @@
--					addf(str, _("\tResponder Key ID: "));
-+					adds(str, _("\tResponder Key ID: "));
diff --git a/daemon/contrib/src/gnutls/rules.mak b/daemon/contrib/src/gnutls/rules.mak
index 58fbd75..e7c2280 100644
--- a/daemon/contrib/src/gnutls/rules.mak
+++ b/daemon/contrib/src/gnutls/rules.mak
@@ -1,11 +1,10 @@
 # GnuTLS
 
-GNUTLS_VERSION := 3.4.10
+GNUTLS_VERSION := 3.4.14
 GNUTLS_URL := ftp://ftp.gnutls.org/gcrypt/gnutls/v3.4/gnutls-$(GNUTLS_VERSION).tar.xz
 
 PKGS += gnutls
-# We need at least the 3.4.10, but DTLS handshake re-ordered packet fix is only available since 3.4.14
-# So we patch the 3.4.10 until official release of 3.4.14
+
 ifeq ($(call need_pkg,"gnutls >= 3.4.14"),)
 PKGS_FOUND += gnutls
 endif
@@ -33,8 +32,6 @@ endif
 ifndef HAVE_IOS
 	$(APPLY) $(SRC)/gnutls/mac-keychain-lookup.patch
 endif
-	$(APPLY) $(SRC)/gnutls/format-security.patch
-	$(APPLY) $(SRC)/gnutls/dtls-packet-reordering.patch
 	$(call pkg_static,"lib/gnutls.pc.in")
 	$(UPDATE_AUTOCONFIG)
 	$(MOVE)
@@ -52,6 +49,7 @@ GNUTLS_CONF := \
 	--disable-nls \
 	--disable-dtls-srtp-support \
 	--without-libintl-prefix \
+	--disable-non-suiteb-curves \
 	$(HOSTCONF)
 
 ifdef HAVE_ANDROID
diff --git a/daemon/contrib/src/gsm/include_ios.patch b/daemon/contrib/src/gsm/include_ios.patch
new file mode 100644
index 0000000..80db687
--- /dev/null
+++ b/daemon/contrib/src/gsm/include_ios.patch
@@ -0,0 +1,11 @@
+--- a/src/code.c	2016-06-13 10:49:31.000000000 -0400
++++ b/src/code.c	2016-06-13 10:49:22.000000000 -0400
+@@ -16,6 +16,8 @@
+ 	extern char	* memcpy P((char *, char *, int));
+ #endif
+
++#include <string.h>
++
+ #include	"private.h"
+ #include	"gsm.h"
+ #include	"proto.h"
diff --git a/daemon/contrib/src/gsm/rules.mak b/daemon/contrib/src/gsm/rules.mak
index 2ca2b44..c080287 100644
--- a/daemon/contrib/src/gsm/rules.mak
+++ b/daemon/contrib/src/gsm/rules.mak
@@ -12,6 +12,7 @@ $(TARBALLS)/libgsm_$(GSM_VERSION).tar.gz:
 gsm: libgsm_$(GSM_VERSION).tar.gz .sum-gsm
 	$(UNPACK)
 	mv gsm-1.0-* libgsm_$(GSM_VERSION)
+	$(APPLY) $(SRC)/gsm/include_ios.patch
 	$(APPLY) $(SRC)/gsm/gsm-cross.patch
 	sed -e 's/^CFLAGS.*=/CFLAGS+=/' -i.orig libgsm_$(GSM_VERSION)/Makefile
 	$(MOVE)
diff --git a/daemon/contrib/src/jsoncpp/SHA512SUMS b/daemon/contrib/src/jsoncpp/SHA512SUMS
index 614157b..e42d7f8 100644
--- a/daemon/contrib/src/jsoncpp/SHA512SUMS
+++ b/daemon/contrib/src/jsoncpp/SHA512SUMS
@@ -1 +1 @@
-589153d525ffde15e10f1ef6907c6b5d0f62a41c8cebdc12fe2bc4d989bcd861cdac79526de2f51872c0a17e574bf0fd8c913f0aa301c184efa1e3f2fb2b1955  jsoncpp-1.6.5.tar.gz
+32702147229ea7a3679654325572c38f4188f258ab6ac21f9e04059d53ef2a7cd0542ec4ec3b0e7b9089acd2b7bce389f16b9ff24b2e63e0ba2a5bcd46bab766  jsoncpp-1.7.2.tar.gz
diff --git a/daemon/contrib/src/jsoncpp/rules.mak b/daemon/contrib/src/jsoncpp/rules.mak
index b23b0e6..5be14e8 100644
--- a/daemon/contrib/src/jsoncpp/rules.mak
+++ b/daemon/contrib/src/jsoncpp/rules.mak
@@ -1,5 +1,5 @@
 # JSONCPP
-JSONCPP_VERSION := 1.6.5
+JSONCPP_VERSION := 1.7.2
 JSONCPP_URL := https://github.com/open-source-parsers/jsoncpp/archive/$(JSONCPP_VERSION).tar.gz
 
 PKGS += jsoncpp
diff --git a/daemon/contrib/src/natpmp/SHA512SUMS b/daemon/contrib/src/natpmp/SHA512SUMS
new file mode 100644
index 0000000..956a4e3
--- /dev/null
+++ b/daemon/contrib/src/natpmp/SHA512SUMS
@@ -0,0 +1 @@
+e50b1f68ce9254bb2f068ddc37417a3c417b80f7b3fb3d84e3e9af4a144d89e204ab993b54c01657335e855d0124a8fcbbf96ce78db7b9ae0b03b6eb79de2e09  libnatpmp-20150609.tar.gz
diff --git a/daemon/contrib/src/natpmp/rules.mak b/daemon/contrib/src/natpmp/rules.mak
new file mode 100644
index 0000000..49ddcb0
--- /dev/null
+++ b/daemon/contrib/src/natpmp/rules.mak
@@ -0,0 +1,21 @@
+# libnatpmp
+NATPMP_VERSION := 20150609
+NATPMP_URL := http://miniupnp.free.fr/files/download.php?file=libnatpmp-$(NATPMP_VERSION).tar.gz
+
+PKGS += natpmp
+ifeq ($(call need_pkg,'libnatpmp'),)
+PKGS_FOUND += natpmp
+endif
+
+$(TARBALLS)/libnatpmp-$(NATPMP_VERSION).tar.gz:
+	$(call download,$(NATPMP_URL))
+
+.sum-natpmp: libnatpmp-$(NATPMP_VERSION).tar.gz
+
+natpmp: libnatpmp-$(NATPMP_VERSION).tar.gz .sum-natpmp
+	$(UNPACK)
+	$(MOVE)
+
+.natpmp: natpmp
+	cd $< && $(MAKE) INSTALLPREFIX="$(PREFIX)" install
+	touch $@
diff --git a/daemon/contrib/src/nettle/rules.mak b/daemon/contrib/src/nettle/rules.mak
index 888570e..b245cca 100644
--- a/daemon/contrib/src/nettle/rules.mak
+++ b/daemon/contrib/src/nettle/rules.mak
@@ -5,12 +5,9 @@ NETTLE_URL := $(GNU)/nettle/nettle-$(NETTLE_VERSION).tar.gz
 
 PKGS += nettle
 
-# TEMPORARY DISABLED
-# Force nettle contrib until gnutls major patches are upstream and released
-# See gnutls rules.mak for more information
-#ifeq ($(call need_pkg,"nettle >= 3.1"),)
-#PKGS_FOUND += nettle
-#endif
+ifeq ($(call need_pkg,"nettle >= 3.1"),)
+PKGS_FOUND += nettle
+endif
 
 $(TARBALLS)/nettle-$(NETTLE_VERSION).tar.gz:
 	$(call download,$(NETTLE_URL))
@@ -26,7 +23,9 @@ DEPS_nettle = gmp $(DEPS_gmp)
 
 .nettle: nettle
 ifdef HAVE_IOS
-	cd $< && $(HOSTVARS) ./configure --disable-assembler $(HOSTCONF)
+	cd $< && sed -i.orig s/-ggdb3//g configure.ac
+	cd $< && autoreconf
+	cd $< && $(HOSTVARS) CFLAGS="$(CFLAGS) -O3" ./configure $(HOSTCONF)
 else
 	cd $< && $(HOSTVARS) ./configure $(HOSTCONF)
 endif
diff --git a/daemon/contrib/src/opus/rules.mak b/daemon/contrib/src/opus/rules.mak
index 52f3cbe..bba61a7 100644
--- a/daemon/contrib/src/opus/rules.mak
+++ b/daemon/contrib/src/opus/rules.mak
@@ -25,10 +25,6 @@ ifndef HAVE_FPU
 OPUS_CONF += --enable-fixed-point
 endif
 
-ifdef HAVE_IOS
-OPUS_CONF += --disable-asm
-endif
-
 .opus: opus
 	cd $< && $(HOSTVARS) ./configure $(HOSTCONF) $(OPUS_CONF)
 	cd $< && $(MAKE) install
diff --git a/daemon/contrib/src/pjproject/gnutls.patch b/daemon/contrib/src/pjproject/gnutls.patch
index 778baf5..4d2123a 100644
--- a/daemon/contrib/src/pjproject/gnutls.patch
+++ b/daemon/contrib/src/pjproject/gnutls.patch
@@ -460,7 +460,7 @@ new file mode 100644
 index 0000000..6864740
 --- /dev/null
 +++ b/pjlib/src/pj/ssl_sock_gtls.c
-@@ -0,0 +1,2869 @@
+@@ -0,0 +1,2865 @@
 +/* $Id$ */
 +/*
 + * Copyright (C) 2014-2015 Savoir-faire Linux. (http://www.savoirfairelinux.com)
@@ -1155,11 +1155,7 @@ index 0000000..6864740
 +    if (ssock->param.proto & PJ_SSL_SOCK_PROTO_TLS1) {
 +        pj_strcat2(&priority, "+VERS-TLS1.0:");
 +    }
-+    if (ssock->param.proto & PJ_SSL_SOCK_PROTO_SSL3) {
-+        pj_strcat2(&priority, "+VERS-SSL3.0:");
-+    } else {
-+        pj_strcat2(&priority, "-VERS-SSL3.0:");
-+    }
++    pj_strcat2(&priority, "-VERS-SSL3.0:");
 +    pj_strcat2(&priority, "%LATEST_RECORD_VERSION");
 +
 +    pj_strcat(&cipher_list, &priority);
diff --git a/daemon/contrib/src/speexdsp/rules.mak b/daemon/contrib/src/speexdsp/rules.mak
index 997ea48..05f88a4 100644
--- a/daemon/contrib/src/speexdsp/rules.mak
+++ b/daemon/contrib/src/speexdsp/rules.mak
@@ -1,7 +1,7 @@
 # speexdsp
 
 SPEEXDSP_VERSION := git
-SPEEXDSP_HASH := HEAD
+SPEEXDSP_HASH := 83b63852e0e4755a8c04a1f9c87dd73b5aa6293f
 SPEEXDSP_GITURL := http://git.xiph.org/?p=speexdsp.git;a=snapshot;h=$(SPEEXDSP_HASH);sf=tgz
 
 PKGS += speexdsp
diff --git a/daemon/contrib/src/uuid/rules.mak b/daemon/contrib/src/uuid/rules.mak
index fa620f9..63f3296 100644
--- a/daemon/contrib/src/uuid/rules.mak
+++ b/daemon/contrib/src/uuid/rules.mak
@@ -3,9 +3,13 @@
 UUID_VERSION := 1.0.2
 UUID_URL := $(SF)/libuuid/libuuid-$(UUID_VERSION).tar.gz
 
+ifndef HAVE_IOS
 ifeq ($(call need_pkg,"uuid >= 2.0.0"),)
 PKGS_FOUND += uuid
 endif
+else
+PKGS_FOUND += uuid
+endif
 
 $(TARBALLS)/libuuid-$(UUID_VERSION).tar.gz:
 	$(call download,$(UUID_URL))
diff --git a/daemon/contrib/src/vpx/rules.mak b/daemon/contrib/src/vpx/rules.mak
index 10b6cf4..0d09bd0 100644
--- a/daemon/contrib/src/vpx/rules.mak
+++ b/daemon/contrib/src/vpx/rules.mak
@@ -1,6 +1,11 @@
 # libvpx
 
+#Libav doesnt support new vpx version
+ifdef HAVE_IOS
+VPX_HASH := cbecf57f3e0d85a7b7f97f3ab7c507f6fe640a93
+else
 VPX_HASH := c74bf6d889992c3cabe017ec353ca85c323107cd
+endif
 VPX_URL := https://github.com/webmproject/libvpx/archive/$(VPX_HASH).tar.gz
 #VPX_GITURL := https://code.google.com/p/webm.libvpx
 
@@ -20,13 +25,18 @@ libvpx: libvpx-$(VPX_HASH).tar.gz .sum-vpx
 DEPS_vpx =
 
 ifdef HAVE_CROSS_COMPILE
+ifndef HAVE_IOS
 VPX_CROSS := $(CROSS_COMPILE)
+endif
 else
 VPX_CROSS :=
 endif
 
+
 ifeq ($(ARCH),arm)
 VPX_ARCH := armv7
+else ifeq ($(ARCH),arm64)
+VPX_ARCH := arm64
 else ifeq ($(ARCH),i386)
 VPX_ARCH := x86
 else ifeq ($(ARCH),mips)
@@ -46,7 +56,11 @@ VPX_OS := android
 else ifdef HAVE_LINUX
 VPX_OS := linux
 else ifdef HAVE_DARWIN_OS
-ifeq ($(ARCH),arm)
+ifeq ($(IOS_TARGET_PLATFORM),iPhoneSimulator)
+VPX_OS := iphonesimulator
+else ifeq ($(ARCH),armv7)
+VPX_OS := darwin
+else ifeq ($(ARCH),arm64)
 VPX_OS := darwin
 else
 ifeq ($(OSX_VERSION),10.5)
@@ -95,7 +109,7 @@ ifdef HAVE_MACOSX
 VPX_CONF += --sdk-path=$(MACOSX_SDK)
 endif
 ifdef HAVE_IOS
-VPX_CONF += --sdk-path=$(SDKROOT)
+VPX_CONF += --sdk-path=$(IOS_SDK)
 endif
 LOCAL_HOSTVARS=
 ifdef HAVE_ANDROID
diff --git a/daemon/contrib/src/x264/rules.mak b/daemon/contrib/src/x264/rules.mak
index 9ad7c95..cf5f4d6 100644
--- a/daemon/contrib/src/x264/rules.mak
+++ b/daemon/contrib/src/x264/rules.mak
@@ -22,9 +22,11 @@ X264CONF += --enable-pic
 else
 X264CONF += --enable-win32thread
 endif
+ifndef HAVE_IOS
 ifdef HAVE_CROSS_COMPILE
 X264CONF += --cross-prefix="$(CROSS_COMPILE)"
 endif
+endif
 
 $(TARBALLS)/x264-$(X264_HASH).tar.xz:
 	$(call download_git,$(X264_GITURL),master,$(X264_HASH))
diff --git a/daemon/src/Makefile.am b/daemon/src/Makefile.am
index e76ec02..ffbca3f 100644
--- a/daemon/src/Makefile.am
+++ b/daemon/src/Makefile.am
@@ -23,23 +23,7 @@ RING_VIDEO_LIBS+= \
 endif
 endif
 
-if BUILD_INSTANT_MESSAGING
-INSTANT_MESSAGING_SUBDIR = im
-IM_LIBA=./im/libim.la
-endif
-
-if USE_DHT
-RINGACC_SUBDIR=ringdht
-RINGACC_CXXFLAG=-DUSE_DHT
-RINGACC_LIBA=./ringdht/libringacc.la
-endif
-
-if BUILD_TLS
-TLS_LIB = @GNUTLS_LIBS@
-TLS_CFLAGS = @GNUTLS_CFLAGS@
-endif
-
-SUBDIRS = client media config hooks sip upnp security $(RINGACC_SUBDIR) $(INSTANT_MESSAGING_SUBDIR) $(RING_VIDEO_SUBDIR)
+SUBDIRS = client media config hooks sip upnp security ringdht im $(RING_VIDEO_SUBDIR)
 
 # libring
 
@@ -53,8 +37,8 @@ libring_la_LIBADD = \
 	./hooks/libhooks.la \
 	./security/libsecurity.la \
 	./upnp/libupnpcontrol.la \
-	$(RINGACC_LIBA) \
-	$(IM_LIBA) \
+	./ringdht/libringacc.la \
+	./im/libim.la \
 	$(RING_VIDEO_LIBS)
 
 libring_la_LDFLAGS = \
@@ -68,14 +52,10 @@ libring_la_LDFLAGS = \
 		@SPEEXDSP_LIBS@ \
 		@LIBUPNP_LIBS@ \
 		@PORTAUDIO_LIBS@ \
-		$(TLS_LIB) \
-		$(IM_LIB) \
+		@GNUTLS_LIBS@ \
+		@OPENDHT_LIBS@ \
 		$(PCRE_LIBS)
 
-if USE_DHT
-libring_la_LDFLAGS += $(OPENDHT_LIBS)
-endif
-
 if HAVE_OSX
 #FIXME necessary for -lintl
 libring_la_LDFLAGS += -L/usr/local/opt/gettext/lib
@@ -89,14 +69,11 @@ libring_la_CFLAGS = \
 		@LIBUPNP_CFLAGS@ \
 		@SPEEXDSP_CFLAGS@ \
 		@PORTAUDIO_CFLAGS@ \
-		$(TLS_CFLAGS)
+		@GNUTLS_CFLAGS@ \
+		@OPENDHT_CFLAGS@
 
 libring_la_CXXFLAGS = @JSONCPP_CFLAGS@
 
-if USE_DHT
-libring_la_CFLAGS += $(OPENDHT_CFLAGS)
-endif
-
 libring_la_SOURCES = \
 		buildinfo.cpp \
 		conference.cpp \
diff --git a/daemon/src/account.cpp b/daemon/src/account.cpp
index b1cdbcb..f7cd8fa 100644
--- a/daemon/src/account.cpp
+++ b/daemon/src/account.cpp
@@ -36,12 +36,8 @@
 #include "logger.h"
 #include "manager.h"
 
-#if HAVE_DHT
 #include <opendht/rng.h>
 using random_device = dht::crypto::random_device;
-#else
-using random_device = std::random_device;
-#endif
 
 #include "client/ring_signal.h"
 #include "account_schema.h"
diff --git a/daemon/src/account_factory.cpp b/daemon/src/account_factory.cpp
index 3feb736..5123372 100644
--- a/daemon/src/account_factory.cpp
+++ b/daemon/src/account_factory.cpp
@@ -25,9 +25,7 @@
 #include "account_factory.h"
 
 #include "sip/sipaccount.h"
-#if HAVE_DHT
 #include "ringdht/ringaccount.h"
-#endif
 
 #include <stdexcept>
 
@@ -40,11 +38,9 @@ AccountFactory::AccountFactory()
     auto sipfunc = [](const std::string& id){ return std::make_shared<SIPAccount>(id, true); };
     generators_.insert(std::make_pair(SIPAccount::ACCOUNT_TYPE, sipfunc));
     RING_DBG("registered %s account", SIPAccount::ACCOUNT_TYPE);
-#if HAVE_DHT
     auto dhtfunc = [](const std::string& id){ return std::make_shared<RingAccount>(id, false); };
     generators_.insert(std::make_pair(RingAccount::ACCOUNT_TYPE, dhtfunc));
     RING_DBG("registered %s account", RingAccount::ACCOUNT_TYPE);
-#endif
 }
 
 std::shared_ptr<Account>
diff --git a/daemon/src/call.h b/daemon/src/call.h
index e5c3329..54c264a 100644
--- a/daemon/src/call.h
+++ b/daemon/src/call.h
@@ -299,7 +299,6 @@ class Call : public Recordable, public std::enable_shared_from_this<Call> {
          */
         virtual void carryingDTMFdigits(char code) = 0;
 
-#if HAVE_INSTANT_MESSAGING
         /**
          * Send a message to a call identified by its callid
          *
@@ -308,7 +307,6 @@ class Call : public Recordable, public std::enable_shared_from_this<Call> {
          */
         virtual void sendTextMessage(const std::map<std::string, std::string>& messages,
                                      const std::string &from) = 0;
-#endif
 
         void removeCall();
 
diff --git a/daemon/src/client/callmanager.cpp b/daemon/src/client/callmanager.cpp
index b190d9d..9882973 100644
--- a/daemon/src/client/callmanager.cpp
+++ b/daemon/src/client/callmanager.cpp
@@ -324,9 +324,7 @@ acceptEnrollment(const std::string& /*callID*/, bool /*accepted*/)
 void
 sendTextMessage(const std::string& callID, const std::map<std::string, std::string>& messages, const std::string& from, bool isMixed)
 {
-#if HAVE_INSTANT_MESSAGING
    ring::Manager::instance().sendCallTextMessage(callID, messages, from, isMixed);
-#endif
 }
 
 } // namespace DRing
diff --git a/daemon/src/client/configurationmanager.cpp b/daemon/src/client/configurationmanager.cpp
index b1338c1..233e335 100644
--- a/daemon/src/client/configurationmanager.cpp
+++ b/daemon/src/client/configurationmanager.cpp
@@ -28,10 +28,8 @@
 #include "configurationmanager_interface.h"
 #include "account_schema.h"
 #include "manager.h"
-#if HAVE_TLS && HAVE_DHT
 #include "security/tlsvalidator.h"
 #include "security/certstore.h"
-#endif
 #include "logger.h"
 #include "fileutils.h"
 #include "archiver.h"
@@ -119,17 +117,12 @@ std::map<std::string, std::string>
 validateCertificate(const std::string&,
                     const std::string& certificate)
 {
-#if HAVE_TLS && HAVE_DHT
     try {
         return TlsValidator{CertificateStore::instance().getCertificate(certificate)}.getSerializedChecks();
     } catch(const std::runtime_error& e) {
         RING_WARN("Certificate loading failed: %s", e.what());
         return {{Certificate::ChecksNames::EXIST, Certificate::CheckValuesNames::FAILED}};
     }
-#else
-    RING_WARN("TLS not supported");
-    return {};
-#endif
 }
 
 std::map<std::string, std::string>
@@ -139,38 +132,28 @@ validateCertificatePath(const std::string&,
                     const std::string& privateKeyPass,
                     const std::string& caList)
 {
-#if HAVE_TLS && HAVE_DHT
     try {
         return TlsValidator{certificate, privateKey, privateKeyPass, caList}.getSerializedChecks();
     } catch(const std::runtime_error& e) {
         RING_WARN("Certificate loading failed: %s", e.what());
         return {{Certificate::ChecksNames::EXIST, Certificate::CheckValuesNames::FAILED}};
     }
-#else
-    RING_WARN("TLS not supported");
-    return {};
-#endif
 }
 
 std::map<std::string, std::string>
 getCertificateDetails(const std::string& certificate)
 {
-#if HAVE_TLS && HAVE_DHT
     try {
         return TlsValidator{CertificateStore::instance().getCertificate(certificate)}.getSerializedDetails();
     } catch(const std::runtime_error& e) {
         RING_WARN("Certificate loading failed: %s", e.what());
     }
-#else
-    RING_WARN("TLS not supported");
-#endif
     return {};
 }
 
 std::map<std::string, std::string>
 getCertificateDetailsPath(const std::string& certificate, const std::string& privateKey, const std::string& privateKeyPassword)
 {
-#if HAVE_TLS && HAVE_DHT
     try {
         auto crt = std::make_shared<dht::crypto::Certificate>(ring::fileutils::loadFile(certificate));
         TlsValidator validator {certificate, privateKey, privateKeyPassword};
@@ -179,20 +162,13 @@ getCertificateDetailsPath(const std::string& certificate, const std::string& pri
     } catch(const std::runtime_error& e) {
         RING_WARN("Certificate loading failed: %s", e.what());
     }
-#else
-    RING_WARN("TLS not supported");
-#endif
     return {};
 }
 
 std::vector<std::string>
 getPinnedCertificates()
 {
-#if HAVE_TLS && HAVE_DHT
     return ring::tls::CertificateStore::instance().getPinnedCertificates();
-#else
-    RING_WARN("TLS not supported");
-#endif
     return {};
 }
 
@@ -390,11 +366,9 @@ getSupportedTlsMethod()
 std::vector<std::string>
 getSupportedCiphers(const std::string& accountID)
 {
-#if HAVE_TLS
     if (auto sipaccount = ring::Manager::instance().getAccount<SIPAccount>(accountID))
         return SIPAccount::getSupportedTlsCiphers();
     RING_ERR("SIP account %s doesn't exist", accountID.c_str());
-#endif
     return {};
 }
 
diff --git a/daemon/src/manager.cpp b/daemon/src/manager.cpp
index 6d26387..91d1b74 100644
--- a/daemon/src/manager.cpp
+++ b/daemon/src/manager.cpp
@@ -39,13 +39,9 @@
 #include "map_utils.h"
 #include "account.h"
 #include "string_utils.h"
-#if HAVE_DHT
 #include "ringdht/ringaccount.h"
 #include <opendht/rng.h>
 using random_device = dht::crypto::random_device;
-#else
-using random_device = std::random_device;
-#endif
 
 #include "call_factory.h"
 
@@ -149,7 +145,6 @@ setSipLogLevel()
     pj_log_set_level(level);
 }
 
-#if HAVE_TLS
 /**
  * Set gnutls's log level based on the RING_TLS_LOGLEVEL environment variable.
  * RING_TLS_LOGLEVEL = 0 minimum logging (default)
@@ -182,7 +177,6 @@ setGnuTlsLogLevel()
     gnutls_global_set_log_level(level);
     gnutls_global_set_log_function(tls_print_logs);
 }
-#endif // HAVE_TLS
 
 Manager&
 Manager::instance()
@@ -276,10 +270,8 @@ Manager::init(const std::string &config_file)
     RING_DBG("pjsip version %s for %s initialized",
              pj_get_version(), PJ_OS_NAME);
 
-#if HAVE_TLS
     setGnuTlsLogLevel();
     RING_DBG("GNU TLS version %s initialized", gnutls_check_version(nullptr));
-#endif
 
     ice_tf_.reset(new IceTransportFactory());
 
@@ -1637,7 +1629,6 @@ Manager::incomingCall(Call &call, const std::string& accountId)
 }
 
 //THREAD=VoIP
-#if HAVE_INSTANT_MESSAGING
 void
 Manager::sendTextMessageToConference(const Conference& conf,
                                      const std::map<std::string, std::string>& messages,
@@ -1718,7 +1709,6 @@ Manager::sendCallTextMessage(const std::string& callID,
         }
     }
 }
-#endif // HAVE_INSTANT_MESSAGING
 
 //THREAD=VoIP CALL=Outgoing
 void
@@ -2825,7 +2815,6 @@ Manager::newOutgoingCall(const std::string& toUrl,
 {
     auto preferred = getAccount(preferredAccountId);
 
-#if HAVE_DHT
     if (toUrl.find("ring:") != std::string::npos) {
         if (preferred && preferred->getAccountType() == RingAccount::ACCOUNT_TYPE)
             return preferred->newOutgoingCall(toUrl);
@@ -2834,7 +2823,6 @@ Manager::newOutgoingCall(const std::string& toUrl,
             if (acc->isEnabled())
                 return acc->newOutgoingCall(toUrl);
     }
-#endif
     // If peer url is an IP, and the preferred account is not an "IP2IP like",
     // we try to find a suitable one in all SIPAccount's.
     auto strippedToUrl = toUrl;
diff --git a/daemon/src/manager.h b/daemon/src/manager.h
index a3dde6c..8867184 100644
--- a/daemon/src/manager.h
+++ b/daemon/src/manager.h
@@ -377,7 +377,6 @@ class Manager {
          */
         void peerHungupCall(Call& call);
 
-#if HAVE_INSTANT_MESSAGING
         /**
          * Notify the client with an incoming message
          * @param accountId     The account identifier
@@ -396,7 +395,6 @@ class Manager {
         void sendCallTextMessage(const std::string& callID,
                                  const std::map<std::string, std::string>& messages,
                                  const std::string& from, bool isMixed);
-#endif // HAVE_INSTANT_MESSAGING
 
         /**
          * Notify the client he has voice mails
@@ -1041,11 +1039,9 @@ class Manager {
         /* Sink ID mapping */
         std::map<std::string, std::weak_ptr<video::SinkClient>> sinkMap_;
 
-#if HAVE_INSTANT_MESSAGING
         void sendTextMessageToConference(const Conference& conf,
                                          const std::map<std::string, std::string>& messages,
                                          const std::string& from) const noexcept;
-#endif
 
 #ifdef RING_VIDEO
     std::unique_ptr<VideoManager> videoManager_;
diff --git a/daemon/src/media/audio/Makefile.am b/daemon/src/media/audio/Makefile.am
index 0b4a8de..b26233d 100644
--- a/daemon/src/media/audio/Makefile.am
+++ b/daemon/src/media/audio/Makefile.am
@@ -24,6 +24,10 @@ if HAVE_OSX
 SUBDIRS += coreaudio
 endif
 
+if HAVE_IOS
+SUBDIRS += coreaudio
+endif
+
 if HAVE_PORTAUDIO
 SUBDIRS += portaudio
 endif
@@ -89,6 +93,10 @@ if HAVE_OSX
 libaudio_la_LIBADD += ./coreaudio/libcoreaudiolayer.la
 endif
 
+if HAVE_IOS
+libaudio_la_LIBADD += ./coreaudio/libcoreaudiolayer.la
+endif
+
 if BUILD_OPENSL
 libaudio_la_LIBADD += ./opensl/libopensl.la
 libaudio_la_LDFLAGS += -lOpenSLES
diff --git a/daemon/src/media/audio/coreaudio/Makefile.am b/daemon/src/media/audio/coreaudio/Makefile.am
index 1969b70..be060ee 100644
--- a/daemon/src/media/audio/coreaudio/Makefile.am
+++ b/daemon/src/media/audio/coreaudio/Makefile.am
@@ -4,5 +4,9 @@ if HAVE_OSX
 noinst_LTLIBRARIES = libcoreaudiolayer.la
 endif
 
+if HAVE_IOS
+noinst_LTLIBRARIES = libcoreaudiolayer.la
+endif
+
 libcoreaudiolayer_la_SOURCES = corelayer.cpp corelayer.h audiodevice.cpp audiodevice.h
 libcoreaudiolayer_la_CXXFLAGS = -I$(top_srcdir)/src
diff --git a/daemon/src/media/audio/coreaudio/audiodevice.cpp b/daemon/src/media/audio/coreaudio/audiodevice.cpp
index 2241aca..7389c60 100644
--- a/daemon/src/media/audio/coreaudio/audiodevice.cpp
+++ b/daemon/src/media/audio/coreaudio/audiodevice.cpp
@@ -20,6 +20,8 @@
 
 #include "audiodevice.h"
 
+#if !TARGET_OS_IPHONE
+
 namespace ring {
 
 AudioDevice::AudioDevice(AudioDeviceID devid, bool isInput)
@@ -168,3 +170,5 @@ std::string AudioDevice::getName() const
 }
 
 } // namespace ring
+
+#endif // TARGET_OS_IPHONE
diff --git a/daemon/src/media/audio/coreaudio/audiodevice.h b/daemon/src/media/audio/coreaudio/audiodevice.h
index ba24605..f309bbc 100644
--- a/daemon/src/media/audio/coreaudio/audiodevice.h
+++ b/daemon/src/media/audio/coreaudio/audiodevice.h
@@ -21,14 +21,19 @@
 #ifndef AUDIO_DEVICE_H
 #define AUDIO_DEVICE_H
 
+#import <TargetConditionals.h>
+
+#if !TARGET_OS_IPHONE
 #include <CoreServices/CoreServices.h>
 #include <CoreAudio/CoreAudio.h>
+#endif
 
 #include <string>
 
 namespace ring {
 
 class AudioDevice {
+#if !TARGET_OS_IPHONE
 public:
     AudioDevice() : id_(kAudioDeviceUnknown) { }
     AudioDevice(AudioDeviceID devid, bool isInput);
@@ -48,6 +53,7 @@ public:
 private:
     int     countChannels() const;
     std::string  getName() const;
+#endif
 };
 
 }
diff --git a/daemon/src/media/audio/coreaudio/corelayer.cpp b/daemon/src/media/audio/coreaudio/corelayer.cpp
index c07f70f..5912bba 100644
--- a/daemon/src/media/audio/coreaudio/corelayer.cpp
+++ b/daemon/src/media/audio/coreaudio/corelayer.cpp
@@ -57,8 +57,10 @@ std::vector<std::string> CoreLayer::getCaptureDeviceList() const
 {
     std::vector<std::string> ret;
 
+#if !TARGET_OS_IPHONE
     for (auto x : getDeviceList(true))
         ret.push_back(x.name_);
+#endif
 
     return ret;
 }
@@ -67,10 +69,10 @@ std::vector<std::string> CoreLayer::getPlaybackDeviceList() const
 {
     std::vector<std::string> ret;
 
+#if !TARGET_OS_IPHONE
     for (auto x : getDeviceList(false))
-    {
         ret.push_back(x.name_);
-    }
+#endif
 
     return ret;
 }
@@ -175,6 +177,7 @@ void CoreLayer::initAudioLayerIO()
 
     // Input buffer setup. Note that ioData is empty and we have to store data
     // in another buffer.
+#if !TARGET_OS_IPHONE
     UInt32 bufferSizeFrames = 0;
     size = sizeof(UInt32);
     checkErr(AudioUnitGetProperty(ioUnit_,
@@ -183,6 +186,14 @@ void CoreLayer::initAudioLayerIO()
                 outputBus,
                 &bufferSizeFrames,
                 &size));
+#else
+    Float32 bufferDuration;
+    UInt32 propSize = sizeof(Float32);
+    AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareIOBufferDuration,
+                            &propSize,
+                            &bufferDuration);
+    UInt32 bufferSizeFrames = audioInputFormat_.sample_rate * bufferDuration;
+#endif
 
     UInt32 bufferSizeBytes = bufferSizeFrames * sizeof(Float32);
     size = offsetof(AudioBufferList, mBuffers[0]) +
@@ -392,6 +403,7 @@ void CoreLayer::updatePreference(AudioPreference &preference, int index, DeviceT
 std::vector<AudioDevice> CoreLayer::getDeviceList(bool getCapture) const
 {
     std::vector<AudioDevice> ret;
+#if !TARGET_OS_IPHONE
     UInt32 propsize;
 
     AudioObjectPropertyAddress theAddress = {
@@ -422,7 +434,7 @@ std::vector<AudioDevice> CoreLayer::getDeviceList(bool getCapture) const
         }
     }
     delete[] devids;
-
+#endif
     return ret;
 }
 
diff --git a/daemon/src/media/audio/coreaudio/corelayer.h b/daemon/src/media/audio/coreaudio/corelayer.h
index 51afd5a..b0a00b8 100644
--- a/daemon/src/media/audio/coreaudio/corelayer.h
+++ b/daemon/src/media/audio/coreaudio/corelayer.h
@@ -25,7 +25,9 @@
 #include "noncopyable.h"
 #include <CoreFoundation/CoreFoundation.h>
 #include <AudioToolbox/AudioToolbox.h>
+#if !TARGET_OS_IPHONE
 #include <CoreAudio/AudioHardware.h>
+#endif
 
 #define checkErr( err) \
     if(err) {\
diff --git a/daemon/src/media/video/Makefile.am b/daemon/src/media/video/Makefile.am
index 7e94139..80e8469 100644
--- a/daemon/src/media/video/Makefile.am
+++ b/daemon/src/media/video/Makefile.am
@@ -33,8 +33,7 @@ libvideo_la_SOURCES = \
 	video_receive_thread.cpp video_receive_thread.h \
 	video_sender.cpp video_sender.h \
 	video_rtp_session.cpp video_rtp_session.h \
-	sinkclient.cpp sinkclient.h \
-	video_provider.h
+	sinkclient.cpp sinkclient.h
 
 libvideo_la_LIBADD = @LIBAVCODEC_LIBS@ @LIBAVFORMAT_LIBS@ @LIBAVDEVICE_LIBS@ @LIBSWSCALE_LIBS@ @LIBAVUTIL_LIBS@
 
diff --git a/daemon/src/ringdht/Makefile.am b/daemon/src/ringdht/Makefile.am
index 1ee66dc..1b9219f 100644
--- a/daemon/src/ringdht/Makefile.am
+++ b/daemon/src/ringdht/Makefile.am
@@ -1,7 +1,5 @@
 include $(top_srcdir)/globals.mak
 
-if USE_DHT
-
 noinst_LTLIBRARIES = libringacc.la
 libringacc_la_CXXFLAGS = @CXXFLAGS@
 
@@ -14,5 +12,3 @@ libringacc_la_SOURCES = \
         sip_transport_ice.h \
         sips_transport_ice.cpp \
         sips_transport_ice.h
-
-endif
diff --git a/daemon/src/ringdht/ringaccount.cpp b/daemon/src/ringdht/ringaccount.cpp
index 43aac58..7c91778 100644
--- a/daemon/src/ringdht/ringaccount.cpp
+++ b/daemon/src/ringdht/ringaccount.cpp
@@ -459,8 +459,14 @@ RingAccount::loadIdentity()
     dht::crypto::PrivateKey dht_key;
 
     try {
+#if TARGET_OS_IPHONE
+        const auto path = fileutils::get_data_dir() + DIR_SEPARATOR_STR + getAccountID() + DIR_SEPARATOR_STR;
+        dht_cert = dht::crypto::Certificate(fileutils::loadFile(path + tlsCertificateFile_));
+        dht_key = dht::crypto::PrivateKey(fileutils::loadFile(path + tlsPrivateKeyFile_), tlsPassword_);
+#else
         dht_cert = dht::crypto::Certificate(fileutils::loadFile(tlsCertificateFile_));
         dht_key = dht::crypto::PrivateKey(fileutils::loadFile(tlsPrivateKeyFile_), tlsPassword_);
+#endif
     }
     catch (const std::exception& e) {
         RING_ERR("Error loading identity: %s", e.what());
@@ -479,8 +485,13 @@ RingAccount::loadIdentity()
 
         // save the chain including CA
         saveIdentity(id, idPath_ + DIR_SEPARATOR_STR "dht");
+#if TARGET_OS_IPHONE
+        tlsCertificateFile_ = "dht.crt";
+        tlsPrivateKeyFile_ =  "dht.key";
+#else
         tlsCertificateFile_ = idPath_ + DIR_SEPARATOR_STR "dht.crt";
         tlsPrivateKeyFile_ = idPath_ + DIR_SEPARATOR_STR "dht.key";
+#endif
         tlsPassword_ = {};
 
         username_ = RING_URI_PREFIX+id.second->getId().toString();
diff --git a/daemon/src/sip/sdp.cpp b/daemon/src/sip/sdp.cpp
index baf675a..8e5299b 100644
--- a/daemon/src/sip/sdp.cpp
+++ b/daemon/src/sip/sdp.cpp
@@ -41,12 +41,8 @@
 #include "system_codec_container.h"
 #include "intrin.h" // for UNUSED
 
-#if HAVE_DHT
 #include <opendht/rng.h>
 using random_device = dht::crypto::random_device;
-#else
-using random_device = std::random_device;
-#endif
 
 #include <algorithm>
 #include <cassert>
diff --git a/daemon/src/sip/sipaccount.cpp b/daemon/src/sip/sipaccount.cpp
index 0fab6b8..85e6ad1 100644
--- a/daemon/src/sip/sipaccount.cpp
+++ b/daemon/src/sip/sipaccount.cpp
@@ -86,7 +86,7 @@ static constexpr int MIN_REGISTRATION_TIME = 60;  // seconds
 static constexpr unsigned DEFAULT_REGISTRATION_TIME = 3600;  // seconds
 static constexpr unsigned REGISTRATION_FIRST_RETRY_INTERVAL = 60; // seconds
 static constexpr unsigned REGISTRATION_RETRY_INTERVAL = 300; // seconds
-static const char *const VALID_TLS_PROTOS[] = {"Default", "TLSv1.2", "TLSv1.1", "TLSv1", "SSLv3"};
+static const char *const VALID_TLS_PROTOS[] = {"Default", "TLSv1.2", "TLSv1.1", "TLSv1"};
 
 constexpr const char * const SIPAccount::ACCOUNT_TYPE;
 
@@ -185,10 +185,8 @@ SIPAccount::newOutgoingCall(const std::string& toUrl)
         family = ipv6 ? pj_AF_INET6() : pj_AF_INET();
 
         // TODO: resolve remote host using SIPVoIPLink::resolveSrvName
-        std::shared_ptr<SipTransport> t =
-#if HAVE_TLS
-            isTlsEnabled() ? link_->sipTransportBroker->getTlsTransport(tlsListener_, IpAddr(sip_utils::getHostFromUri(to))) :
-#endif
+        std::shared_ptr<SipTransport> t = isTlsEnabled() ?
+            link_->sipTransportBroker->getTlsTransport(tlsListener_, IpAddr(sip_utils::getHostFromUri(to))) :
             transport_;
         setTransport(t);
         call->setTransport(t);
@@ -655,7 +653,6 @@ SIPAccount::getVolatileAccountDetails() const
         a.emplace(Conf::CONFIG_PRESENCE_NOTE,       presence_->getNote());
     }
 
-#if HAVE_TLS
     if (transport_ and transport_->isSecure() and transport_->isConnected()) {
         const auto& tlsInfos = transport_->getTlsInfos();
         auto cipher = pj_ssl_cipher_name(tlsInfos.cipher);
@@ -673,7 +670,6 @@ SIPAccount::getVolatileAccountDetails() const
         }
         a.emplace(DRing::TlsTransport::TLS_PEER_CA_NUM,    ring::to_string(n));
     }
-#endif
 
     return a;
 }
@@ -788,7 +784,6 @@ void SIPAccount::doRegister2_()
         ipv6 = hostIp_.isIpv6();
 #endif
 
-#if HAVE_TLS
     // Init TLS settings if the user wants to use TLS
     if (tlsEnable_) {
         RING_DBG("TLS is enabled for account %s", accountID_.c_str());
@@ -810,9 +805,7 @@ void SIPAccount::doRegister2_()
                 return;
             }
         }
-    } else
-#endif
-    {
+    } else {
         tlsListener_.reset();
         transportType_ = ipv6 ? PJSIP_TRANSPORT_UDP6 : PJSIP_TRANSPORT_UDP;
     }
@@ -837,12 +830,9 @@ void SIPAccount::doRegister2_()
     try {
         RING_WARN("Creating transport");
         transport_.reset();
-#if HAVE_TLS
         if (isTlsEnabled()) {
             setTransport(link_->sipTransportBroker->getTlsTransport(tlsListener_, hostIp_, tlsServerName_.empty() ? hostname_ : tlsServerName_));
-        } else
-#endif
-        {
+        } else {
             setTransport(link_->sipTransportBroker->getUdpTransport(
                 SipTransportDescr { getTransportType(), getLocalPort(), getLocalInterface() }
             ));
@@ -1143,7 +1133,6 @@ SIPAccount::sendUnregister()
     }
 }
 
-#if HAVE_TLS
 pj_uint32_t
 SIPAccount::tlsProtocolFromString(const std::string& method)
 {
@@ -1155,8 +1144,6 @@ SIPAccount::tlsProtocolFromString(const std::string& method)
         return PJ_SSL_SOCK_PROTO_TLS1_2 | PJ_SSL_SOCK_PROTO_TLS1_1;
     if (method == "TLSv1")
         return PJ_SSL_SOCK_PROTO_TLS1_2 | PJ_SSL_SOCK_PROTO_TLS1_1 | PJ_SSL_SOCK_PROTO_TLS1;
-    if (method == "SSLv3")
-        return PJ_SSL_SOCK_PROTO_SSL3;
     return PJSIP_SSL_DEFAULT_PROTO;
 }
 
@@ -1231,8 +1218,6 @@ void SIPAccount::initTlsConfiguration()
     tlsSetting_.qos_ignore_error = PJ_TRUE;
 }
 
-#endif
-
 void SIPAccount::initStunConfiguration()
 {
     size_t pos;
@@ -1260,13 +1245,10 @@ void SIPAccount::loadConfig()
     if (registrationExpire_ == 0)
         registrationExpire_ = DEFAULT_REGISTRATION_TIME; /** Default expire value for registration */
 
-#if HAVE_TLS
-
     if (tlsEnable_) {
         initTlsConfiguration();
         transportType_ = PJSIP_TRANSPORT_TLS;
     } else
-#endif
         transportType_ = PJSIP_TRANSPORT_UDP;
 }
 
diff --git a/daemon/src/sip/sipaccount.h b/daemon/src/sip/sipaccount.h
index 7a63bf4..5ad7e29 100644
--- a/daemon/src/sip/sipaccount.h
+++ b/daemon/src/sip/sipaccount.h
@@ -571,8 +571,6 @@ class SIPAccount : public SIPAccountBase {
          */
         pjsip_transport_type_e transportType_ {PJSIP_TRANSPORT_UNSPECIFIED};
 
-#if HAVE_TLS
-
         /**
          * Maps a string description of the SSL method
          * to the corresponding enum value in pjsip_ssl_method.
@@ -592,8 +590,6 @@ class SIPAccount : public SIPAccountBase {
          */
         void trimCiphers();
 
-#endif
-
         /**
          * Initializes STUN config from the config file
          */
diff --git a/daemon/src/sip/sipcall.cpp b/daemon/src/sip/sipcall.cpp
index df972e9..4114a7e 100644
--- a/daemon/src/sip/sipcall.cpp
+++ b/daemon/src/sip/sipcall.cpp
@@ -34,15 +34,9 @@
 #include "string_utils.h"
 #include "upnp/upnp_control.h"
 #include "sip_utils.h"
-
 #include "audio/audio_rtp_session.h"
-
 #include "system_codec_container.h"
-
-#if HAVE_INSTANT_MESSAGING
 #include "im/instant_messaging.h"
-#endif
-
 #include "dring/call_const.h"
 #include "dring/media_const.h"
 #include "client/ring_signal.h"
@@ -666,7 +660,6 @@ SIPCall::carryingDTMFdigits(char code)
     dtmfSend(*this, code, getSIPAccount().getDtmfType());
 }
 
-#if HAVE_INSTANT_MESSAGING
 void
 SIPCall::sendTextMessage(const std::map<std::string, std::string>& messages,
                          const std::string& /* from */)
@@ -680,7 +673,6 @@ SIPCall::sendTextMessage(const std::map<std::string, std::string>& messages,
 
     im::sendSipMessage(inv.get(), messages);
 }
-#endif // HAVE_INSTANT_MESSAGING
 
 void
 SIPCall::onFailure(signed cause)
diff --git a/daemon/src/sip/sipcall.h b/daemon/src/sip/sipcall.h
index 4c25206..74f35b1 100644
--- a/daemon/src/sip/sipcall.h
+++ b/daemon/src/sip/sipcall.h
@@ -156,10 +156,8 @@ class SIPCall : public Call
 
         void carryingDTMFdigits(char code) override;
 
-#if HAVE_INSTANT_MESSAGING
         void sendTextMessage(const std::map<std::string, std::string>& messages,
                              const std::string& from) override;
-#endif
 
         SIPAccountBase& getSIPAccount() const;
 
diff --git a/daemon/src/sip/siptransport.cpp b/daemon/src/sip/siptransport.cpp
index 7119f92..a9f4f28 100644
--- a/daemon/src/sip/siptransport.cpp
+++ b/daemon/src/sip/siptransport.cpp
@@ -32,10 +32,8 @@
 
 #include <pjsip.h>
 #include <pjsip/sip_types.h>
-#if HAVE_TLS
 #include <pjsip/sip_transport_tls.h>
 #include <pj/ssl_sock.h>
-#endif
 #include <pjnath.h>
 #include <pjnath/stun_config.h>
 #include <pjlib.h>
@@ -123,7 +121,6 @@ SipTransport::stateCallback(pjsip_transport_state state,
 {
     connected_ = state == PJSIP_TP_STATE_CONNECTED;
 
-#if HAVE_TLS
     auto extInfo = static_cast<const pjsip_tls_state_info*>(info->ext_info);
     if (isSecure() && extInfo && extInfo->ssl_sock_info && extInfo->ssl_sock_info->established) {
         auto tlsInfo = extInfo->ssl_sock_info;
@@ -142,7 +139,6 @@ SipTransport::stateCallback(pjsip_transport_state state,
     } else {
         tlsInfos_ = {};
     }
-#endif
 
     std::vector<SipTransportStateCallback> cbs;
     {
@@ -180,11 +176,11 @@ SipTransportBroker::SipTransportBroker(pjsip_endpoint *endpt,
                                        pj_caching_pool& cp, pj_pool_t& pool) :
 cp_(cp), pool_(pool), endpt_(endpt)
 {
-/*#if HAVE_DHT
+/*
     pjsip_transport_register_type(PJSIP_TRANSPORT_DATAGRAM, "ICE",
                                   pjsip_transport_get_default_port_for_type(PJSIP_TRANSPORT_UDP),
                                   &ice_pj_transport_type_);
-#endif*/
+*/
     RING_DBG("SipTransportBroker@%p", this);
 }
 
@@ -353,7 +349,6 @@ SipTransportBroker::createUdpTransport(const SipTransportDescr& d)
     return ret;
 }
 
-#if HAVE_TLS
 std::shared_ptr<TlsListener>
 SipTransportBroker::getTlsListener(const SipTransportDescr& d, const pjsip_tls_setting* settings)
 {
@@ -423,9 +418,7 @@ SipTransportBroker::getTlsTransport(const std::shared_ptr<TlsListener>& l, const
     }
     return ret;
 }
-#endif
 
-#if HAVE_DHT
 std::shared_ptr<SipTransport>
 SipTransportBroker::getIceTransport(const std::shared_ptr<IceTransport> ice,
                                     unsigned comp_id)
@@ -464,6 +457,5 @@ SipTransportBroker::getTlsIceTransport(const std::shared_ptr<ring::IceTransport>
     }
     return sip_tr;
 }
-#endif
 
 } // namespace ring
diff --git a/daemon/src/sip/siptransport.h b/daemon/src/sip/siptransport.h
index 9a636b3..b12a094 100644
--- a/daemon/src/sip/siptransport.h
+++ b/daemon/src/sip/siptransport.h
@@ -169,22 +169,18 @@ public:
 
     std::shared_ptr<SipTransport> getUdpTransport(const SipTransportDescr&);
 
-#if HAVE_TLS
     std::shared_ptr<TlsListener>
     getTlsListener(const SipTransportDescr&, const pjsip_tls_setting*);
 
     std::shared_ptr<SipTransport>
     getTlsTransport(const std::shared_ptr<TlsListener>&, const IpAddr& remote, const std::string& remote_name = {});
-#endif
 
-#if HAVE_DHT
     std::shared_ptr<SipTransport>
     getIceTransport(const std::shared_ptr<IceTransport>, unsigned comp_id);
 
     std::shared_ptr<SipTransport>
     getTlsIceTransport(const std::shared_ptr<IceTransport>, unsigned comp_id,
                        const tls::TlsParams&);
-#endif
 
     std::shared_ptr<SipTransport> addTransport(pjsip_transport*);
 
@@ -221,9 +217,7 @@ private:
     /**
      * Storage for SIP/ICE transport instances.
      */
-#if HAVE_DHT
     int ice_pj_transport_type_ {PJSIP_TRANSPORT_START_OTHER};
-#endif
 
     pj_caching_pool& cp_;
     pj_pool_t& pool_;
diff --git a/daemon/src/sip/sipvoiplink.cpp b/daemon/src/sip/sipvoiplink.cpp
index 0457584..8874521 100644
--- a/daemon/src/sip/sipvoiplink.cpp
+++ b/daemon/src/sip/sipvoiplink.cpp
@@ -32,19 +32,14 @@
 #include "sipcall.h"
 #include "sipaccount.h"
 
-#if HAVE_DHT
 #include "ringdht/ringaccount.h"
-#endif
 
 #include "manager.h"
 #if HAVE_SDES
 #include "sdes_negotiator.h"
 #endif
 
-#if HAVE_INSTANT_MESSAGING
 #include "im/instant_messaging.h"
-#endif
-
 #include "system_codec_container.h"
 #include "audio/audio_rtp_session.h"
 
@@ -637,7 +632,6 @@ SIPVoIPLink::guessAccount(const std::string& userName,
     std::shared_ptr<SIPAccountBase> IP2IPAccount;
     MatchRank best = MatchRank::NONE;
 
-#if HAVE_DHT
     // DHT accounts
     for (const auto& account : Manager::instance().getAllAccounts<RingAccount>()) {
         if (!account)
@@ -652,7 +646,6 @@ SIPVoIPLink::guessAccount(const std::string& userName,
             result = account;
         }
     }
-#endif
 
     // SIP accounts
     for (const auto& account : Manager::instance().getAllAccounts<SIPAccount>()) {
@@ -1113,7 +1106,6 @@ static void
 onRequestMessage(pjsip_inv_session* /*inv*/, pjsip_rx_data* /*rdata*/, pjsip_msg* msg,
                  SIPCall& call)
 {
-#if HAVE_INSTANT_MESSAGING
     if (!msg->body)
         return;
 
@@ -1122,8 +1114,6 @@ onRequestMessage(pjsip_inv_session* /*inv*/, pjsip_rx_data* /*rdata*/, pjsip_msg
     //      in the future
     Manager::instance().incomingMessage(call.getCallId(), call.getPeerNumber(),
                                         im::parseSipMessage(msg));
-
-#endif // HAVE_INSTANT_MESSAGING
 }
 
 static void
diff --git a/daemon/src/upnp/upnp_context.cpp b/daemon/src/upnp/upnp_context.cpp
index a994dd8..ace784f 100644
--- a/daemon/src/upnp/upnp_context.cpp
+++ b/daemon/src/upnp/upnp_context.cpp
@@ -38,17 +38,17 @@
 #include <upnp/upnptools.h>
 #endif
 
+#if HAVE_LIBNATPMP
+#include <natpmp.h>
+#endif
+
 #include "logger.h"
 #include "ip_utils.h"
 #include "upnp_igd.h"
 #include "intrin.h"
 
-#if HAVE_DHT
 #include <opendht/rng.h>
 using random_device = dht::crypto::random_device;
-#else
-using random_device = std::random_device;
-#endif
 
 namespace ring { namespace upnp {
 
@@ -65,6 +65,20 @@ getUPnPContext()
     return context;
 }
 
+/* UPnP error codes */
+constexpr static int INVALID_ARGS = 402;
+constexpr static int ARRAY_IDX_INVALID = 713;
+constexpr static int CONFLICT_IN_MAPPING = 718;
+
+/* max number of times to retry mapping if it fails due to conflict;
+ * there isn't much logic in picking this number... ideally not many ports should
+ * be mapped in a system, so a few number of random port retries should work;
+ * a high number of retries would indicate there might be some kind of bug or else
+ * incompatibility with the router; we use it to prevent an infinite loop of
+ * retrying to map the entry
+ */
+constexpr static unsigned MAX_RETRIES = 20;
+
 #if HAVE_LIBUPNP
 
 /* UPnP IGD definitions */
@@ -75,23 +89,10 @@ constexpr static const char * UPNP_WANCON_DEVICE = "urn:schemas-upnp-org:device:
 constexpr static const char * UPNP_WANIP_SERVICE = "urn:schemas-upnp-org:service:WANIPConnection:1";
 constexpr static const char * UPNP_WANPPP_SERVICE = "urn:schemas-upnp-org:service:WANPPPConnection:1";
 
-/* UPnP error codes */
-constexpr static int          INVALID_ARGS = 402;
 constexpr static const char * INVALID_ARGS_STR = "402";
-constexpr static int          ARRAY_IDX_INVALID = 713;
 constexpr static const char * ARRAY_IDX_INVALID_STR = "713";
-constexpr static int          CONFLICT_IN_MAPPING = 718;
 constexpr static const char * CONFLICT_IN_MAPPING_STR = "718";
 
-/* max number of times to retry mapping if it fails due to conflict;
- * there isn't much logic in picking this number... ideally not many ports should
- * be mapped in a system, so a few number of random port retries should work;
- * a high number of retries would indicate there might be some kind of bug or else
- * incompatibility with the router; we use it to prevent an infinite loop of
- * retrying to map the entry
- */
-constexpr static unsigned MAX_RETRIES = 20;
-
 /*
  * Local prototypes
  */
@@ -100,18 +101,68 @@ static std::string get_first_doc_item(IXML_Document*, const char*);
 static std::string get_first_element_item(IXML_Element*, const char*);
 static void checkResponseError(IXML_Document*);
 
-static int
-cp_callback(Upnp_EventType event_type, void* event, void* user_data)
-{
-    if (auto upnpContext = static_cast<UPnPContext*>(user_data))
-        return upnpContext->handleUPnPEvents(event_type, event);
+#else
 
-    RING_WARN("UPnP callback without UPnPContext");
-    return 0;
-}
+constexpr static int UPNP_E_SUCCESS = 0;
+
+#endif // HAVE_LIBUPNP
 
 UPnPContext::UPnPContext()
 {
+#if HAVE_LIBNATPMP
+    pmpThread_ = std::thread([this]() {
+        PMPIGD* pmp_igd = new PMPIGD();
+        natpmp_t natpmp;
+        bool found {false};
+
+        while (pmpRun_) {
+            if (initnatpmp(&natpmp, 0, 0) < 0) {
+                RING_ERR("NAT-PMP: can't initialize libnatpmp");
+                std::unique_lock<std::mutex> lk(pmpMutex_);
+                pmpCv_.wait_for(lk, std::chrono::minutes(1));
+            } else {
+                RING_DBG("NAT-PMP: initialized");
+                break;
+            }
+        }
+
+        while (pmpRun_) {
+            std::unique_lock<std::mutex> lk(pmpMutex_);
+            pmpCv_.wait_until(lk, pmp_igd->getRenewalTime(), [&] {
+                return not pmpRun_ or pmp_igd->getRenewalTime() <= clock::now();
+            });
+            if (not pmpRun_) break;
+
+            auto now = clock::now();
+
+            if (pmp_igd->renewal_ < now) {
+                PMPsearchForIGD(pmp_igd, natpmp, found);
+            }
+            if (found) {
+                if (pmp_igd->clearAll_) {
+                    PMPdeleteAllPortMapping(*pmp_igd, natpmp, NATPMP_PROTOCOL_UDP);
+                    PMPdeleteAllPortMapping(*pmp_igd, natpmp, NATPMP_PROTOCOL_TCP);
+                    pmp_igd->clearAll_ = false;
+                    pmp_igd->toRemove_.clear();
+                } else if (not pmp_igd->toRemove_.empty()) {
+                    for (auto& m : pmp_igd->toRemove_)
+                        PMPaddPortMapping(*pmp_igd, natpmp, m, true);
+                    pmp_igd->toRemove_.clear();
+                }
+                auto mapping = pmp_igd->getNextMappingToRenew();
+                if (mapping and mapping->renewal_ < now)
+                    PMPaddPortMapping(*pmp_igd, natpmp, *mapping);
+            }
+        }
+        if (not found) delete pmp_igd;
+        closenatpmp(&natpmp);
+        RING_DBG("NAT-PMP: ended");
+    });
+    clientRegistered_ = true;
+#endif
+
+#if HAVE_LIBUPNP
+
     int upnp_err;
     char* ip_address = nullptr;
     unsigned short port = 0;
@@ -159,19 +210,39 @@ UPnPContext::UPnPContext()
      * we will probably receive their advertisements either way
      */
     searchForIGD();
+#endif
 }
 
 UPnPContext::~UPnPContext()
 {
     /* make sure everything is unregistered, freed, and UpnpFinish() is called */
-
     {
         std::lock_guard<std::mutex> lock(validIGDMutex_);
         for( auto const &it : validIGDs_) {
-            removeMappingsByLocalIPAndDescription(it.second.get(), Mapping::UPNP_DEFAULT_MAPPING_DESCRIPTION);
+#if HAVE_LIBUPNP
+            if (auto igd = dynamic_cast<UPnPIGD*>(it.second.get()))
+                removeMappingsByLocalIPAndDescription(*igd, Mapping::UPNP_DEFAULT_MAPPING_DESCRIPTION);
+#endif
+#if HAVE_LIBNATPMP
+            if (auto pmp = dynamic_cast<PMPIGD*>(it.second.get())) {
+                {
+                    std::lock_guard<std::mutex> lk(pmpMutex_);
+                    pmp->clearAll();
+                }
+                pmpCv_.notify_all();
+            }
+#endif
         }
     }
 
+#if HAVE_LIBNATPMP
+    pmpRun_ = false;
+    pmpCv_.notify_all();
+    if (pmpThread_.joinable())
+        pmpThread_.join();
+#endif
+
+#if HAVE_LIBUPNP
     if (clientRegistered_)
         UpnpUnRegisterClient( ctrlptHandle_ );
 
@@ -181,21 +252,7 @@ UPnPContext::~UPnPContext()
 #ifndef _WIN32
     UpnpFinish();
 #endif
-}
-
-void
-UPnPContext::searchForIGD()
-{
-    if (not clientRegistered_) {
-        RING_WARN("UPnP: Control Point not registered");
-        return;
-    }
-
-    /* send out search for both types, as some routers may possibly only reply to one */
-    UpnpSearchAsync(ctrlptHandle_, SEARCH_TIMEOUT, UPNP_ROOT_DEVICE, this);
-    UpnpSearchAsync(ctrlptHandle_, SEARCH_TIMEOUT, UPNP_IGD_DEVICE, this);
-    UpnpSearchAsync(ctrlptHandle_, SEARCH_TIMEOUT, UPNP_WANIP_SERVICE, this);
-    UpnpSearchAsync(ctrlptHandle_, SEARCH_TIMEOUT, UPNP_WANPPP_SERVICE, this);
+#endif
 }
 
 bool
@@ -243,7 +300,11 @@ UPnPContext::chooseIGD_unlocked() const
 {
     if (validIGDs_.empty())
         return nullptr;
-    return validIGDs_.begin()->second.get();
+    auto natpmp = validIGDs_.find("NATPMP");
+    if (natpmp == validIGDs_.end())
+        return validIGDs_.begin()->second.get();
+    else
+        return natpmp->second.get();
 }
 
 /**
@@ -288,11 +349,21 @@ UPnPContext::addMapping(IGD* igd,
     }
 
     /* mapping doesn't exist, so try to add it */
-    RING_DBG("UPnP: adding port mapping : %s", mapping.toString().c_str());
+    RING_DBG("adding port mapping : %s", mapping.toString().c_str());
 
-    if(addPortMapping(igd, mapping, upnp_error)) {
+#if HAVE_LIBUPNP
+    auto upnp = dynamic_cast<const UPnPIGD*>(igd);
+    if (not upnp or addPortMapping(*upnp, mapping, upnp_error))
+#endif
+    {
         /* success; add it to global list */
         globalMappings->emplace(port_external, std::move(GlobalMapping{mapping}));
+#if HAVE_LIBNATPMP
+#if HAVE_LIBUPNP
+        if (not upnp)
+#endif
+            pmpCv_.notify_all();
+#endif
         return mapping;
     }
     return {};
@@ -308,17 +379,17 @@ generateRandomPort()
     /* define the range */
     static std::uniform_int_distribution<uint16_t> dist(Mapping::UPNP_PORT_MIN, Mapping::UPNP_PORT_MAX);
 
-    return dist(gen);;
+    return dist(gen);
 }
 
 /**
  * chooses a random port that is not yet used by the daemon for UPnP
  */
 uint16_t
-UPnPContext::chooseRandomPort(const IGD* igd, PortType type)
+UPnPContext::chooseRandomPort(const IGD& igd, PortType type)
 {
     auto globalMappings = type == PortType::UDP ?
-                          &igd->udpMappings : &igd->tcpMappings;
+                          &igd.udpMappings : &igd.tcpMappings;
 
     uint16_t port = generateRandomPort();
 
@@ -367,7 +438,7 @@ UPnPContext::addAnyMapping(uint16_t port_desired,
         auto iter = globalMappings->find(port_desired);
         if (iter != globalMappings->end()) {
             /* port already used, we need a unique port */
-            port_desired = chooseRandomPort(igd, type);
+            port_desired = chooseRandomPort(*igd, type);
         }
     }
 
@@ -392,7 +463,7 @@ UPnPContext::addAnyMapping(uint16_t port_desired,
         RING_DBG("UPnP: mapping failed (conflicting entry? err = %d), trying with a different port.",
                  upnp_error);
         /* TODO: make sure we don't try sellecting the same random port twice if it fails ? */
-        port_desired = chooseRandomPort(igd, type);
+        port_desired = chooseRandomPort(*igd, type);
         if (use_same_port)
             port_local = port_desired;
         mapping = addMapping(igd, port_desired, port_local, type, &upnp_error);
@@ -427,21 +498,33 @@ UPnPContext::removeMapping(const Mapping& mapping)
     auto iter = globalMappings->find(mapping.getPortExternal());
     if ( iter != globalMappings->end() ) {
         /* make sure its the same mapping */
-        GlobalMapping *global_mapping = &iter->second;
-        if (mapping == *global_mapping ) {
+        GlobalMapping& global_mapping = iter->second;
+        if (mapping == global_mapping ) {
             /* now check the users */
-            if (global_mapping->users > 1) {
+            if (global_mapping.users > 1) {
                 /* more than one user, simply decrement the number */
-                --(global_mapping->users);
+                --(global_mapping.users);
                 RING_DBG("UPnP: decrementing users of mapping: %s, %d users remaining",
-                         mapping.toString().c_str(), global_mapping->users);
+                         mapping.toString().c_str(), global_mapping.users);
             } else {
                 /* no other users, can delete */
                 RING_DBG("UPnP: removing port mapping : %s",
                          mapping.toString().c_str());
-                deletePortMapping(igd,
-                                  mapping.getPortExternalStr(),
-                                  mapping.getTypeStr());
+#if HAVE_LIBUPNP
+                if (auto upnp = dynamic_cast<UPnPIGD*>(igd))
+                    deletePortMapping(*upnp,
+                                      mapping.getPortExternalStr(),
+                                      mapping.getTypeStr());
+#endif
+#if HAVE_LIBNATPMP
+                if (auto pmp = dynamic_cast<PMPIGD*>(igd)) {
+                    {
+                        std::lock_guard<std::mutex> lk(pmpMutex_);
+                        pmp->toRemove_.emplace_back(std::move(global_mapping));
+                    }
+                    pmpCv_.notify_all();
+                }
+#endif
                 globalMappings->erase(iter);
             }
         } else {
@@ -482,6 +565,117 @@ UPnPContext::getExternalIP() const
     return {};
 }
 
+#if HAVE_LIBNATPMP
+
+void
+UPnPContext::PMPsearchForIGD(PMPIGD* pmp_igd, natpmp_t& natpmp, bool& found)
+{
+    if (sendpublicaddressrequest(&natpmp) < 0) {
+        RING_ERR("NAT-PMP: can't send request");
+        pmp_igd->renewal_ = clock::now() + std::chrono::minutes(1);
+        return;
+    }
+
+    while (pmpRun_) {
+        natpmpresp_t response;
+        std::this_thread::sleep_for(std::chrono::milliseconds(2));
+        auto r = readnatpmpresponseorretry(&natpmp, &response);
+        if (r < 0 && r != NATPMP_TRYAGAIN) {
+            RING_WARN("NAT-PMP: can't find device");
+            pmp_igd->renewal_ = clock::now() + std::chrono::minutes(5);
+            break;
+        }
+        else if (r != NATPMP_TRYAGAIN) {
+            pmp_igd->localIp = ip_utils::getLocalAddr(AF_INET);
+            pmp_igd->publicIp = IpAddr(response.pnu.publicaddress.addr);
+            if (not found) {
+                found = true;
+                RING_DBG("NAT-PMP: found new device");
+                RING_DBG("NAT-PMP: got external IP: %s", pmp_igd->publicIp.toString().c_str());
+                {
+                    std::lock_guard<std::mutex> lock(validIGDMutex_);
+                    validIGDs_.emplace("NATPMP", std::unique_ptr<IGD>(pmp_igd));
+                    validIGDCondVar_.notify_all();
+                    for (const auto& l : igdListeners_)
+                        l.second();
+                }
+            }
+            pmp_igd->renewal_ = clock::now() + std::chrono::minutes(1);
+            break;
+        }
+    }
+}
+
+void
+UPnPContext::PMPaddPortMapping(const PMPIGD& /*pmp_igd*/, natpmp_t& natpmp, GlobalMapping& mapping, bool remove) const
+{
+    if (sendnewportmappingrequest(&natpmp,
+                                  mapping.getType() == PortType::UDP ? NATPMP_PROTOCOL_UDP : NATPMP_PROTOCOL_TCP,
+                                  mapping.getPortInternal(),
+                                  mapping.getPortExternal(), remove ? 0 : 3600) < 0) {
+        RING_ERR("NAT-PMP: can't send port mapping request");
+        mapping.renewal_ = clock::now() + std::chrono::minutes(1);
+        return;
+    }
+    RING_DBG("NAT-PMP: sent port mapping %srequest", remove ? "removal " : "");
+    while (pmpRun_) {
+        natpmpresp_t response;
+        std::this_thread::sleep_for(std::chrono::milliseconds(2));
+        auto r = readnatpmpresponseorretry(&natpmp, &response);
+        if (r < 0 && r != NATPMP_TRYAGAIN) {
+            RING_ERR("NAT-PMP: can't %sregister port mapping", remove ? "un" : "");
+            break;
+        }
+        else if (r != NATPMP_TRYAGAIN) {
+            mapping.renewal_ = clock::now()
+                             + std::chrono::seconds(response.pnu.newportmapping.lifetime/2);
+            break;
+        }
+    }
+}
+
+void
+UPnPContext::PMPdeleteAllPortMapping(const PMPIGD& /*pmp_igd*/, natpmp_t& natpmp, int proto) const
+{
+    if (sendnewportmappingrequest(&natpmp, proto, 0, 0, 0) < 0) {
+        RING_ERR("NAT-PMP: can't send all port mapping removal request");
+        return;
+    }
+    RING_DBG("NAT-PMP: sent all port mapping removal request");
+    while (pmpRun_) {
+        natpmpresp_t response;
+        std::this_thread::sleep_for(std::chrono::milliseconds(2));
+        auto r = readnatpmpresponseorretry(&natpmp, &response);
+        if (r < 0 && r != NATPMP_TRYAGAIN) {
+            RING_ERR("NAT-PMP: can't remove all port mappings");
+            break;
+        }
+        else if (r != NATPMP_TRYAGAIN) {
+            break;
+        }
+    }
+}
+
+#endif /* HAVE_LIBNATPMP */
+
+
+#if HAVE_LIBUPNP
+
+void
+UPnPContext::searchForIGD()
+{
+    if (not clientRegistered_) {
+        RING_WARN("UPnP: Control Point not registered");
+        return;
+    }
+
+    /* send out search for both types, as some routers may possibly only reply to one */
+    UpnpSearchAsync(ctrlptHandle_, SEARCH_TIMEOUT, UPNP_ROOT_DEVICE, this);
+    UpnpSearchAsync(ctrlptHandle_, SEARCH_TIMEOUT, UPNP_IGD_DEVICE, this);
+    UpnpSearchAsync(ctrlptHandle_, SEARCH_TIMEOUT, UPNP_WANIP_SERVICE, this);
+    UpnpSearchAsync(ctrlptHandle_, SEARCH_TIMEOUT, UPNP_WANPPP_SERVICE, this);
+}
+
 /**
  * Parses the device description and adds desired devices to
  * relevant lists
@@ -532,7 +726,7 @@ UPnPContext::parseIGD(IXML_Document* doc, const Upnp_Discovery* d_event)
         }
     }
 
-    std::unique_ptr<IGD> new_igd;
+    std::unique_ptr<UPnPIGD> new_igd;
     int upnp_err;
 
     std::string friendlyName = get_first_doc_item(doc, "friendlyName");
@@ -620,9 +814,9 @@ UPnPContext::parseIGD(IXML_Document* doc, const Upnp_Discovery* d_event)
                     if (not (serviceId.empty() and controlURL.empty() and eventSubURL.empty()) ) {
                         /* RING_DBG("UPnP: got service info from device:\n\tserviceType: %s\n\tserviceID: %s\n\tcontrolURL: %s\n\teventSubURL: %s",
                                  serviceType.c_str(), serviceId.c_str(), controlURL.c_str(), eventSubURL.c_str()); */
-                        new_igd.reset(new IGD(UDN, baseURL, friendlyName, serviceType, serviceId, controlURL, eventSubURL));
-                        if (isIGDConnected(new_igd.get())) {
-                            new_igd->publicIp = getExternalIP(new_igd.get());
+                        new_igd.reset(new UPnPIGD(UDN, baseURL, friendlyName, serviceType, serviceId, controlURL, eventSubURL));
+                        if (isIGDConnected(*new_igd)) {
+                            new_igd->publicIp = getExternalIP(*new_igd);
                             if (new_igd->publicIp) {
                                 RING_DBG("UPnP: got external IP: %s", new_igd->publicIp.toString().c_str());
                                 new_igd->localIp = ip_utils::getLocalAddr(pj_AF_INET());
@@ -650,7 +844,7 @@ UPnPContext::parseIGD(IXML_Document* doc, const Upnp_Discovery* d_event)
         {
             std::lock_guard<std::mutex> lock(validIGDMutex_);
             /* delete all RING mappings first */
-            removeMappingsByLocalIPAndDescription(new_igd.get(), Mapping::UPNP_DEFAULT_MAPPING_DESCRIPTION);
+            removeMappingsByLocalIPAndDescription(*new_igd, Mapping::UPNP_DEFAULT_MAPPING_DESCRIPTION);
             validIGDs_.emplace(UDN, std::move(new_igd));
             validIGDCondVar_.notify_all();
             for (const auto& l : igdListeners_)
@@ -701,6 +895,17 @@ get_first_element_item(IXML_Element* element, const char* item)
     }
     return ret;
 }
+
+int
+UPnPContext::cp_callback(Upnp_EventType event_type, void* event, void* user_data)
+{
+    if (auto upnpContext = static_cast<UPnPContext*>(user_data))
+        return upnpContext->handleUPnPEvents(event_type, event);
+
+    RING_WARN("UPnP callback without UPnPContext");
+    return 0;
+}
+
 int
 UPnPContext::handleUPnPEvents(Upnp_EventType event_type, void* event)
 {
@@ -870,22 +1075,22 @@ checkResponseError(IXML_Document* doc)
 }
 
 bool
-UPnPContext::isIGDConnected(const IGD* igd)
+UPnPContext::isIGDConnected(const UPnPIGD& igd)
 {
     bool connected = false;
     std::unique_ptr<IXML_Document, decltype(ixmlDocument_free)&> action(nullptr, ixmlDocument_free);
-    action.reset(UpnpMakeAction("GetStatusInfo", igd->getServiceType().c_str(), 0, nullptr));
+    action.reset(UpnpMakeAction("GetStatusInfo", igd.getServiceType().c_str(), 0, nullptr));
 
     std::unique_ptr<IXML_Document, decltype(ixmlDocument_free)&> response(nullptr, ixmlDocument_free);
     IXML_Document* response_ptr = nullptr;
-    int upnp_err = UpnpSendAction(ctrlptHandle_, igd->getControlURL().c_str(),
-                                  igd->getServiceType().c_str(), nullptr, action.get(), &response_ptr);
+    int upnp_err = UpnpSendAction(ctrlptHandle_, igd.getControlURL().c_str(),
+                                  igd.getServiceType().c_str(), nullptr, action.get(), &response_ptr);
     response.reset(response_ptr);
     checkResponseError(response.get());
     if( upnp_err != UPNP_E_SUCCESS) {
         /* TODO: if failed, should we chck if the igd is disconnected? */
         RING_WARN("UPnP: Failed to get GetStatusInfo from: %s, %d: %s",
-                  igd->getServiceType().c_str(), upnp_err, UpnpGetErrorMessage(upnp_err));
+                  igd.getServiceType().c_str(), upnp_err, UpnpGetErrorMessage(upnp_err));
 
         return false;
     }
@@ -903,21 +1108,21 @@ UPnPContext::isIGDConnected(const IGD* igd)
 }
 
 IpAddr
-UPnPContext::getExternalIP(const IGD* igd)
+UPnPContext::getExternalIP(const UPnPIGD& igd)
 {
     std::unique_ptr<IXML_Document, decltype(ixmlDocument_free)&> action(nullptr, ixmlDocument_free);
-    action.reset(UpnpMakeAction("GetExternalIPAddress", igd->getServiceType().c_str(), 0, nullptr));
+    action.reset(UpnpMakeAction("GetExternalIPAddress", igd.getServiceType().c_str(), 0, nullptr));
 
     std::unique_ptr<IXML_Document, decltype(ixmlDocument_free)&> response(nullptr, ixmlDocument_free);
     IXML_Document* response_ptr = nullptr;
-    int upnp_err = UpnpSendAction(ctrlptHandle_, igd->getControlURL().c_str(),
-                                  igd->getServiceType().c_str(), nullptr, action.get(), &response_ptr);
+    int upnp_err = UpnpSendAction(ctrlptHandle_, igd.getControlURL().c_str(),
+                                  igd.getServiceType().c_str(), nullptr, action.get(), &response_ptr);
     response.reset(response_ptr);
     checkResponseError(response.get());
     if( upnp_err != UPNP_E_SUCCESS) {
         /* TODO: if failed, should we chck if the igd is disconnected? */
         RING_WARN("UPnP: Failed to get GetExternalIPAddress from: %s, %d: %s",
-                  igd->getServiceType().c_str(), upnp_err, UpnpGetErrorMessage(upnp_err));
+                  igd.getServiceType().c_str(), upnp_err, UpnpGetErrorMessage(upnp_err));
         return {};
     }
 
@@ -926,15 +1131,15 @@ UPnPContext::getExternalIP(const IGD* igd)
 }
 
 void
-UPnPContext::removeMappingsByLocalIPAndDescription(const IGD* igd, const std::string& description)
+UPnPContext::removeMappingsByLocalIPAndDescription(const UPnPIGD& igd, const std::string& description)
 {
-    if (!igd->localIp) {
+    if (!igd.localIp) {
         RING_DBG("UPnP: cannot determine local IP in function removeMappingsByLocalIPAndDescription()");
         return;
     }
 
     RING_DBG("UPnP: removing all port mappings with description: \"%s\" and local ip: %s",
-             description.c_str(), igd->localIp.toString().c_str());
+             description.c_str(), igd.localIp.toString().c_str());
 
     int entry_idx = 0;
     bool done = false;
@@ -942,19 +1147,19 @@ UPnPContext::removeMappingsByLocalIPAndDescription(const IGD* igd, const std::st
     do {
         std::unique_ptr<IXML_Document, decltype(ixmlDocument_free)&> action(nullptr, ixmlDocument_free);
         IXML_Document* action_ptr = nullptr;
-        UpnpAddToAction(&action_ptr, "GetGenericPortMappingEntry", igd->getServiceType().c_str(),
+        UpnpAddToAction(&action_ptr, "GetGenericPortMappingEntry", igd.getServiceType().c_str(),
                         "NewPortMappingIndex", ring::to_string(entry_idx).c_str());
         action.reset(action_ptr);
 
         std::unique_ptr<IXML_Document, decltype(ixmlDocument_free)&> response(nullptr, ixmlDocument_free);
         IXML_Document* response_ptr = nullptr;
-        int upnp_err = UpnpSendAction(ctrlptHandle_, igd->getControlURL().c_str(),
-                                      igd->getServiceType().c_str(), nullptr, action.get(), &response_ptr);
+        int upnp_err = UpnpSendAction(ctrlptHandle_, igd.getControlURL().c_str(),
+                                      igd.getServiceType().c_str(), nullptr, action.get(), &response_ptr);
         response.reset(response_ptr);
         if( not response and upnp_err != UPNP_E_SUCCESS) {
             /* TODO: if failed, should we chck if the igd is disconnected? */
             RING_WARN("UPnP: Failed to get GetGenericPortMappingEntry from: %s, %d: %s",
-                      igd->getServiceType().c_str(), upnp_err, UpnpGetErrorMessage(upnp_err));
+                      igd.getServiceType().c_str(), upnp_err, UpnpGetErrorMessage(upnp_err));
             return;
         }
 
@@ -967,7 +1172,7 @@ UPnPContext::removeMappingsByLocalIPAndDescription(const IGD* igd, const std::st
             std::string client_ip = get_first_doc_item(response.get(), "NewInternalClient");
 
             /* check if same IP and description */
-            if (IpAddr(client_ip) == igd->localIp and desc_actual.compare(description) == 0) {
+            if (IpAddr(client_ip) == igd.localIp and desc_actual.compare(description) == 0) {
                 /* get the rest of the needed parameters */
                 std::string port_internal = get_first_doc_item(response.get(), "NewInternalPort");
                 std::string port_external = get_first_doc_item(response.get(), "NewExternalPort");
@@ -1000,28 +1205,28 @@ UPnPContext::removeMappingsByLocalIPAndDescription(const IGD* igd, const std::st
 }
 
 bool
-UPnPContext::deletePortMapping(const IGD* igd, const std::string& port_external, const std::string& protocol)
+UPnPContext::deletePortMapping(const UPnPIGD& igd, const std::string& port_external, const std::string& protocol)
 {
     std::string action_name{"DeletePortMapping"};
     std::unique_ptr<IXML_Document, decltype(ixmlDocument_free)&> action(nullptr, ixmlDocument_free);
     IXML_Document* action_ptr = nullptr;
-    UpnpAddToAction(&action_ptr, action_name.c_str(), igd->getServiceType().c_str(),
+    UpnpAddToAction(&action_ptr, action_name.c_str(), igd.getServiceType().c_str(),
                     "NewRemoteHost", "");
-    UpnpAddToAction(&action_ptr, action_name.c_str(), igd->getServiceType().c_str(),
+    UpnpAddToAction(&action_ptr, action_name.c_str(), igd.getServiceType().c_str(),
                     "NewExternalPort", port_external.c_str());
-    UpnpAddToAction(&action_ptr, action_name.c_str(), igd->getServiceType().c_str(),
+    UpnpAddToAction(&action_ptr, action_name.c_str(), igd.getServiceType().c_str(),
                     "NewProtocol", protocol.c_str());
     action.reset(action_ptr);
 
     std::unique_ptr<IXML_Document, decltype(ixmlDocument_free)&> response(nullptr, ixmlDocument_free);
     IXML_Document* response_ptr = nullptr;
-    int upnp_err = UpnpSendAction(ctrlptHandle_, igd->getControlURL().c_str(),
-                                  igd->getServiceType().c_str(), nullptr, action.get(), &response_ptr);
+    int upnp_err = UpnpSendAction(ctrlptHandle_, igd.getControlURL().c_str(),
+                                  igd.getServiceType().c_str(), nullptr, action.get(), &response_ptr);
     response.reset(response_ptr);
     if( upnp_err != UPNP_E_SUCCESS) {
         /* TODO: if failed, should we check if the igd is disconnected? */
         RING_WARN("UPnP: Failed to get %s from: %s, %d: %s", action_name.c_str(),
-                  igd->getServiceType().c_str(), upnp_err, UpnpGetErrorMessage(upnp_err));
+                  igd.getServiceType().c_str(), upnp_err, UpnpGetErrorMessage(upnp_err));
         return false;
     }
     /* check if there is an error code */
@@ -1036,41 +1241,41 @@ UPnPContext::deletePortMapping(const IGD* igd, const std::string& port_external,
 }
 
 bool
-UPnPContext::addPortMapping(const IGD* igd, const Mapping& mapping, int* error_code)
+UPnPContext::addPortMapping(const UPnPIGD& igd, const Mapping& mapping, int* error_code)
 {
     *error_code = UPNP_E_SUCCESS;
 
     std::string action_name{"AddPortMapping"};
     std::unique_ptr<IXML_Document, decltype(ixmlDocument_free)&> action(nullptr, ixmlDocument_free);
     IXML_Document* action_ptr = nullptr;
-    UpnpAddToAction(&action_ptr, action_name.c_str(), igd->getServiceType().c_str(),
+    UpnpAddToAction(&action_ptr, action_name.c_str(), igd.getServiceType().c_str(),
                     "NewRemoteHost", "");
-    UpnpAddToAction(&action_ptr, action_name.c_str(), igd->getServiceType().c_str(),
+    UpnpAddToAction(&action_ptr, action_name.c_str(), igd.getServiceType().c_str(),
                     "NewExternalPort", mapping.getPortExternalStr().c_str());
-    UpnpAddToAction(&action_ptr, action_name.c_str(), igd->getServiceType().c_str(),
+    UpnpAddToAction(&action_ptr, action_name.c_str(), igd.getServiceType().c_str(),
                     "NewProtocol", mapping.getTypeStr().c_str());
-    UpnpAddToAction(&action_ptr, action_name.c_str(), igd->getServiceType().c_str(),
+    UpnpAddToAction(&action_ptr, action_name.c_str(), igd.getServiceType().c_str(),
                     "NewInternalPort", mapping.getPortInternalStr().c_str());
-    UpnpAddToAction(&action_ptr, action_name.c_str(), igd->getServiceType().c_str(),
-                    "NewInternalClient", igd->localIp.toString().c_str());
-    UpnpAddToAction(&action_ptr, action_name.c_str(), igd->getServiceType().c_str(),
+    UpnpAddToAction(&action_ptr, action_name.c_str(), igd.getServiceType().c_str(),
+                    "NewInternalClient", igd.localIp.toString().c_str());
+    UpnpAddToAction(&action_ptr, action_name.c_str(), igd.getServiceType().c_str(),
                     "NewEnabled", "1");
-    UpnpAddToAction(&action_ptr, action_name.c_str(), igd->getServiceType().c_str(),
+    UpnpAddToAction(&action_ptr, action_name.c_str(), igd.getServiceType().c_str(),
                     "NewPortMappingDescription", mapping.getDescription().c_str());
     /* for now assume lease duration is always infinite */
-    UpnpAddToAction(&action_ptr, action_name.c_str(), igd->getServiceType().c_str(),
+    UpnpAddToAction(&action_ptr, action_name.c_str(), igd.getServiceType().c_str(),
                     "NewLeaseDuration", "0");
     action.reset(action_ptr);
 
     std::unique_ptr<IXML_Document, decltype(ixmlDocument_free)&> response(nullptr, ixmlDocument_free);
     IXML_Document* response_ptr = nullptr;
-    int upnp_err = UpnpSendAction(ctrlptHandle_, igd->getControlURL().c_str(),
-                                  igd->getServiceType().c_str(), nullptr, action.get(), &response_ptr);
+    int upnp_err = UpnpSendAction(ctrlptHandle_, igd.getControlURL().c_str(),
+                                  igd.getServiceType().c_str(), nullptr, action.get(), &response_ptr);
     response.reset(response_ptr);
     if( not response and upnp_err != UPNP_E_SUCCESS) {
         /* TODO: if failed, should we chck if the igd is disconnected? */
         RING_WARN("UPnP: Failed to %s from: %s, %d: %s", action_name.c_str(),
-                  igd->getServiceType().c_str(), upnp_err, UpnpGetErrorMessage(upnp_err));
+                  igd.getServiceType().c_str(), upnp_err, UpnpGetErrorMessage(upnp_err));
         *error_code = -1; /* make sure to -1 since we didn't get a response */
         return false;
     }
diff --git a/daemon/src/upnp/upnp_context.h b/daemon/src/upnp/upnp_context.h
index 72d06b7..3ad8285 100644
--- a/daemon/src/upnp/upnp_context.h
+++ b/daemon/src/upnp/upnp_context.h
@@ -18,8 +18,7 @@
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
  */
 
-#ifndef UPNP_CONTEXT_H_
-#define UPNP_CONTEXT_H_
+#pragma once
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -32,6 +31,7 @@
 #include <condition_variable>
 #include <chrono>
 #include <atomic>
+#include <thread>
 
 #if HAVE_LIBUPNP
 #ifdef _WIN32
@@ -43,6 +43,10 @@
 #include <upnp/upnptools.h>
 #endif
 
+#if HAVE_LIBNATPMP
+#include <natpmp.h>
+#endif
+
 #include "noncopyable.h"
 #include "upnp_igd.h"
 
@@ -56,7 +60,6 @@ class UPnPContext {
 public:
     constexpr static unsigned SEARCH_TIMEOUT {30};
 
-#if HAVE_LIBUPNP
     UPnPContext();
     ~UPnPContext();
 
@@ -104,20 +107,62 @@ public:
      */
     IpAddr getLocalIP() const;
 
+private:
+    NON_COPYABLE(UPnPContext);
+
+    std::atomic_bool clientRegistered_ {false};
+
     /**
-     * callback function for the UPnP client (control point)
-     * all UPnP events received by the client are processed here
+     * map of valid IGDs - IGDs which have the correct services and are connected
+     * to some external network (have an external IP)
+     *
+     * the UDN string is used to uniquely identify the IGD
+     *
+     * the mutex is used to access these lists and IGDs in a thread-safe manner
      */
-    int handleUPnPEvents(Upnp_EventType event_type, void* event);
+    std::map<std::string, std::unique_ptr<IGD>> validIGDs_;
+    mutable std::mutex validIGDMutex_;
+    std::condition_variable validIGDCondVar_;
 
-#else
-    /* use default constructor and destructor */
-    UPnPContext() = default;
-    ~UPnPContext() = default;
-#endif
+    /**
+     * Map of valid IGD listeners.
+     */
+    std::map<size_t, IGDFoundCallback> igdListeners_;
+
+    /**
+     * Last provided token for valid IGD listeners.
+     * 0 is the invalid token.
+     */
+    size_t listenerToken_ {0};
+
+    /**
+     * chooses the IGD to use (currently selects the first one in the map)
+     * assumes you already have a lock on igd_mutex_
+     */
+    IGD* chooseIGD_unlocked() const;
 
-private:
-    NON_COPYABLE(UPnPContext);
+
+    /* tries to add mapping, assumes you alreayd have lock on igd_mutex_ */
+    Mapping addMapping(IGD* igd,
+                       uint16_t port_external,
+                       uint16_t port_internal,
+                       PortType type,
+                       int *upnp_error);
+
+    uint16_t chooseRandomPort(const IGD& igd, PortType type);
+
+#if HAVE_LIBNATPMP
+
+    std::thread pmpThread_;
+    std::mutex pmpMutex_;
+    std::condition_variable pmpCv_;
+    std::atomic_bool pmpRun_ {true};
+
+    void PMPsearchForIGD(PMPIGD* pmp_igd, natpmp_t& natpmp, bool& found);
+    void PMPaddPortMapping(const PMPIGD& pmp_igd, natpmp_t& natpmp, GlobalMapping& mapping, bool remove=false) const;
+    void PMPdeleteAllPortMapping(const PMPIGD& pmp_igd, natpmp_t& natpmp, int proto) const;
+
+#endif
 
 #if HAVE_LIBUPNP
 
@@ -150,40 +195,18 @@ private:
     UpnpDevice_Handle deviceHandle_ {-1};
 
     /**
-     * keep track if we've successfully registered
-     * a client and/ore device
+     * keep track if we've successfully registered a device
      */
-    std::atomic_bool clientRegistered_ {false};
     bool deviceRegistered_ {false};
 
-    /**
-     * map of valid IGDs - IGDs which have the correct services and are connected
-     * to some external network (have an external IP)
-     *
-     * the UDN string is used to uniquely identify the IGD
-     *
-     * the mutex is used to access these lists and IGDs in a thread-safe manner
-     */
-    std::map<std::string, std::unique_ptr<IGD>> validIGDs_;
-    mutable std::mutex validIGDMutex_;
-    std::condition_variable validIGDCondVar_;
-
-    /**
-     * Map of valid IGD listeners.
-     */
-    std::map<size_t, IGDFoundCallback> igdListeners_;
+    static int cp_callback(Upnp_EventType event_type, void* event, void* user_data);
 
     /**
-     * Last provided token for valid IGD listeners.
-     * 0 is the invalid token.
+     * callback function for the UPnP client (control point)
+     * all UPnP events received by the client are processed here
      */
-    size_t listenerToken_ {0};
+    int handleUPnPEvents(Upnp_EventType event_type, void* event);
 
-    /**
-     * chooses the IGD to use (currently selects the first one in the map)
-     * assumes you already have a lock on igd_mutex_
-     */
-    IGD* chooseIGD_unlocked() const;
 
     /* sends out async search for IGD */
     void searchForIGD();
@@ -196,33 +219,24 @@ private:
 
     void parseIGD(IXML_Document* doc, const Upnp_Discovery* d_event);
 
-    /* tries to add mapping, assumes you alreayd have lock on igd_mutex_ */
-    Mapping addMapping(IGD* igd,
-                       uint16_t port_external,
-                       uint16_t port_internal,
-                       PortType type,
-                       int *upnp_error);
-
-    uint16_t chooseRandomPort(const IGD* igd, PortType type);
 
     /* these functions directly create UPnP actions
      * and make synchronous UPnP control point calls
      * they assume you have a lock on the igd_mutex_ */
-    bool isIGDConnected(const IGD* igd);
+    bool isIGDConnected(const UPnPIGD& igd);
 
-    IpAddr getExternalIP(const IGD* igd);
+    IpAddr getExternalIP(const UPnPIGD& igd);
 
-    void removeMappingsByLocalIPAndDescription(const IGD* igd,
+    void removeMappingsByLocalIPAndDescription(const UPnPIGD& igd,
                                                const std::string& description);
 
-    bool deletePortMapping(const IGD* igd,
+    bool deletePortMapping(const UPnPIGD& igd,
                            const std::string& port_external,
                            const std::string& protocol);
 
-    bool addPortMapping(const IGD* igd,
+    bool addPortMapping(const UPnPIGD& igd,
                         const Mapping& mapping,
                         int* error_code);
-
 #endif /* HAVE_LIBUPNP */
 
 };
@@ -236,5 +250,3 @@ private:
 std::shared_ptr<UPnPContext> getUPnPContext();
 
 }} // namespace ring::upnp
-
-#endif /* UPNP_CONTEXT_H_ */
diff --git a/daemon/src/upnp/upnp_control.cpp b/daemon/src/upnp/upnp_control.cpp
index 4e3be9d..d6b06f3 100644
--- a/daemon/src/upnp/upnp_control.cpp
+++ b/daemon/src/upnp/upnp_control.cpp
@@ -46,19 +46,14 @@ Controller::~Controller()
 {
     /* remove all mappings */
     removeMappings();
-#if HAVE_LIBUPNP
     if (listToken_ and upnpContext_)
         upnpContext_->removeIGDListener(listToken_);
-#endif
 }
 
 bool
 Controller::hasValidIGD(std::chrono::seconds timeout)
 {
-#if HAVE_LIBUPNP
     return upnpContext_ and upnpContext_->hasValidIGD(timeout);
-#endif
-    return false;
 }
 
 void
@@ -66,11 +61,9 @@ Controller::setIGDListener(IGDFoundCallback&& cb)
 {
     if (not upnpContext_)
         return;
-#if HAVE_LIBUPNP
     if (listToken_)
         upnpContext_->removeIGDListener(listToken_);
     listToken_ = cb ? upnpContext_->addIGDListener(std::move(cb)) : 0;
-#endif
 }
 
 bool
@@ -81,7 +74,6 @@ Controller::addAnyMapping(uint16_t port_desired,
                           bool unique,
                           uint16_t *port_used)
 {
-#if HAVE_LIBUPNP
     if (not upnpContext_)
         return false;
 
@@ -97,7 +89,6 @@ Controller::addAnyMapping(uint16_t port_desired,
         instanceMappings.emplace(usedPort, std::move(mapping));
         return true;
     }
-#endif
     return false;
 }
 
@@ -113,7 +104,6 @@ Controller::addAnyMapping(uint16_t port_desired,
 
 void
 Controller::removeMappings(PortType type) {
-#if HAVE_LIBUPNP
     if (not upnpContext_)
         return;
 
@@ -123,34 +113,28 @@ Controller::removeMappings(PortType type) {
         upnpContext_->removeMapping(mapping);
         iter = instanceMappings.erase(iter);
     }
-#endif
 }
+
 void
 Controller::removeMappings()
 {
-#if HAVE_LIBUPNP
     removeMappings(PortType::UDP);
     removeMappings(PortType::TCP);
-#endif
 }
 
 IpAddr
 Controller::getLocalIP() const
 {
-#if HAVE_LIBUPNP
     if (upnpContext_)
         return upnpContext_->getLocalIP();
-#endif
     return {}; //  empty address
 }
 
 IpAddr
 Controller::getExternalIP() const
 {
-#if HAVE_LIBUPNP
     if (upnpContext_)
         return upnpContext_->getExternalIP();
-#endif
     return {}; //  empty address
 }
 
diff --git a/daemon/src/upnp/upnp_igd.h b/daemon/src/upnp/upnp_igd.h
index 3fdce01..6a65de3 100644
--- a/daemon/src/upnp/upnp_igd.h
+++ b/daemon/src/upnp/upnp_igd.h
@@ -18,12 +18,16 @@
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
  */
 
-#ifndef UPNP_IGD_H_
-#define UPNP_IGD_H_
+#pragma once
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
 
 #include <string>
 #include <map>
 #include <functional>
+#include <chrono>
 
 #include "noncopyable.h"
 #include "ip_utils.h"
@@ -63,13 +67,13 @@ public:
     friend bool operator== (const Mapping& cRedir1, const Mapping& cRedir2);
     friend bool operator!= (const Mapping& cRedir1, const Mapping& cRedir2);
 
-    uint16_t      getPortExternal()    const { return port_external_; };
-    std::string   getPortExternalStr() const { return ring::to_string(port_external_); };
-    uint16_t      getPortInternal()    const { return port_internal_; };
-    std::string   getPortInternalStr() const { return ring::to_string(port_internal_); };
-    PortType      getType()            const { return type_; };
+    uint16_t      getPortExternal()    const { return port_external_; }
+    std::string   getPortExternalStr() const { return ring::to_string(port_external_); }
+    uint16_t      getPortInternal()    const { return port_internal_; }
+    std::string   getPortInternalStr() const { return ring::to_string(port_internal_); }
+    PortType      getType()            const { return type_; }
     std::string   getTypeStr()         const { return type_ == PortType::UDP ? "UDP" : "TCP"; }
-    std::string   getDescription()     const { return description_; };
+    std::string   getDescription()     const { return description_; }
 
     std::string toString() const {
         return getPortExternalStr() + ":" + getPortInternalStr() + ", " + getTypeStr();
@@ -83,6 +87,11 @@ public:
         return isValid();
     }
 
+#if HAVE_LIBNATPMP
+    std::chrono::system_clock::time_point renewal_ {std::chrono::system_clock::time_point::min()};
+    bool remove {false};
+#endif
+
 private:
     NON_COPYABLE(Mapping);
 
@@ -123,7 +132,6 @@ using IGDFoundCallback = std::function<void()>;
 /* defines a UPnP capable Internet Gateway Device (a router) */
 class IGD {
 public:
-
     /* device address seen by IGD */
     IpAddr localIp;
 
@@ -136,7 +144,22 @@ public:
 
     /* constructors */
     IGD() {}
-    IGD(std::string UDN,
+
+    /* move constructor and operator */
+    IGD(IGD&&) = default;
+    IGD& operator=(IGD&&) = default;
+
+    virtual ~IGD() = default;
+
+private:
+    NON_COPYABLE(IGD);
+};
+
+#if HAVE_LIBUPNP
+
+class UPnPIGD : public IGD {
+public:
+    UPnPIGD(std::string UDN,
         std::string baseURL,
         std::string friendlyName,
         std::string serviceType,
@@ -152,12 +175,6 @@ public:
         , eventSubURL_(eventSubURL)
         {}
 
-    /* move constructor and operator */
-    IGD(IGD&&) = default;
-    IGD& operator=(IGD&&) = default;
-
-    ~IGD() = default;
-
     const std::string& getUDN() const { return UDN_; };
     const std::string& getBaseURL() const { return baseURL_; };
     const std::string& getFriendlyName() const { return friendlyName_; };
@@ -167,8 +184,6 @@ public:
     const std::string& getEventSubURL() const { return eventSubURL_; };
 
 private:
-    NON_COPYABLE(IGD);
-
     /* root device info */
     std::string UDN_ {}; /* used to uniquely identify this UPnP device */
     std::string baseURL_ {};
@@ -179,9 +194,47 @@ private:
     std::string serviceId_ {};
     std::string controlURL_ {};
     std::string eventSubURL_ {};
+};
+
+#endif
+
+#if HAVE_LIBNATPMP
+
+using clock = std::chrono::system_clock;
+using time_point = clock::time_point;
+
+class PMPIGD : public IGD {
+public:
+
+    void clearAll() {
+        toRemove_.clear();
+        udpMappings.clear();
+        tcpMappings.clear();
+        clearAll_ = true;
+    }
+
+    GlobalMapping* getNextMappingToRenew() const {
+        const GlobalMapping* mapping {nullptr};
+        for (const auto& m : udpMappings)
+            if (!mapping or m.second.renewal_ < mapping->renewal_)
+                mapping = &m.second;
+        for (const auto& m : tcpMappings)
+            if (!mapping or m.second.renewal_ < mapping->renewal_)
+                mapping = &m.second;
+        return (GlobalMapping*)mapping;
+    }
 
+    time_point getRenewalTime() const {
+        const auto next = getNextMappingToRenew();
+        auto nextTime = std::min(renewal_, next ? next->renewal_ : time_point::max());
+        return toRemove_.empty() ? nextTime : std::min(nextTime, time_point::min());
+    }
+
+    time_point renewal_ {time_point::min()};
+    std::vector<GlobalMapping> toRemove_ {};
+    bool clearAll_ {false};
 };
 
-}} // namespace ring::upnp
+#endif
 
-#endif /* UPNP_IGD_H_ */
+}} // namespace ring::upnp
diff --git a/docs/source/dev/releasing.rst b/docs/source/dev/releasing.rst
index 17bc36f..defcc5d 100644
--- a/docs/source/dev/releasing.rst
+++ b/docs/source/dev/releasing.rst
@@ -8,7 +8,7 @@ Release tarball
 
 Ring is released in the form of a tarball. They are hosted here:
 
- - https://gpl.savoirfairelinux.net/ring-download/ring-release/tarballs/
+ - https://dl.ring.cx/ring-release/tarballs/
 
 Tarballs are generated from the integration branch of the `ring-project <https://github.com/savoirfairelinux/ring-project>`_ repository with a job on our `Jenkins server <https://test.savoirfairelinux.com/>`_. They include a copy of all contrib libraries configured in ``daemon/contrib/src``. If you are a Savoir-faire Linux employee, you may trigger the job from `this page <https://test.savoirfairelinux.com/job/ring-release/>`_.
 
diff --git a/lrc/src/macromodel.cpp b/lrc/src/macromodel.cpp
index e52fc7d..566aec4 100644
--- a/lrc/src/macromodel.cpp
+++ b/lrc/src/macromodel.cpp
@@ -198,10 +198,13 @@ QModelIndex MacroModel::parent( const QModelIndex& index) const
 
 QModelIndex MacroModel::index( int row, int column, const QModelIndex& parent) const
 {
-   if (!parent.isValid() && d_ptr->m_lCategories.size() > row) {
+   if (column != 0 || parent.parent().isValid())
+      return QModelIndex();
+
+   if ((!parent.isValid()) && d_ptr->m_lCategories.size() > row && row >= 0) {
       return createIndex(row,column,d_ptr->m_lCategories[row]->m_pPointer);
    }
-   else if (parent.isValid() && d_ptr->m_lCategories[parent.row()]->m_lContent.size() > row) {
+   else if (parent.isValid() && d_ptr->m_lCategories[parent.row()]->m_lContent.size() > row && row >= 0) {
       return createIndex(row,column,d_ptr->m_lCategories[parent.row()]->m_lContent[row]->d_ptr->m_pPointer);
    }
    return QModelIndex();
diff --git a/lrc/src/private/videorenderermanager.cpp b/lrc/src/private/videorenderermanager.cpp
index 75e67de..d1523d6 100644
--- a/lrc/src/private/videorenderermanager.cpp
+++ b/lrc/src/private/videorenderermanager.cpp
@@ -62,13 +62,13 @@ public:
    //Helper
    void removeRenderer(Video::Renderer* r);
 
-
 private:
    VideoRendererManager* q_ptr;
 
 public Q_SLOTS:
    void startedDecoding(const QString& id, const QString& shmPath, int width, int height);
    void stoppedDecoding(const QString& id, const QString& shmPath);
+   void callIsOver();
 
 };
 
@@ -227,9 +227,9 @@ void VideoRendererManagerPrivate::startedDecoding(const QString& id, const QStri
 
    }
    else {
-      r = m_hRenderers[rid];
+      r = m_hRenderers.value(rid);
 
-      QThread* t = m_hThreads[r];
+      QThread* t = m_hThreads.value(r);
 
       if (t && !t->isRunning())
          t->start();
@@ -280,72 +280,87 @@ void VideoRendererManagerPrivate::startedDecoding(const QString& id, const QStri
    }
 }
 
-/**
- * @warning This method can be called multiple time for the same renderer
- */
+/// Deletes the renderer and related resources
 void VideoRendererManagerPrivate::removeRenderer(Video::Renderer* r)
 {
-   if (!r || !m_hRenderers.contains(m_hRendererIds[r]))
-      return;
+    const auto id = m_hRendererIds.value(r);
+    auto t = m_hThreads.value(r);
 
-   const QByteArray id = m_hRendererIds[r];
+    m_hRendererIds.remove(r);
+    m_hRenderers.remove(id);
+    m_hThreads.remove(r);
 
-   //Quit if for some reasons the renderer is not found
-   if ( !r ) {
-      qWarning() << "Cannot stop rendering, renderer" << id << "not found";
-      return;
-   }
+    if (t) {
+        t->deleteLater();
+    }
 
-   Call* c = CallModel::instance().getCall(id);
+    r->deleteLater();
+}
 
-   if (c && c->lifeCycleState() == Call::LifeCycleState::FINISHED) {
-      c->d_ptr->removeRenderer(r);
-   }
+/**
+ * A video stopped being rendered
+ *
+ * @warning This method can be called multiple time for the same renderer
+ */
+void VideoRendererManagerPrivate::stoppedDecoding(const QString& id, const QString& shmPath)
+{
+    Q_UNUSED(shmPath)
 
-   r->stopRendering();
+    if (!m_hRenderers.contains(id.toLatin1()) || !m_hRenderers.contains(id.toLatin1())) {
+        qWarning() << "Cannot stop decoding, renderer" << id << "not found";
+        return; // nothing to do
+    }
 
-   qDebug() << "Video stopped for call" << id <<  "Renderer found:" << m_hRenderers.contains(id);
+    auto r = m_hRenderers.value(id.toLatin1());
 
-   Video::Device* dev = Video::DeviceModel::instance().getDevice(id);
+    Call* c = CallModel::instance().getCall(id);
 
-   if (dev)
-      emit dev->renderingStopped(r);
+    // TODO: the current implementeation of CallPrivate::removeRenderer() does nothing
+    if (c && c->lifeCycleState() == Call::LifeCycleState::FINISHED) {
+        c->d_ptr->removeRenderer(r);
+    }
 
-   if (id == PREVIEW_RENDERER_ID) {
-      m_PreviewState = false;
-      emit q_ptr->previewStateChanged(false);
-      emit q_ptr->previewStopped(r);
-   }
+    r->stopRendering();
 
-   QThread* t = m_hThreads[r];
+    qDebug() << "Video stopped for call" << id <<  "Renderer found:" << m_hRenderers.contains(id.toLatin1());
 
-   if (t) {
-       t->quit();
-       t->wait();
-   }
+    Video::Device* dev = Video::DeviceModel::instance().getDevice(id);
 
-   if (c && c->lifeCycleState() == Call::LifeCycleState::FINISHED) {
+    if (dev)
+        emit dev->renderingStopped(r);
 
-       m_hRendererIds.remove(r);
-       m_hRenderers.remove(id);
+    if (id == PREVIEW_RENDERER_ID) {
+        m_PreviewState = false;
+        emit q_ptr->previewStateChanged(false);
+        emit q_ptr->previewStopped(r);
+    }
 
-       m_hThreads[r] = nullptr;
-       if (t) {
-           t->deleteLater();
-       }
+    QThread* t = m_hThreads.value(r);
 
-       r->deleteLater();
-   }
+    if (t) {
+        t->quit();
+        t->wait();
+    }
+
+    // decoding stopped; remove the renderer, if/when call is over
+    if (c && c->lifeCycleState() == Call::LifeCycleState::FINISHED) {
+        removeRenderer(r);
+    } else if (c) {
+        connect(c, &Call::isOver, this, &VideoRendererManagerPrivate::callIsOver);
+    }
 }
 
-///A video stopped being rendered
-void VideoRendererManagerPrivate::stoppedDecoding(const QString& id, const QString& shmPath)
+void VideoRendererManagerPrivate::callIsOver()
 {
-   Q_UNUSED(shmPath)
-
-   if (m_hRenderers.contains(id.toLatin1())) {
-      removeRenderer(m_hRenderers[id.toLatin1()]);
-   }
+    if (auto call = qobject_cast<Call *>(sender())) {
+        if (auto r = m_hRenderers.value(call->dringId().toLatin1()))
+            removeRenderer(r);
+        else
+            qDebug() << "Could not delete renderer, it might have already been removed:" << call->dringId();
+
+        // remove the connection from this call to this
+        disconnect(call, &Call::isOver, this, 0);
+    }
 }
 
 void VideoRendererManager::switchDevice(const Video::Device* device) const
diff --git a/lrc/src/recentmodel.cpp b/lrc/src/recentmodel.cpp
index ff3d0ea..e3645bf 100644
--- a/lrc/src/recentmodel.cpp
+++ b/lrc/src/recentmodel.cpp
@@ -196,7 +196,7 @@ RecentModel::getParticipantNumber(Call *call) const
 
 void RecentModelPrivate::selectNode(RecentViewNode* node) const
 {
-   const auto idx = q_ptr->createIndex(node->m_Index, 0, node->m_pParent);
+   const auto idx = q_ptr->createIndex(node->m_Index, 0, node);
 
    q_ptr->selectionModel()->setCurrentIndex(idx, QItemSelectionModel::ClearAndSelect);
 }
@@ -748,7 +748,7 @@ void RecentModelPrivate::slotContactChanged(ContactMethod* cm, Person* np, Perso
         removeNode(n);
 
         if (newParentNode && newParentNode->m_lChildren.size()) {
-            q_ptr->selectionModel()->select(q_ptr->getIndex(const_cast<Person*>(newParentNode->m_uContent.m_pPerson)), QItemSelectionModel::ClearAndSelect);
+            selectNode(newParentNode);
         }
     }
 }
diff --git a/lrc/src/tlsmethodmodel.cpp b/lrc/src/tlsmethodmodel.cpp
index 609a7be..59c69d5 100644
--- a/lrc/src/tlsmethodmodel.cpp
+++ b/lrc/src/tlsmethodmodel.cpp
@@ -40,7 +40,6 @@ public:
       constexpr static const char* TLSv1   = "TLSv1"  ;
       constexpr static const char* TLSv1_1 = "TLSv1.1";
       constexpr static const char* TLSv1_2 = "TLSv1.2";
-      constexpr static const char* SSLv3   = "SSLv3"  ;
    };
 
 
@@ -50,7 +49,6 @@ public:
       constexpr static const char* TLSv1   = "TLSv1"  ;
       constexpr static const char* TLSv1_1 = "TLSv1.1";
       constexpr static const char* TLSv1_2 = "TLSv1.2";
-      constexpr static const char* SSLv3   = "SSLv3"  ;
    };
 
    static const char* toDaemonName(TlsMethodModel::Type type);
@@ -112,16 +110,18 @@ QVariant TlsMethodModel::data( const QModelIndex& index, int role) const
             return TlsMethodModelPrivate::Name::TLSv1_1;
          case TlsMethodModel::Type::TLSv1_2:
             return TlsMethodModelPrivate::Name::TLSv1_2;
-         case TlsMethodModel::Type::SSLv3:
-            return TlsMethodModelPrivate::Name::SSLv3;
+         case TlsMethodModel::Type::COUNT__:
+            break;
       };
    }
    return QVariant();
 }
 
 int TlsMethodModel::rowCount( const QModelIndex& parent ) const
+
 {
-   return parent.isValid()?0: d_ptr->isRing ? 1 : 4;
+    // In the RING case, only the "default" encryption type can be used
+    return parent.isValid() ? 0 : d_ptr->isRing ? 1 : static_cast<int>(TlsMethodModel::Type::COUNT__);
 }
 
 Qt::ItemFlags TlsMethodModel::flags( const QModelIndex& index ) const
@@ -181,8 +181,9 @@ const char* TlsMethodModelPrivate::toDaemonName(TlsMethodModel::Type type)
          return TlsMethodModelPrivate::DaemonName::TLSv1_1;
       case TlsMethodModel::Type::TLSv1_2:
          return TlsMethodModelPrivate::DaemonName::TLSv1_2;
-      case TlsMethodModel::Type::SSLv3:
-         return TlsMethodModelPrivate::DaemonName::SSLv3;
+      case TlsMethodModel::Type::COUNT__:
+         // default
+         break;
    };
    return TlsMethodModelPrivate::DaemonName::DEFAULT;
 }
@@ -198,8 +199,6 @@ TlsMethodModel::Type TlsMethodModelPrivate::fromDaemonName(const QString& name)
       return TlsMethodModel::Type::TLSv1_1;
    else if (name == TlsMethodModelPrivate::DaemonName::TLSv1_2)
       return TlsMethodModel::Type::TLSv1_2;
-   else if (name == TlsMethodModelPrivate::DaemonName::SSLv3)
-      return TlsMethodModel::Type::SSLv3;
    qDebug() << "Unknown TLS method" << name;
    return TlsMethodModel::Type::DEFAULT;
 }
diff --git a/lrc/src/tlsmethodmodel.h b/lrc/src/tlsmethodmodel.h
index 94e5116..be5747d 100644
--- a/lrc/src/tlsmethodmodel.h
+++ b/lrc/src/tlsmethodmodel.h
@@ -46,7 +46,7 @@ public:
       TLSv1_0   = 1,
       TLSv1_1   = 2,
       TLSv1_2   = 3,
-      SSLv3     = 4,
+      COUNT__
    };
 
    //Private constructor, can only be called by 'Account'
@@ -70,4 +70,3 @@ private:
 
 };
 Q_DECLARE_METATYPE(TlsMethodModel*)
-
diff --git a/make-ring.py b/make-ring.py
index 41ed474..f75a63a 100755
--- a/make-ring.py
+++ b/make-ring.py
@@ -53,11 +53,13 @@ FEDORA_DEPENDENCIES = [
     'autoconf', 'automake', 'cmake', 'speexdsp-devel', 'pulseaudio-libs-devel',
     'libsamplerate-devel', 'libtool', 'dbus-devel', 'expat-devel', 'pcre-devel',
     'yaml-cpp-devel', 'boost-devel', 'dbus-c++-devel', 'dbus-devel',
-    'libsndfile-devel', 'libsrtp-devel', 'libXext-devel', 'libXfixes-devel', 'yasm',
-    'speex-devel', 'chrpath', 'check', 'astyle', 'uuid-c++-devel', 'gettext-devel',
+    'libsndfile-devel', 'libXext-devel', 'libXfixes-devel', 'yasm',
+    'speex-devel', 'chrpath', 'check', 'astyle', 'uuid-c++-devel', 'gettext',
     'gcc-c++', 'which', 'alsa-lib-devel', 'systemd-devel', 'libuuid-devel',
     'uuid-devel', 'gnutls-devel', 'nettle-devel', 'opus-devel', 'speexdsp-devel',
-    'yaml-cpp-devel', 'qt5-qtbase-devel', 'swig', 'qrencode-devel'
+    'yaml-cpp-devel', 'qt5-qtbase-devel', 'swig', 'qrencode-devel', 'jsoncpp-devel',
+    'gtk3-devel', 'clutter-devel', 'clutter-gtk-devel', 'evolution-data-server-devel',
+    'libnotify-devel', 'libappindicator-gtk3-devel', 'patch'
 ]
 
 UBUNTU_DEPENDENCIES = [
@@ -68,24 +70,22 @@ UBUNTU_DEPENDENCIES = [
     'libdbus-c++-dev', 'libebook1.2-dev', 'libexpat1-dev', 'libgnutls-dev',
     'libgsm1-dev', 'libgtk-3-dev', 'libjack-dev', 'libnotify-dev',
     'libopus-dev', 'libpcre3-dev', 'libpulse-dev', 'libsamplerate0-dev',
-    'libsndfile1-dev', 'libspeex-dev', 'libspeexdsp-dev', 'libsrtp-dev',
-    'libswscale-dev', 'libtool', 'libudev-dev', 'libupnp-dev',
-    'libyaml-cpp-dev', 'qtbase5-dev', 'sip-tester', 'swig',
-    'uuid-dev', 'yasm', 'libqrencode-dev'
+    'libsndfile1-dev', 'libspeex-dev', 'libspeexdsp-dev', 'libswscale-dev', 'libtool',
+    'libudev-dev', 'libupnp-dev', 'libyaml-cpp-dev', 'qtbase5-dev', 'sip-tester', 'swig',
+    'uuid-dev', 'yasm', 'libqrencode-dev', 'libjsoncpp-dev', 'libappindicator3-dev'
 ]
 
-
 DEBIAN_DEPENDENCIES = [
     'autoconf', 'autopoint', 'cmake', 'dbus', 'doxygen', 'g++', 'gettext',
     'gnome-icon-theme-symbolic', 'libasound2-dev', 'libavcodec-dev',
     'libavcodec-extra', 'libavdevice-dev', 'libavformat-dev', 'libboost-dev',
     'libclutter-gtk-1.0-dev', 'libcppunit-dev', 'libdbus-1-dev',
-    'libdbus-c++-dev', 'libebook1.2-dev', 'libexpat1-dev', 'libgsm1-dev',
-    'libgtk-3-dev', 'libjack-dev', 'libnotify-dev', 'libopus-dev',
-    'libpcre3-dev', 'libpulse-dev', 'libsamplerate0-dev', 'libsndfile1-dev',
-    'libspeex-dev', 'libspeexdsp-dev', 'libswscale-dev', 'libtool',
-    'libudev-dev', 'libupnp-dev', 'libyaml-cpp-dev',
-    'qtbase5-dev', 'sip-tester', 'swig',  'uuid-dev', 'yasm', 'libqrencode-dev'
+    'libdbus-c++-dev', 'libebook1.2-dev', 'libexpat1-dev', 'libgnutls-dev',
+    'libgsm1-dev', 'libgtk-3-dev', 'libjack-dev', 'libnotify-dev',
+    'libopus-dev', 'libpcre3-dev', 'libpulse-dev', 'libsamplerate0-dev',
+    'libsndfile1-dev', 'libspeex-dev', 'libspeexdsp-dev', 'libswscale-dev', 'libtool',
+    'libudev-dev', 'libupnp-dev', 'libyaml-cpp-dev', 'qtbase5-dev', 'sip-tester', 'swig',
+    'uuid-dev', 'yasm', 'libqrencode-dev', 'libjsoncpp-dev', 'libappindicator3-dev'
 ]
 
 ARCH_LINUX_DEPENDENCIES = [

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-voip/ring.git



More information about the Pkg-voip-commits mailing list