diff --git a/appveyor.yml b/appveyor.yml
index dd6efecb5f9ebb74cd081aa15337ff6051a50220..652647b26781a56474efff9b67857858caeb501f 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -6,31 +6,48 @@ environment:
     CMD_IN_ENV: "cmd /E:ON /V:ON /C .\\ci\\appveyor\\run_with_env.cmd"
 
   matrix:
-    - PYTHON: "C:\\Python34_64"
+    - PYTHON: "C:\\Python35_64"
       PYTHON_VERSION: "3.5"
       PYTHON_ARCH: "64"
-      CONDA_PY: "34"
+      CONDA_PY: "35"
       CONDA_NPY: "18"
+      QTDIR: "C:\\Qt\\5.6\\5.6\\msvc2015_64"
+      QDOWNLOAD: "http://download.qt.io/development_releases/qt/5.6/5.6.0-beta/qt-opensource-windows-x86-msvc2015_64-5.6.0-beta.exe"
+      QINSTALLER: "qt-opensource-windows-x86-msvc2015_64-5.6.0-beta.exe"
       platform: x64
 
-    - PYTHON: "C:\\Python34_32"
+    - PYTHON: "C:\\Python35_32"
       PYTHON_VERSION: "3.5"
       PYTHON_ARCH: "32"
-      CONDA_PY: "34"
+      CONDA_PY: "35"
       CONDA_NPY: "18"
+      QTDIR: "C:\\Qt\\5.6\\5.6\\msvc2015"
+      QDOWNLOAD: "http://download.qt.io/development_releases/qt/5.6/5.6.0-beta/qt-opensource-windows-x86-msvc2015-5.6.0-beta.exe"
+      QINSTALLER: "qt-opensource-windows-x86-msvc2015-5.6.0-beta.exe"
       platform: x86
 
 install:
   # this installs the appropriate Miniconda (Py2/Py3, 32/64 bit),
   # as well as pip, conda-build, and the binstar CLI
   - powershell .\\ci\\appveyor\\install.ps1
+
+  - IF NOT EXIST C:\Qt\5.6\5.6 curl -kLO %QDOWNLOAD%
+  - IF NOT EXIST C:\Qt\5.6\5.6 %QINSTALLER% --script ci\appveyor\qt-installer-noninteractive.qs
+  # - dir /b /s /ad c:\Qt
+  - "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%"
+  - "IF EXIST %QTDIR%\\include\\QtNfc MOVE %QTDIR%\\include\\QtNfc %QTDIR%\\include\\QtNfc-disable"
+  # Add qt to path
+  - "set PATH=%QTDIR%\\bin;%PATH%"
+
   - "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%"
-  - "SET QT_QPA_PLATFORM_PLUGIN_PATH=%PYTHON%\\envs\\test-environment\\Scripts\\plugins"
-  - choco install -y vcredist2013
+  - "SET QT_PLUGIN_PATH=C:\\Qt\\5.6\\5.6\\msvc_2015\\plugins"
+  - choco install -y vcredist2015
   - "%CMD_IN_ENV% conda config --set always_yes yes --set changeps1 no"
   - "%CMD_IN_ENV% conda config --add channels inso/channel/sakia"
-  - "%CMD_IN_ENV% conda config --add channels pyzo"
-  - "%CMD_IN_ENV% conda create -q -n test-environment python=%PYTHON_VERSION% cx_freeze pyqt5 libsodium=1.0.3"
+  - "%CMD_IN_ENV% conda create -q -n test-environment python=%PYTHON_VERSION% pyqt5 libsodium=1.0.3"
+
+cache:
+  - C:\Qt\5.6\5.6
 
 build_script:
   - ".\\ci\\appveyor\\build.cmd"
diff --git a/ci/appveyor/build.cmd b/ci/appveyor/build.cmd
index bd4410c0b09eb36a4b4391aff179bddf92770125..a1b9b313e4a0f0b3dc536e1148fd2f863329fbf0 100644
--- a/ci/appveyor/build.cmd
+++ b/ci/appveyor/build.cmd
@@ -3,7 +3,7 @@
 call activate test-environment
 
 echo "%PATH%"
-echo "%QT_QPA_PLATFORM_PLUGIN_PATH%"
+echo "%QT_PLUGIN_PATH%"
 python -V
 call pyuic5 --version
 
@@ -19,5 +19,5 @@ if %errorlevel% neq 0 exit /b 1s
 python gen_translations.py
 if %errorlevel% neq 0 exit /b 1
 
-python setup.py build
-if %errorlevel% neq 0 exit /b 1
+@REM python setup.py build
+@REM if %errorlevel% neq 0 exit /b 1
diff --git a/ci/appveyor/qt-installer-noninteractive.qs b/ci/appveyor/qt-installer-noninteractive.qs
new file mode 100644
index 0000000000000000000000000000000000000000..9df892cdb83b2576853b6e9be5697dc049f3c04e
--- /dev/null
+++ b/ci/appveyor/qt-installer-noninteractive.qs
@@ -0,0 +1,56 @@
+// Emacs mode hint: -*- mode: JavaScript -*-
+
+function Controller() {
+    installer.autoRejectMessageBoxes();
+    installer.installationFinished.connect(function() {
+        gui.clickButton(buttons.NextButton);
+    })
+}
+
+Controller.prototype.WelcomePageCallback = function() {
+    gui.clickButton(buttons.NextButton);
+}
+
+Controller.prototype.CredentialsPageCallback = function() {
+    gui.clickButton(buttons.NextButton);
+}
+
+Controller.prototype.IntroductionPageCallback = function() {
+    gui.clickButton(buttons.NextButton);
+}
+
+Controller.prototype.TargetDirectoryPageCallback = function()
+{
+    gui.currentPageWidget().TargetDirectoryLineEdit.setText("C:\\Qt\\5.6");
+    gui.clickButton(buttons.NextButton);
+}
+
+Controller.prototype.ComponentSelectionPageCallback = function() {
+    //var widget = gui.currentPageWidget();
+
+    //widget.selectAll();
+
+    gui.clickButton(buttons.NextButton);
+}
+
+Controller.prototype.LicenseAgreementPageCallback = function() {
+    gui.currentPageWidget().AcceptLicenseRadioButton.setChecked(true);
+    gui.clickButton(buttons.NextButton);
+}
+
+Controller.prototype.StartMenuDirectoryPageCallback = function() {
+    gui.clickButton(buttons.NextButton);
+}
+
+Controller.prototype.ReadyForInstallationPageCallback = function()
+{
+    gui.clickButton(buttons.NextButton);
+}
+
+Controller.prototype.FinishedPageCallback = function() {
+var checkBoxForm = gui.currentPageWidget().LaunchQtCreatorCheckBoxForm
+if (checkBoxForm && checkBoxForm.launchQtCreatorCheckBox) {
+    checkBoxForm.launchQtCreatorCheckBox.checked = false;
+}
+    gui.clickButton(buttons.FinishButton);
+}
diff --git a/ci/appveyor/tests.cmd b/ci/appveyor/tests.cmd
index a2029cc5d5442022e4959cc771f92e0845de1efc..094bc394e38247295483cfccd0019374eccfd14e 100644
--- a/ci/appveyor/tests.cmd
+++ b/ci/appveyor/tests.cmd
@@ -3,7 +3,7 @@
 call activate test-environment
 
 echo "%PATH%"
-echo "%QT_QPA_PLATFORM_PLUGIN_PATH%"
+echo "%QT_PLUGIN_PATH%"
 python -V
 call pyuic5 --version
 
@@ -11,6 +11,8 @@ pyrcc5 -version
 
 lrelease -version
 
+echo "%CWD%"
+
 python setup.py test
 
 if %errorlevel% neq 0 exit /b 1
\ No newline at end of file
diff --git a/ci/travis/before_install.sh b/ci/travis/before_install.sh
index 679c5c359219d24967e843e06b2d05d009335b17..ba2085b4ef33aa5fb5759befc1bacf0ee8667cf3 100755
--- a/ci/travis/before_install.sh
+++ b/ci/travis/before_install.sh
@@ -57,10 +57,20 @@ then
     pyenv activate sakia-env
     if [ $TRAVIS_OS_NAME == "osx" ]
     then
-        python configure.py --confirm-license
+        python configure.py --confirm-license \
+            --enable QtCore \
+            --enable QtWidgets \
+            --enable QtGui \
+            --enable QtSvg\
+            --enable QtTest
     elif [ $TRAVIS_OS_NAME == "linux" ]
     then
-        python configure.py --qmake "/usr/lib/x86_64-linux-gnu/qt5/bin/qmake" --confirm-license
+        python configure.py --qmake "/usr/lib/x86_64-linux-gnu/qt5/bin/qmake" --confirm-license  \
+            --enable QtCore \
+            --enable QtWidgets \
+            --enable QtGui \
+            --enable QtSvg\
+            --enable QtTest
     fi
 
     make -j 2 && make install
diff --git a/requirements.txt b/requirements.txt
index 58d74c97e088fd0fd603005a7c8048bdb9303abd..c4379dc46caef502b33db85fe8b273c1058bd20a 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,4 +1,4 @@
 ucoinpy>=0.13
-quamash
+git+https://github.com/harvimt/quamash.git@gh45
 asynctest
-networkx
\ No newline at end of file
+git+https://github.com/networkx/networkx.git@v1.11
\ No newline at end of file
diff --git a/res/icons/AUTHORS b/res/icons/AUTHORS
index 23af4ae9d95d73a77e3cc96aee08e56473c1843c..ea1311c735ce47045d80a49dabef8c7a7bdebf42 100644
--- a/res/icons/AUTHORS
+++ b/res/icons/AUTHORS
@@ -25,4 +25,20 @@ noun_155533_cc.svg : by anbileru adaleru
 noun_155520_cc.svg : by anbileru adaleru
 noun_155540_cc.svg : by anbileru adaleru
 noun_100552_cc.svg : by Rui
-noun_178537_cc.svg : by Nathan David Smith
\ No newline at end of file
+noun_178537_cc.svg : by Nathan David Smith
+noun_213188_cc.svg : by Aha-Soft
+noun_213886_cc.svg : by Aha-Soft
+noun_213196_cc.svg : by Aha-Soft
+noun_60040_cc.svg : by Dmitry Baranovskiy
+noun_87601_cc.svg : by Arthur Shlain
+noun_274635_cc.svg : by Pham Thi Dieu Linh
+noun_198591_cc.svg : by Андрей Уханёв
+noun_269788_cc.svg : by TMD
+noun_269789_cc.svg : by TMD
+noun_269790_cc.svg : by TMD
+noun_269791_cc.svg : by TMD
+noun_269792_cc.svg : by TMD
+noun_269793_cc.svg : by TMD
+noun_188924_cc.svg : by anbileru adaleru
+noun_188905_cc.svg : by anbileru adaleru
+noun_188906_cc.svg : by anbileru adaleru
\ No newline at end of file
diff --git a/res/icons/connected.svg b/res/icons/connected.svg
deleted file mode 100644
index c6a97c9c66be3ebf88117731bd8e14d55542ef8b..0000000000000000000000000000000000000000
--- a/res/icons/connected.svg
+++ /dev/null
@@ -1,98 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:xlink="http://www.w3.org/1999/xlink"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="100"
-   height="100"
-   viewBox="0 0 100 100"
-   id="svg3336"
-   version="1.1"
-   inkscape:version="0.91 r13725"
-   sodipodi:docname="connected.svg">
-  <defs
-     id="defs3338">
-    <linearGradient
-       inkscape:collect="always"
-       id="linearGradient4150">
-      <stop
-         style="stop-color:#ffffff;stop-opacity:1;"
-         offset="0"
-         id="stop4152" />
-      <stop
-         style="stop-color:#ffffff;stop-opacity:0.04620462"
-         offset="1"
-         id="stop4154" />
-    </linearGradient>
-    <radialGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4150"
-       id="radialGradient4162"
-       cx="52.325901"
-       cy="1005.1627"
-       fx="52.325901"
-       fy="1005.1627"
-       r="42.926411"
-       gradientTransform="matrix(1.539681,0,0,1.5451884,-68.190831,-562.49866)"
-       gradientUnits="userSpaceOnUse" />
-  </defs>
-  <sodipodi:namedview
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="2.8284271"
-     inkscape:cx="18.741815"
-     inkscape:cy="33.829638"
-     inkscape:document-units="px"
-     inkscape:current-layer="layer1"
-     showgrid="false"
-     units="px"
-     inkscape:snap-bbox="false"
-     inkscape:window-width="1366"
-     inkscape:window-height="709"
-     inkscape:window-x="-4"
-     inkscape:window-y="0"
-     inkscape:window-maximized="1" />
-  <metadata
-     id="metadata3341">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-        <dc:title />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <g
-     inkscape:label="Calque 1"
-     inkscape:groupmode="layer"
-     id="layer1"
-     transform="translate(0,-952.36216)">
-    <ellipse
-       style="opacity:1;fill:#17d017;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-       id="path3346"
-       cx="51.785713"
-       cy="1005.5765"
-       rx="41.785713"
-       ry="40.714287" />
-    <ellipse
-       style="opacity:0.65;fill:url(#radialGradient4162);fill-opacity:1;stroke:none;stroke-width:1.25129819;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-       id="path4148"
-       cx="12.374369"
-       cy="990.66699"
-       rx="64.928177"
-       ry="65.10495" />
-  </g>
-</svg>
diff --git a/res/icons/disconnected.svg b/res/icons/disconnected.svg
deleted file mode 100644
index 6647ff69d1f4db23fc7130d611543229eb42b3af..0000000000000000000000000000000000000000
--- a/res/icons/disconnected.svg
+++ /dev/null
@@ -1,98 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:xlink="http://www.w3.org/1999/xlink"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="100"
-   height="100"
-   viewBox="0 0 100 100"
-   id="svg3336"
-   version="1.1"
-   inkscape:version="0.91 r13725"
-   sodipodi:docname="disconnected.svg">
-  <defs
-     id="defs3338">
-    <linearGradient
-       inkscape:collect="always"
-       id="linearGradient4150">
-      <stop
-         style="stop-color:#ffffff;stop-opacity:1;"
-         offset="0"
-         id="stop4152" />
-      <stop
-         style="stop-color:#ffffff;stop-opacity:0.04620462"
-         offset="1"
-         id="stop4154" />
-    </linearGradient>
-    <radialGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4150"
-       id="radialGradient4162"
-       cx="52.325901"
-       cy="1005.1627"
-       fx="52.325901"
-       fy="1005.1627"
-       r="42.926411"
-       gradientTransform="matrix(1.539681,0,0,1.5451884,-50.51316,-559.67022)"
-       gradientUnits="userSpaceOnUse" />
-  </defs>
-  <sodipodi:namedview
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="2.8284271"
-     inkscape:cx="18.741815"
-     inkscape:cy="33.829638"
-     inkscape:document-units="px"
-     inkscape:current-layer="layer1"
-     showgrid="false"
-     units="px"
-     inkscape:snap-bbox="false"
-     inkscape:window-width="1366"
-     inkscape:window-height="709"
-     inkscape:window-x="-4"
-     inkscape:window-y="0"
-     inkscape:window-maximized="1" />
-  <metadata
-     id="metadata3341">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-        <dc:title />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <g
-     inkscape:label="Calque 1"
-     inkscape:groupmode="layer"
-     id="layer1"
-     transform="translate(0,-952.36216)">
-    <ellipse
-       style="opacity:1;fill:#c60002;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-       id="path3346"
-       cx="51.785713"
-       cy="1005.5765"
-       rx="41.785713"
-       ry="40.714287" />
-    <ellipse
-       style="opacity:0.65;fill:url(#radialGradient4162);fill-opacity:1;stroke:none;stroke-width:1.25129819;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-       id="path4148"
-       cx="30.05204"
-       cy="993.49536"
-       rx="64.928177"
-       ry="65.10495" />
-  </g>
-</svg>
diff --git a/res/icons/icons.qrc b/res/icons/icons.qrc
index 1e3016df94ab4c91c9f41ed191f800230a3383a6..b889b5abe8699731a8a6ac86e25ca3bacc0c685f 100644
--- a/res/icons/icons.qrc
+++ b/res/icons/icons.qrc
@@ -29,8 +29,18 @@
     <file alias="settings_app_icon">noun_42425_cc.svg</file>
     <file alias="settings_network_icon">noun_62146_cc.svg</file>
     <file alias="explorer_icon">noun_101791_cc.svg</file>
-    <file alias="connected">connected.svg</file>
-    <file alias="weak_connect">weak_connect.svg</file>
-    <file alias="disconnected">disconnected.svg</file>
+    <file alias="connected">noun_269788_cc.svg</file>
+    <file alias="weak_connect">noun_269792_cc.svg</file>
+    <file alias="disconnected">noun_269793_cc.svg</file>
+    <file alias="member">noun_213188_cc.svg</file>
+    <file alias="not_member">noun_213192_cc.svg</file>
+    <file alias="member_warning">noun_213886_cc.svg</file>
+    <file alias="forked">noun_60040_cc.svg</file>
+    <file alias="offline">noun_87601_cc.svg</file>
+    <file alias="synchronized">noun_274635_cc.svg</file>
+    <file alias="corrupted">noun_198591_cc.svg</file>
+    <file alias="dividend">noun_188924_cc.svg</file>
+    <file alias="received">noun_188906_cc.svg</file>
+    <file alias="sent">noun_188905_cc.svg</file>
   </qresource>
 </RCC>
diff --git a/res/icons/noun_188905_cc.svg b/res/icons/noun_188905_cc.svg
new file mode 100644
index 0000000000000000000000000000000000000000..6d017d53c8bd32c7c145eba03069ebd771521845
--- /dev/null
+++ b/res/icons/noun_188905_cc.svg
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   viewBox="0 0 125 100"
+   version="1.1"
+   x="0px"
+   y="0px"
+   id="svg2"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="noun_188905_cc.svg"
+   width="125"
+   height="100">
+  <metadata
+     id="metadata38">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs36" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1366"
+     inkscape:window-height="712"
+     id="namedview34"
+     showgrid="false"
+     inkscape:zoom="2.6700352"
+     inkscape:cx="-21.344737"
+     inkscape:cy="57.606196"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="g4" />
+  <g
+     transform="matrix(1.1387208,0,0,1.1387208,-7.4656982,-1106.1042)"
+     id="g4"
+     style="fill:#aa8800">
+    <rect
+       style="opacity:1;fill:#decd87;fill-opacity:0.61290325;fill-rule:evenodd;stroke:none;stroke-width:9;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect4145"
+       width="86.172173"
+       height="42.09938"
+       x="8.2007217"
+       y="996.02557" />
+    <path
+       style="opacity:1;fill:#e9ddaf;fill-opacity:0.99539173;fill-rule:evenodd;stroke:none;stroke-width:9;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="path4147"
+       sodipodi:type="arc"
+       sodipodi:cx="93.715096"
+       sodipodi:cy="999.8078"
+       sodipodi:rx="21.04969"
+       sodipodi:ry="20.227436"
+       sodipodi:start="0"
+       sodipodi:end="6.2784729"
+       d="m 114.76479,999.8078 a 21.04969,20.227436 0 0 1 -21.024896,20.2274 21.04969,20.227436 0 0 1 -21.07443,-20.17974 21.04969,20.227436 0 0 1 20.975236,-20.27497 21.04969,20.227436 0 0 1 21.12385,20.13199 l -21.049454,0.0953 z" />
+    <path
+       d="m 8,995.49506 c 0,14.88924 0,29.77844 0,44.66764 l 86.973908,0 0,-20.2133 c -0.320011,0.015 -0.634655,0.047 -0.9585,0.047 -0.323462,0 -0.638489,-0.032 -0.9585,-0.047 l 0,18.2963 -83.139908,0 0,-40.83364 63.827666,0 c 0.06646,-0.64846 0.170102,-1.28708 0.297007,-1.917 z"
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#d4aa00;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:7.90360552;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       id="path6"
+       inkscape:connector-curvature="0" />
+    <path
+       d="m 18.910414,995.77609 -10.6307876,10.68831 1.3577472,1.3504 10.6334714,-10.68582 -1.360431,-1.35289 z"
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#d4aa00;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:7.90360552;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       id="path8"
+       inkscape:connector-curvature="0" />
+    <path
+       d="m 24.22715,995.77609 -15.9475236,16.03241 1.3577472,1.3504 15.9500794,-16.02992 -1.360303,-1.35289 z"
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#d4aa00;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:7.90360552;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       id="path10"
+       inkscape:connector-curvature="0" />
+    <path
+       d="m 72.751149,1032.9005 0,1.917 15.947523,0 0,-1.917 -15.947523,0 z"
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#d4aa00;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:7.90360552;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       id="path12"
+       inkscape:connector-curvature="0" />
+    <path
+       d="m 19.589415,1006.1834 0,1.917 55.944962,0 c -0.28755,-0.6229 -0.543789,-1.2616 -0.768845,-1.917 l -55.176117,0 z"
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#d4aa00;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:7.90360552;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       id="path14"
+       inkscape:connector-curvature="0" />
+    <path
+       d="m 19.589415,1011.5239 0,1.917 42.728142,0 0,-1.917 -42.728142,0 z"
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#d4aa00;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:7.90360552;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       id="path16"
+       inkscape:connector-curvature="0" />
+    <path
+       d="m 19.589415,1016.8681 0,1.917 26.683235,0 0,-1.917 -26.683235,0 z"
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#d4aa00;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:7.90360552;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       id="path18"
+       inkscape:connector-curvature="0" />
+    <path
+       d="m 94.015408,978.06876 c -11.703541,0 -21.336594,9.68673 -21.336594,21.44395 0,11.88299 9.640593,21.44399 21.336594,21.44399 11.821752,0 21.336592,-9.5684 21.336592,-21.44399 0,-11.74981 -9.50742,-21.44395 -21.336592,-21.44395 z m 0,1.917 c 10.783512,0 19.419592,8.80925 19.419592,19.52695 0,10.85549 -8.62867,19.52699 -19.419592,19.52699 -10.653153,0 -19.419594,-8.6789 -19.419594,-19.52699 0,-10.71028 8.773981,-19.52695 19.419594,-19.52695 z"
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#d4aa00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:7.90360552;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       id="path20"
+       inkscape:connector-curvature="0" />
+    <path
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#d4aa00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:7.90360552;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       d="m 95.14113,988.45949 -1.350387,1.35787 11.010267,10.96284 1.35289,-1.36037 -11.01277,-10.96034 z"
+       id="path22"
+       inkscape:connector-curvature="0" />
+    <path
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#d4aa00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:7.90360552;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       d="m 104.80101,998.24667 -11.010267,10.96033 1.350387,1.3603 11.01277,-10.96276 -1.35289,-1.35787 z"
+       id="path24"
+       inkscape:connector-curvature="0" />
+    <path
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#d4aa00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:7.90360552;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       d="m 81.874392,998.55369 0,1.91701 23.358448,0 0,-1.91701 -23.358448,0 z"
+       id="path26"
+       inkscape:connector-curvature="0" />
+    <path
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#d4aa00;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:7.90360552;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       d="m 19.586867,1022.2202 c 0,2.4204 0,4.8408 0,7.2612 l 33.814583,0 0,-7.2612 z m 1.917,1.917 8.71636,0 0,3.4272 -8.71636,0 z m 10.63336,0 19.347223,0 0,3.4272 -19.347223,0 z"
+       id="path28"
+       inkscape:connector-curvature="0" />
+  </g>
+</svg>
diff --git a/res/icons/noun_188906_cc.svg b/res/icons/noun_188906_cc.svg
new file mode 100644
index 0000000000000000000000000000000000000000..74ceb8e2721bf7f240a06806fc677346f2e3294d
--- /dev/null
+++ b/res/icons/noun_188906_cc.svg
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   viewBox="0 0 125 100"
+   version="1.1"
+   x="0px"
+   y="0px"
+   id="svg2"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="noun_188906_cc.svg"
+   width="125"
+   height="100">
+  <metadata
+     id="metadata38">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs36" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1366"
+     inkscape:window-height="712"
+     id="namedview34"
+     showgrid="false"
+     inkscape:zoom="3.776"
+     inkscape:cx="47.720009"
+     inkscape:cy="73.89717"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="g4" />
+  <g
+     transform="matrix(1.4786603,0,0,1.4786603,-9.8292821,-1439.5248)"
+     id="g4"
+     style="fill:#338000">
+    <path
+       style="opacity:1;fill:#aade87;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:27.23500061;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="path4147"
+       sodipodi:type="arc"
+       sodipodi:cx="75.691109"
+       sodipodi:cy="995.31189"
+       sodipodi:rx="16.387802"
+       sodipodi:ry="17.01466"
+       sodipodi:start="0"
+       sodipodi:end="6.2783233"
+       d="M 92.078911,995.31189 A 16.387802,17.01466 0 0 1 75.711028,1012.3265 16.387802,17.01466 0 0 1 59.303355,995.35325 16.387802,17.01466 0 0 1 75.631351,978.29734 16.387802,17.01466 0 0 1 92.078717,995.22916"
+       sodipodi:open="true" />
+    <rect
+       style="opacity:1;fill:#aade87;fill-opacity:0.61290325;fill-rule:evenodd;stroke:none;stroke-width:27.23500061;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect4145"
+       width="67.879524"
+       height="34.208435"
+       x="7.9011359"
+       y="992.26715" />
+    <path
+       d="m 8,991.70436 c 0,11.65044 0,23.30084 0,34.95124 l 68.0547,0 0,-15.8164 c -0.2504,0.012 -0.4966,0.037 -0.75,0.037 -0.2531,0 -0.4996,-0.025 -0.75,-0.037 l 0,14.3164 -65.0547,0 0,-31.95124 49.9434,0 c 0.052,-0.5074 0.1331,-1.0071 0.2324,-1.5 z"
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#338000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       id="path6"
+       inkscape:connector-curvature="0" />
+    <path
+       d="m 16.5371,991.92426 -8.3183,8.36334 1.0624,1.0566 8.3204,-8.36134 -1.0645,-1.0586 z"
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#338000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       id="path8"
+       inkscape:connector-curvature="0" />
+    <path
+       d="m 20.6973,991.92426 -12.4785,12.54494 1.0624,1.0566 12.4805,-12.54294 -1.0644,-1.0586 z"
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#338000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       id="path10"
+       inkscape:connector-curvature="0" />
+    <path
+       d="m 58.666,1020.9731 0,1.5 12.4785,0 0,-1.5 -12.4785,0 z"
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#338000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       id="path12"
+       inkscape:connector-curvature="0" />
+    <path
+       d="m 17.0684,1000.0677 0,1.5 43.7754,0 c -0.225,-0.4874 -0.4255,-0.9872 -0.6016,-1.5 l -43.1738,0 z"
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#338000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       id="path14"
+       inkscape:connector-curvature="0" />
+    <path
+       d="m 17.0684,1004.2465 0,1.5 33.4336,0 0,-1.5 -33.4336,0 z"
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#338000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       id="path16"
+       inkscape:connector-curvature="0" />
+    <path
+       d="m 17.0684,1008.4282 0,1.5 20.8789,0 0,-1.5 -20.8789,0 z"
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#338000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       id="path18"
+       inkscape:connector-curvature="0" />
+    <path
+       d="m 75.3047,978.06876 c -9.1577,0 -16.6953,7.5796 -16.6953,16.7793 0,9.29814 7.5435,16.77934 16.6953,16.77934 9.2502,0 16.6953,-7.487 16.6953,-16.77934 0,-9.1939 -7.4393,-16.7793 -16.6953,-16.7793 z m 0,1.5 c 8.4378,0 15.1953,6.893 15.1953,15.2793 0,8.49414 -6.7517,15.27934 -15.1953,15.27934 -8.3358,0 -15.1953,-6.791 -15.1953,-15.27934 0,-8.3805 6.8654,-15.2793 15.1953,-15.2793 z"
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#338000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       id="path20"
+       inkscape:connector-curvature="0" />
+    <path
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#338000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       d="m 74.421873,986.19922 1.056641,1.0625 -8.615235,8.57812 -1.058593,-1.06445 8.617187,-8.57617 z"
+       id="path22"
+       inkscape:connector-curvature="0" />
+    <path
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#338000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       d="m 66.863279,993.85742 8.615235,8.57618 -1.056641,1.0644 -8.617187,-8.57808 1.058593,-1.0625 z"
+       id="path24"
+       inkscape:connector-curvature="0" />
+    <path
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#338000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       d="m 84.802732,994.09766 0,1.5 -18.277343,0 0,-1.5 18.277343,0 z"
+       id="path26"
+       inkscape:connector-curvature="0" />
+    <path
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#338000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.49999988;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       d="m 17.066406,60.253906 c 0,1.89388 0,3.787761 0,5.681641 l 26.458985,0 0,-5.681641 z m 1.5,1.5 6.820313,0 0,2.681641 -6.820313,0 z m 8.320313,0 15.138672,0 0,2.681641 -15.138672,0 z"
+       transform="translate(0,952.36216)"
+       id="path28"
+       inkscape:connector-curvature="0" />
+  </g>
+</svg>
diff --git a/res/icons/noun_188924_cc.svg b/res/icons/noun_188924_cc.svg
new file mode 100644
index 0000000000000000000000000000000000000000..efd676ef385e3c5b992f298d0234f8d06288a1d9
--- /dev/null
+++ b/res/icons/noun_188924_cc.svg
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   viewBox="0 0 125 100"
+   version="1.1"
+   x="0px"
+   y="0px"
+   id="svg2"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="noun_188924_cc.svg"
+   width="125"
+   height="100">
+  <metadata
+     id="metadata44">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs42" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1366"
+     inkscape:window-height="712"
+     id="namedview40"
+     showgrid="false"
+     inkscape:zoom="2.6700352"
+     inkscape:cx="2.5475798"
+     inkscape:cy="65.94635"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg2" />
+  <path
+     style="opacity:1;fill:#afe9dd;fill-opacity:0.99539173;fill-rule:evenodd;stroke:none;stroke-width:9;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+     id="path4150"
+     sodipodi:type="arc"
+     sodipodi:cx="99.99868"
+     sodipodi:cy="32.959686"
+     sodipodi:rx="22.84614"
+     sodipodi:ry="23.220667"
+     sodipodi:start="0"
+     sodipodi:end="6.2784729"
+     d="M 122.84482,32.959686 A 22.84614,23.220667 0 0 1 100.0256,56.180337 22.84614,23.220667 0 0 1 77.152604,33.014399 22.84614,23.220667 0 0 1 99.917935,9.7391644 22.84614,23.220667 0 0 1 122.84457,32.850261 l -22.84589,0.109425 z" />
+  <rect
+     style="opacity:1;fill:#afe9dd;fill-opacity:0.99539173;fill-rule:evenodd;stroke:none;stroke-width:9;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+     id="rect4148"
+     width="97.751518"
+     height="50.561131"
+     x="2.6216884"
+     y="29.588943" />
+  <g
+     transform="matrix(1.4672496,0,0,1.4672496,-10.504946,-1426.072)"
+     id="g4"
+     style="fill:#005544">
+    <path
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#005544;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       d="m 24.7188,1013.3598 0,4.1816 1.5,0 0,-4.1816 -1.5,0 z"
+       id="path6"
+       inkscape:connector-curvature="0" />
+    <path
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#005544;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.49999988;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       d="m 17.068359,1012.6152 c 0,1.8939 0,3.7878 0,5.6817 l 26.458985,0 0,-5.6817 z m 1.5,1.5 23.458985,0 0,2.6817 -23.458985,0 z"
+       id="path8"
+       inkscape:connector-curvature="0" />
+    <path
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#005544;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       d="m 8,991.7044 c 0,11.6504 0,23.3008 0,34.9512 l 68.0547,0 0,-15.8164 c -0.2504,0.012 -0.4966,0.037 -0.75,0.037 -0.2531,0 -0.4996,-0.025 -0.75,-0.037 l 0,14.3164 -65.0547,0 0,-31.9512 49.9434,0 c 0.052,-0.50739 0.1331,-1.00719 0.2324,-1.5 z"
+       id="path10"
+       inkscape:connector-curvature="0" />
+    <path
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#005544;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       d="m 16.5371,991.92423 -8.3183,8.36327 1.0624,1.0567 8.3204,-8.36138 -1.0645,-1.05859 z"
+       id="path12"
+       inkscape:connector-curvature="0" />
+    <path
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#005544;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       d="m 20.6973,991.92423 -12.4785,12.54497 1.0624,1.0566 12.4805,-12.54298 -1.0644,-1.05859 z"
+       id="path14"
+       inkscape:connector-curvature="0" />
+    <path
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#005544;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       d="m 58.666,1020.9731 0,1.5 12.4785,0 0,-1.5 -12.4785,0 z"
+       id="path16"
+       inkscape:connector-curvature="0" />
+    <path
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#005544;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       d="m 17.0684,1000.0677 0,1.5 43.7754,0 c -0.225,-0.4875 -0.4255,-0.9873 -0.6016,-1.5 l -43.1738,0 z"
+       id="path18"
+       inkscape:connector-curvature="0" />
+    <path
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#005544;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       d="m 17.0684,1004.2465 0,1.5 33.4336,0 0,-1.5 -33.4336,0 z"
+       id="path20"
+       inkscape:connector-curvature="0" />
+    <path
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#005544;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       d="m 17.0684,1008.4281 0,1.5 20.8789,0 0,-1.5 -20.8789,0 z"
+       id="path22"
+       inkscape:connector-curvature="0" />
+    <path
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#005544;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       d="m 75.3047,978.06876 c -9.1577,0 -16.6953,7.57955 -16.6953,16.7793 0,9.29814 7.5435,16.77924 16.6953,16.77924 9.2502,0 16.6953,-7.4869 16.6953,-16.77924 0,-9.19389 -7.4393,-16.7793 -16.6953,-16.7793 z m 0,1.5 c 8.4378,0 15.1953,6.89296 15.1953,15.2793 0,8.49414 -6.7517,15.27924 -15.1953,15.27924 -8.3358,0 -15.1953,-6.7909 -15.1953,-15.27924 0,-8.38048 6.8654,-15.2793 15.1953,-15.2793 z"
+       id="path24"
+       inkscape:connector-curvature="0" />
+    <path
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#005544;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       d="m 74.347656,985.49805 0,10.07812 1.5,0 0,-10.07812 -1.5,0 z"
+       id="path26"
+       inkscape:connector-curvature="0" />
+    <path
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#005544;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       d="m 66.265625,991.66211 -0.460937,1.42773 9.535156,3.08204 0.46289,-1.42774 -9.537109,-3.08203 z"
+       id="path28"
+       inkscape:connector-curvature="0" />
+    <path
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#005544;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       d="m 84.34375,991.66211 -9.537109,3.08203 0.46289,1.42774 9.535157,-3.08204 -0.460938,-1.42773 z"
+       id="path30"
+       inkscape:connector-curvature="0" />
+    <path
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#005544;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       d="m 74.251953,995.07812 -5.863281,8.12308 1.216797,0.8769 5.863281,-8.12107 -1.216797,-0.87891 z"
+       id="path32"
+       inkscape:connector-curvature="0" />
+    <path
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#005544;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       d="m 76.179688,995.19727 -1.216797,0.8789 5.863281,8.12113 1.216797,-0.877 -5.863281,-8.12303 z"
+       id="path34"
+       inkscape:connector-curvature="0" />
+  </g>
+</svg>
diff --git a/res/icons/noun_198591_cc.svg b/res/icons/noun_198591_cc.svg
new file mode 100644
index 0000000000000000000000000000000000000000..240d78a522479c22aba69d7ea760e52921bda485
--- /dev/null
+++ b/res/icons/noun_198591_cc.svg
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 99.999 125"
+   enable-background="new 0 0 99.999 100"
+   xml:space="preserve"
+   id="svg2"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="noun_198591_cc.svg"><metadata
+     id="metadata14"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+     id="defs12" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1366"
+     inkscape:window-height="712"
+     id="namedview10"
+     showgrid="false"
+     inkscape:zoom="1.888"
+     inkscape:cx="49.9995"
+     inkscape:cy="62.5"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg2" /><path
+     d="m 86.731,35.862 8.268,-8.267 -10.59,-10.593 -8.284,8.283 C 60.558,14.231 39.493,14.253 23.946,25.353 L 15.595,17 5.001,27.59 13.369,35.959 C 2.337,51.494 2.336,72.504 13.366,88.041 l -8.367,8.367 10.594,10.59 8.351,-8.35 c 15.545,11.099 36.609,11.121 52.179,0.066 L 84.407,107 94.997,96.406 86.729,88.138 C 97.854,72.561 97.854,51.438 86.731,35.862 Z M 72.891,28.52 50.001,51.409 27.18,28.586 C 40.896,19.178 59.15,19.155 72.891,28.52 Z M 16.604,84.805 C 7.257,71.1 7.257,52.897 16.603,39.191 L 39.409,62 16.604,84.805 Z m 10.577,10.606 22.82,-22.819 22.889,22.89 c -13.742,9.367 -31.995,9.34 -45.709,-0.071 z M 83.496,84.905 60.593,62 83.498,39.096 c 9.431,13.75 9.431,32.06 -0.002,45.809 z"
+     id="path4"
+     inkscape:connector-curvature="0"
+     style="fill:#6c5353" /></svg>
\ No newline at end of file
diff --git a/res/icons/noun_213188_cc.svg b/res/icons/noun_213188_cc.svg
new file mode 100644
index 0000000000000000000000000000000000000000..53c003da2ca2e6692cd6bd8603a1f920771763b9
--- /dev/null
+++ b/res/icons/noun_213188_cc.svg
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 100 125"
+   id="svg2"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="noun_213188_cc.svg">
+  <metadata
+     id="metadata16">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs14" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1366"
+     inkscape:window-height="712"
+     id="namedview12"
+     showgrid="false"
+     inkscape:zoom="1.888"
+     inkscape:cx="50"
+     inkscape:cy="62.5"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg2" />
+  <g
+     transform="matrix(1.2059793,0,0,1.2059793,-9.8622,43.847222)"
+     id="g4"
+     style="fill:#008000">
+    <path
+       d="M 50,5 C 39.766783,5 31.46875,15.218727 31.46875,27.8125 c 0,12.6 8.298033,22.8125 18.53125,22.8125 10.233219,0 18.53125,-10.2125 18.53125,-22.8125 C 68.53125,15.218727 60.233219,5 50,5 Z M 31.375,53.78125 c -2.404152,-0.0062 -4.971172,0.888365 -7.46875,2.9375 -6.869896,5.624221 -11.602724,13.02221 -14.1875,21.21875 -2.416609,7.667128 1.916284,9.677963 8.40625,10.53125 5.319031,0.703805 8.871669,2.39866 13.3125,3.8125 C 39.758607,94.940767 44.824222,95 50,95 c 5.175779,0 10.241392,-0.05923 18.5625,-2.71875 4.440831,-1.41384 7.993469,-3.108695 13.3125,-3.8125 6.489965,-0.853287 10.822859,-2.864122 8.40625,-10.53125 -2.584775,-8.19654 -7.317603,-15.594529 -14.1875,-21.21875 -3.998616,-3.276125 -8.168037,-3.638063 -11.5625,-2 -5.088582,2.460207 -9.598378,3.75 -14.53125,3.75 -4.932871,0 -9.442669,-1.289793 -14.53125,-3.75 -1.270588,-0.610381 -2.648768,-0.931273 -4.09375,-0.9375 z"
+       transform="translate(0,-36)"
+       style="fill:#008000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+       id="path6"
+       inkscape:connector-curvature="0" />
+  </g>
+</svg>
diff --git a/res/icons/noun_213192_cc.svg b/res/icons/noun_213192_cc.svg
new file mode 100644
index 0000000000000000000000000000000000000000..04550973a4da468a256d21108d0c754b1bb03b07
--- /dev/null
+++ b/res/icons/noun_213192_cc.svg
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 100 125"
+   id="svg2"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="noun_213192_cc.svg">
+  <metadata
+     id="metadata16">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs14" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1366"
+     inkscape:window-height="712"
+     id="namedview12"
+     showgrid="false"
+     inkscape:zoom="1.888"
+     inkscape:cx="-50.900424"
+     inkscape:cy="62.5"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg2" />
+  <g
+     transform="matrix(1.1000428,0,0,1.1000428,-4.4991194,48.745336)"
+     id="g4"
+     style="fill:#aa0000">
+    <path
+       d="M 37.84375,11.46875 C 29.634879,11.46875 23,19.647734 23,29.75 c 0,10.108496 6.634879,18.3125 14.84375,18.3125 8.208869,0 14.875,-8.204004 14.875,-18.3125 0,-10.102266 -6.666131,-18.28125 -14.875,-18.28125 z M 62.1875,47.125 c -0.211762,0 -0.400565,0.08807 -0.5625,0.25 l -7.78125,7.75 c -0.32387,0.32387 -0.32387,0.838607 0,1.15625 L 65.375,67.84375 53.84375,79.375 c -0.32387,0.323871 -0.32387,0.83238 0,1.15625 l 7.78125,7.75 c 0.32387,0.323871 0.83238,0.323871 1.15625,0 L 74.3125,76.75 85.84375,88.28125 c 0.317641,0.323871 0.832379,0.323871 1.15625,0 l 7.75,-7.75 c 0.32387,-0.32387 0.32387,-0.832379 0,-1.15625 L 83.21875,67.84375 94.75,56.28125 c 0.32387,-0.317643 0.32387,-0.83238 0,-1.15625 L 87,47.375 c -0.323871,-0.323871 -0.838609,-0.323871 -1.15625,0 L 74.3125,58.90625 62.78125,47.375 c -0.161935,-0.161936 -0.381989,-0.25 -0.59375,-0.25 z m -39.28125,3.46875 c -1.930766,-0.0062 -4.000722,0.705714 -6,2.34375 -5.512025,4.509274 -9.3009835,10.460417 -11.375,17.03125 -1.9369944,6.15354 1.5493878,7.752389 6.75,8.4375 4.26637,0.560544 7.131153,1.922726 10.6875,3.0625 6.676713,2.130071 10.720738,2.1875 14.875,2.1875 3.936271,0 7.771178,-0.05634 13.84375,-1.875 -0.498263,-0.803446 -0.736565,-1.715998 -0.46875,-2.71875 2.958433,-4.241456 7.074882,-7.494239 10.625,-11.21875 C 59.564201,65.557972 57.27955,63.285776 55,61 53.59241,59.349505 51.156033,58.110192 51.09375,55.65625 51.486131,53.600919 53.11153,52.188947 54.625,50.8125 52.806345,50.388976 51.050842,50.596357 49.5,51.34375 c -4.079521,1.968136 -7.701294,3 -11.65625,3 -3.954957,0 -7.576728,-1.031864 -11.65625,-3 -1.015209,-0.498261 -2.122791,-0.75 -3.28125,-0.75 z"
+       transform="translate(0,-36)"
+       style="fill:#aa0000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+       id="path6"
+       inkscape:connector-curvature="0" />
+  </g>
+</svg>
diff --git a/res/icons/noun_213886_cc.svg b/res/icons/noun_213886_cc.svg
new file mode 100644
index 0000000000000000000000000000000000000000..8abb8ccabd91d0670153095f50581d762f4a334e
--- /dev/null
+++ b/res/icons/noun_213886_cc.svg
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 100 125"
+   id="svg2"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="noun_213886_cc.svg">
+  <metadata
+     id="metadata16">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs14" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1366"
+     inkscape:window-height="712"
+     id="namedview12"
+     showgrid="false"
+     inkscape:zoom="1.888"
+     inkscape:cx="50"
+     inkscape:cy="62.5"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg2" />
+  <g
+     transform="matrix(1.0756045,0,0,1.0756045,-4.3771943,50.028402)"
+     id="g4"
+     style="fill:#d45500">
+    <path
+       d="M 37.84375,11.46875 C 29.634795,11.46875 23,19.672651 23,29.78125 c 0,10.10237 6.634795,18.28125 14.84375,18.28125 8.208953,0 14.875,-8.17888 14.875,-18.28125 0,-10.108599 -6.666047,-18.3125 -14.875,-18.3125 z M 71.28125,47.125 c -0.429757,0 -0.844508,0.257528 -1.0625,0.625 L 47.75,86.6875 c -0.217992,0.367472 -0.211765,0.845049 0,1.21875 0.211763,0.367472 0.632745,0.625 1.0625,0.625 l 44.96875,0 c 0.429756,0 0.850737,-0.257528 1.0625,-0.625 0.217992,-0.373701 0.217965,-0.851278 0,-1.21875 l -22.5,-38.9375 c -0.211765,-0.367472 -0.638974,-0.625 -1.0625,-0.625 z m -48.375,3.46875 c -1.930786,-0.0062 -4.000702,0.705696 -6,2.34375 -5.512083,4.515547 -9.3009621,10.460349 -11.375,17.03125 -1.9370144,6.147373 1.5493347,7.752384 6.75,8.4375 4.266414,0.560551 7.131117,1.922712 10.6875,3.0625 6.676783,2.130092 10.720696,2.1875 14.875,2.1875 2.846352,0 5.650126,-0.02118 9.28125,-0.71875 C 52.032933,73.981145 57.280324,65.206788 62.40625,56.375 61.297605,55.166703 60.076745,54.002546 58.78125,52.9375 55.573654,50.315369 52.221787,50.060819 49.5,51.375 c -4.079563,1.968156 -7.701253,2.96875 -11.65625,2.96875 -3.954997,0 -7.545436,-1.000594 -11.625,-2.96875 -1.015219,-0.492041 -2.154029,-0.775022 -3.3125,-0.78125 z m 48.375,6.1875 c 0.566779,0 1.107615,0.320354 1.5,0.78125 0.392385,0.460898 0.682137,1.090012 0.9375,1.8125 0.523179,1.438747 0.84375,3.313528 0.84375,5.40625 0,2.192376 -0.677317,5.026916 -1.34375,7.375 -0.666432,2.348085 -1.34375,4.1875 -1.34375,4.1875 -0.09342,0.26159 -0.344617,0.4375 -0.59375,0.4375 -0.242905,0 -0.469074,-0.17591 -0.5625,-0.4375 0,0 -0.683546,-1.839415 -1.34375,-4.1875 -0.666433,-2.348084 -1.34375,-5.182624 -1.34375,-7.375 0,-2.092722 0.295548,-3.967503 0.8125,-5.40625 0.26159,-0.722488 0.576365,-1.351602 0.96875,-1.8125 0.392385,-0.460896 0.901971,-0.78125 1.46875,-0.78125 z m 0,21.4375 c 1.575769,0 2.875,1.261751 2.875,2.84375 0,1.581999 -1.299231,2.875 -2.875,2.875 -1.575771,0 -2.84375,-1.293001 -2.84375,-2.875 0,-1.57577 1.267979,-2.84375 2.84375,-2.84375 z"
+       transform="translate(0,-36)"
+       style="fill:#d45500;fill-opacity:1;fill-rule:nonzero;stroke:none"
+       id="path6"
+       inkscape:connector-curvature="0" />
+  </g>
+</svg>
diff --git a/res/icons/noun_269788_cc.svg b/res/icons/noun_269788_cc.svg
new file mode 100644
index 0000000000000000000000000000000000000000..0e7ff36d7682e4c2bdadf8f6f70f6eac6371a664
--- /dev/null
+++ b/res/icons/noun_269788_cc.svg
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 262.20472 184.25197"
+   enable-background="new 0 0 100 100"
+   xml:space="preserve"
+   id="svg2"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="noun_269788_cc.svg"
+   width="74mm"
+   height="52mm"><metadata
+     id="metadata22"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
+     id="defs20" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1366"
+     inkscape:window-height="712"
+     id="namedview18"
+     showgrid="false"
+     inkscape:zoom="0.6675088"
+     inkscape:cx="168.27594"
+     inkscape:cy="16.790099"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg2"
+     units="mm" /><rect
+     x="11.055084"
+     y="144.259"
+     width="34.501839"
+     height="34.501839"
+     id="rect4"
+     style="fill:#00aa00" /><rect
+     x="60.344528"
+     y="109.75682"
+     width="34.501839"
+     height="69.006248"
+     id="rect6"
+     style="fill:#00aa00" /><rect
+     x="109.63396"
+     y="75.254662"
+     width="34.501839"
+     height="103.5081"
+     id="rect8"
+     style="fill:#00aa00" /><rect
+     x="158.92342"
+     y="40.752491"
+     width="34.499264"
+     height="138.00993"
+     id="rect10"
+     style="fill:#00aa00" /><rect
+     x="208.21284"
+     y="6.2480106"
+     width="34.501839"
+     height="172.51178"
+     id="rect12"
+     style="fill:#00aa00" /></svg>
\ No newline at end of file
diff --git a/res/icons/noun_269792_cc.svg b/res/icons/noun_269792_cc.svg
new file mode 100644
index 0000000000000000000000000000000000000000..47fce937268e6fbab30233a12f9651e271087642
--- /dev/null
+++ b/res/icons/noun_269792_cc.svg
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 184.25197 131.10236"
+   enable-background="new 0 0 100 100"
+   xml:space="preserve"
+   id="svg2"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="noun_269792_cc.svg"
+   width="52mm"
+   height="37mm"><metadata
+     id="metadata22"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
+     id="defs20" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1366"
+     inkscape:window-height="712"
+     id="namedview18"
+     showgrid="false"
+     inkscape:zoom="1.888"
+     inkscape:cx="-23.710046"
+     inkscape:cy="47.263014"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg2"
+     units="mm" /><rect
+     x="5.8220339"
+     y="102.44091"
+     width="24.950264"
+     height="24.950264"
+     id="rect4"
+     style="fill:#d45500" /><rect
+     x="41.466068"
+     y="77.490646"
+     width="24.950264"
+     height="49.90239"
+     id="rect6"
+     style="fill:#d45500" /><rect
+     x="77.110092"
+     y="52.540382"
+     width="24.950264"
+     height="74.852654"
+     id="rect8"
+     style="fill:#d45500" /><path
+     d="m 137.70439,127.39303 -24.95025,0 0,-99.802926 24.9484,0 0,99.802926 z m -21.22745,-3.72281 17.50278,0 0,-92.357307 -17.50278,0 0,92.357307 z"
+     id="path10"
+     inkscape:connector-curvature="0"
+     style="fill:#d45500" /><path
+     d="m 173.34842,127.39303 -24.95025,0 0,-124.7550516 24.95025,0 0,124.7550516 z m -21.22745,-3.72281 17.50465,0 0,-117.3094328 -17.50465,0 0,117.3094328 z"
+     id="path12"
+     inkscape:connector-curvature="0"
+     style="fill:#d45500" /></svg>
\ No newline at end of file
diff --git a/res/icons/noun_269793_cc.svg b/res/icons/noun_269793_cc.svg
new file mode 100644
index 0000000000000000000000000000000000000000..7c9bf0c5329c13d5fd2759eb7808b68b0d9db078
--- /dev/null
+++ b/res/icons/noun_269793_cc.svg
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 184.25197 131.10236"
+   enable-background="new 0 0 100 100"
+   xml:space="preserve"
+   id="svg2"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="noun_269793_cc.svg"
+   width="52mm"
+   height="37mm"><metadata
+     id="metadata22"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
+     id="defs20" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1366"
+     inkscape:window-height="712"
+     id="namedview18"
+     showgrid="false"
+     inkscape:zoom="0.118"
+     inkscape:cx="-2954.4935"
+     inkscape:cy="962.76781"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg2"
+     units="mm" /><path
+     d="m 28.934386,129.85912 -25.8157419,0 0,-25.81766 25.8157419,0 0,25.81766 z m -21.9637959,-3.85193 18.1118499,0 0,-18.11185 -18.1118499,0 0,18.11185 z"
+     id="path4"
+     inkscape:connector-curvature="0"
+     style="fill:#d40000" /><path
+     d="m 65.814843,129.85912 -25.815743,0 0,-51.633399 25.815743,0 0,51.633399 z m -21.963796,-3.85193 18.111849,0 0,-43.929529 -18.111849,0 0,43.929529 z"
+     id="path6"
+     inkscape:connector-curvature="0"
+     style="fill:#d40000" /><path
+     d="m 102.6953,129.85912 -25.815743,0 0,-77.449138 25.815743,0 0,77.449138 z m -21.963796,-3.85193 18.111849,0 0,-69.745263 -18.111849,0 0,69.745263 z"
+     id="path8"
+     inkscape:connector-curvature="0"
+     style="fill:#d40000" /><path
+     d="m 139.57576,129.85912 -25.81575,0 0,-103.26488 25.81382,0 0,103.26488 z m -21.9638,-3.85193 18.10992,0 0,-95.561003 -18.10992,0 0,95.561003 z"
+     id="path10"
+     inkscape:connector-curvature="0"
+     style="fill:#d40000" /><path
+     d="m 176.45621,129.85912 -25.81574,0 0,-129.08254796 25.81574,0 0,129.08254796 z m -21.96379,-3.85193 18.11185,0 0,-121.3786714 -18.11185,0 0,121.3786714 z"
+     id="path12"
+     inkscape:connector-curvature="0"
+     style="fill:#d40000" /></svg>
\ No newline at end of file
diff --git a/res/icons/noun_274635_cc.svg b/res/icons/noun_274635_cc.svg
new file mode 100644
index 0000000000000000000000000000000000000000..9534a54837711a4617e296c830b799abf5258f15
--- /dev/null
+++ b/res/icons/noun_274635_cc.svg
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:sketch="http://www.bohemiancoding.com/sketch/ns"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   viewBox="0 0 30 37.5"
+   version="1.1"
+   x="0px"
+   y="0px"
+   id="svg2"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="noun_274635_cc.svg">
+  <metadata
+     id="metadata22">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs20" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1366"
+     inkscape:window-height="712"
+     id="namedview18"
+     showgrid="false"
+     inkscape:zoom="6.2933333"
+     inkscape:cx="15"
+     inkscape:cy="18.75"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg2" />
+  <title
+     id="title4">action_012-history-arrow-time-update</title>
+  <desc
+     id="desc6">Created with Sketch.</desc>
+  <g
+     sketch:type="MSPage"
+     id="g8"
+     transform="matrix(1.0647348,0,0,1.0647348,-1.8454517,4.1873838)"
+     style="fill:#008000;fill-rule:evenodd;stroke:none;stroke-width:1">
+    <g
+       sketch:type="MSArtboardGroup"
+       transform="translate(-90,-90)"
+       id="g10"
+       style="fill:#008000">
+      <path
+         d="m 114.3382,97.08445 -1.1269,0.94558 c -0.84382,0.708053 -0.64338,1.40872 0.45043,1.562694 l 3.69774,0.520526 c 0.54582,0.0768 0.99829,-0.305762 1.01729,-0.85361 l 0.12949,-3.73195 c 0.0384,-1.106118 -0.61569,-1.424029 -1.46073,-0.714951 l -1.20361,1.009943 c -4.79252,-5.711508 -13.30772,-6.456492 -19.019228,-1.663968 -5.711508,4.792525 -6.456492,13.307726 -1.663968,19.019236 4.792525,5.7115 13.307726,6.45649 19.019236,1.66396 1.98848,-1.66854 3.43633,-3.84334 4.20465,-6.29948 0.16183,-0.51734 -0.12637,-1.06791 -0.6437,-1.22974 -0.51734,-0.16183 -1.06791,0.12636 -1.22974,0.6437 -0.65647,2.09858 -1.89232,3.95478 -3.59298,5.38181 -4.88103,4.09567 -12.15808,3.45901 -16.253749,-1.42202 -4.095669,-4.88103 -3.459009,-12.15808 1.422019,-16.253749 4.88103,-4.095669 12.15808,-3.459009 16.25375,1.422019 z m -14.780852,3.78713 -0.700482,0.70049 c -0.197092,0.19709 -0.195891,0.51784 0.0035,0.71724 l 6.350314,6.35031 c 0.19903,0.19903 0.52358,0.19718 0.71424,0.007 l 4.94913,-4.94913 c 0.19543,-0.19543 0.20252,-0.50521 -0.003,-0.71073 l -0.70049,-0.70048 c -0.19709,-0.19709 -0.518,-0.19573 -0.70405,-0.01 l -3.89545,3.89545 -5.303,-5.30299 c -0.19543,-0.19543 -0.505203,-0.20252 -0.710723,0.003 z"
+         sketch:type="MSShapeGroup"
+         id="path12"
+         inkscape:connector-curvature="0"
+         style="fill:#008000" />
+    </g>
+  </g>
+</svg>
diff --git a/res/icons/noun_60040_cc.svg b/res/icons/noun_60040_cc.svg
new file mode 100644
index 0000000000000000000000000000000000000000..65b0400d994538da3e9a552c3a406cab6c1e5779
--- /dev/null
+++ b/res/icons/noun_60040_cc.svg
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 100 125"
+   enable-background="new 0 0 100 100"
+   xml:space="preserve"
+   id="svg2"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="noun_60040_cc.svg"><metadata
+     id="metadata14"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+     id="defs12" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1366"
+     inkscape:window-height="712"
+     id="namedview10"
+     showgrid="false"
+     inkscape:zoom="1.888"
+     inkscape:cx="18.19375"
+     inkscape:cy="62.5"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg2" /><path
+     d="M 99.87499,38.500263 C 99.87499,31.625118 94.249868,26 87.374724,26 c -4.625098,0 -8.625182,2.500053 -10.875229,6.250132 l -53.251121,0 C 21.123329,28.500053 16.998242,26 12.373145,26 5.4979998,26 -0.127119,31.625118 -0.127119,38.500263 c 0,6.875145 5.6251188,12.500263 12.500264,12.500263 4.625097,0 8.625181,-2.500052 10.875229,-6.250131 l 53.376123,0 c 2.125045,3.750079 6.250132,6.250131 10.875229,6.250131 6.750142,0 12.375264,-5.625118 12.375264,-12.500263 z m -87.501845,7.500158 c -4.125087,0 -7.5001584,-3.375071 -7.5001584,-7.500158 0,-4.125087 3.3750714,-7.500158 7.5001584,-7.500158 4.125086,0 7.500158,3.375071 7.500158,7.500158 0,4.125087 -3.375072,7.500158 -7.500159,7.500158 z m 75.001579,0 c -4.125087,0 -7.500158,-3.375071 -7.500158,-7.500158 0,-4.125087 3.375071,-7.500158 7.500158,-7.500158 4.125087,0 7.500158,3.375071 7.500158,7.500158 0,4.125087 -3.375071,7.500158 -7.500158,7.500158 z m 0,5.000105 -13.125277,22.750479 6.875145,0 0,2.250048 c 0,1.875039 -0.625013,6.250131 -6.250132,6.250131 l -51.626086,0 c -2.125045,-3.750079 -6.250132,-6.250131 -10.875229,-6.250131 -6.8751452,0 -12.500264,5.625118 -12.500264,12.500263 0,6.875145 5.6251188,12.500264 12.500264,12.500264 4.625097,0 8.625181,-2.500054 10.875229,-6.250132 l 51.626086,0 c 13.75029,0 18.750395,-11.250237 18.750395,-18.750395 l 0,-2.250048 6.875145,0 L 87.374724,51.000526 Z M 12.373145,96.001474 c -4.125087,0 -7.5001584,-3.375071 -7.5001584,-7.500158 0,-4.125087 3.3750714,-7.500158 7.5001584,-7.500158 4.125086,0 7.500158,3.375071 7.500158,7.500158 0,4.125087 -3.375072,7.500158 -7.500159,7.500158 z"
+     id="path4"
+     inkscape:connector-curvature="0"
+     style="fill:#d45500" /></svg>
\ No newline at end of file
diff --git a/res/icons/noun_87601_cc.svg b/res/icons/noun_87601_cc.svg
new file mode 100644
index 0000000000000000000000000000000000000000..21ae9b4b0944f8557e359cca97cea1bb2983b89d
--- /dev/null
+++ b/res/icons/noun_87601_cc.svg
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 100 125"
+   enable-background="new 0 0 100 100"
+   xml:space="preserve"
+   id="svg2"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="noun_87601_cc.svg"><metadata
+     id="metadata16"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+     id="defs14" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1366"
+     inkscape:window-height="712"
+     id="namedview12"
+     showgrid="false"
+     inkscape:zoom="1.888"
+     inkscape:cx="50"
+     inkscape:cy="62.5"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg2" /><path
+     d="m 0.83531061,26.711164 c 0,4.97582 1.74826129,9.682677 5.11030139,13.448161 l 0,15.599867 c 0,5.513746 4.572376,10.086122 10.086122,10.086122 l 6.993044,0 c 1.479297,13.179198 12.775753,23.534282 26.492877,23.534282 13.717126,0 25.01358,-10.355084 26.62736,-23.534282 l 6.993044,0 c 1.882743,0 3.36204,1.479297 3.36204,3.36204 l 0,15.465385 c -3.227559,3.765486 -5.110301,8.472342 -5.110301,13.448166 l 0,24.879095 16.810202,0 0,-24.74462 c 0,-4.975817 -1.748261,-9.682673 -5.110301,-13.448158 l 0,-15.599868 c 0,-5.513746 -4.572375,-10.086121 -10.086121,-10.086121 l -6.993045,0 C 74.531235,45.942035 63.234781,35.58695 49.517655,35.58695 c -13.717124,0 -25.01358,10.355085 -26.62736,23.534283 l -6.993044,0 c -1.882742,0 -3.36204,-1.479297 -3.36204,-3.362041 l 0,-15.465385 c 3.227559,-3.765485 5.110302,-8.472342 5.110302,-13.448162 l 0,-24.8790979 -16.81020239,0 0,24.7446169 z M 88.248361,98.25538 c 0,-2.420666 0.537926,-4.572372 1.748261,-6.589597 1.075853,2.017225 1.74826,4.303412 1.74826,6.589597 l 0,7.93442 -3.36204,0 0,-7.93442 z m 0,14.6585 3.36204,0 0,3.36204 -3.36204,0 0,-3.36204 z M 49.517655,42.311031 c 11.161975,0 20.172242,9.010268 20.172242,20.172243 0,11.161973 -9.010267,20.172242 -20.172242,20.172242 -11.161973,0 -20.172242,-9.010269 -20.172242,-20.172242 0,-11.161975 9.010269,-20.172243 20.172242,-20.172243 z M 7.5593909,8.6906274 l 3.3620411,0 0,3.3620406 -3.3620411,0 0,-3.3620406 z m 0,10.0861206 3.3620411,0 0,7.934416 c 0,2.420669 -0.537927,4.572375 -1.748261,6.589599 C 8.097318,31.283539 7.4249098,28.997351 7.4249098,26.711164 l 0,-7.934416 z"
+     id="path4"
+     inkscape:connector-curvature="0"
+     style="fill:#d40000" /><polygon
+     points="46.5,50 41.2,55.3 44.7,58.8 50,53.5 55.3,58.8 58.8,55.3 53.5,50 58.8,44.7 55.3,41.2 50,46.5 44.7,41.2 41.2,44.7 "
+     id="polygon6"
+     transform="matrix(1.3448162,0,0,1.3448162,-17.723152,-4.7575344)"
+     style="fill:#d40000" /></svg>
\ No newline at end of file
diff --git a/res/ui/certification.ui b/res/ui/certification.ui
index fda8aba450a1ca89b154570dfdceb5113173aeb4..b65ffecfa69f9f79bc2af2230537110e13fcff5e 100644
--- a/res/ui/certification.ui
+++ b/res/ui/certification.ui
@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>399</width>
-    <height>216</height>
+    <width>715</width>
+    <height>477</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -16,6 +16,12 @@
   <layout class="QVBoxLayout" name="verticalLayout">
    <item>
     <widget class="QGroupBox" name="groupBox_2">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
      <property name="title">
       <string>Community</string>
      </property>
@@ -31,55 +37,161 @@
      <property name="title">
       <string>Certify user</string>
      </property>
-     <layout class="QVBoxLayout" name="verticalLayout_2">
+     <layout class="QHBoxLayout" name="horizontalLayout_5">
       <item>
-       <layout class="QHBoxLayout" name="horizontalLayout_2">
+       <layout class="QVBoxLayout" name="verticalLayout_3">
+        <property name="topMargin">
+         <number>6</number>
+        </property>
         <item>
-         <widget class="QRadioButton" name="radio_contact">
-          <property name="text">
-           <string>Contact</string>
-          </property>
-          <property name="checked">
-           <bool>true</bool>
-          </property>
-         </widget>
+         <layout class="QHBoxLayout" name="horizontalLayout_2">
+          <item>
+           <widget class="QRadioButton" name="radio_contact">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <property name="text">
+             <string>Con&amp;tact</string>
+            </property>
+            <property name="checked">
+             <bool>true</bool>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <spacer name="horizontalSpacer">
+            <property name="orientation">
+             <enum>Qt::Horizontal</enum>
+            </property>
+            <property name="sizeType">
+             <enum>QSizePolicy::Maximum</enum>
+            </property>
+            <property name="sizeHint" stdset="0">
+             <size>
+              <width>20</width>
+              <height>20</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
+          <item>
+           <widget class="QComboBox" name="combo_contact">
+            <property name="enabled">
+             <bool>true</bool>
+            </property>
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+           </widget>
+          </item>
+         </layout>
         </item>
         <item>
-         <widget class="QComboBox" name="combo_contact">
-          <property name="enabled">
-           <bool>true</bool>
-          </property>
-         </widget>
-        </item>
-       </layout>
-      </item>
-      <item>
-       <layout class="QHBoxLayout" name="horizontalLayout">
-        <item>
-         <widget class="QRadioButton" name="radio_pubkey">
-          <property name="text">
-           <string>User public key</string>
-          </property>
-          <property name="checked">
-           <bool>false</bool>
-          </property>
-         </widget>
+         <layout class="QHBoxLayout" name="horizontalLayout">
+          <item>
+           <widget class="QRadioButton" name="radio_pubkey">
+            <property name="text">
+             <string>&amp;User public key</string>
+            </property>
+            <property name="checked">
+             <bool>false</bool>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <spacer name="horizontalSpacer_2">
+            <property name="orientation">
+             <enum>Qt::Horizontal</enum>
+            </property>
+            <property name="sizeType">
+             <enum>QSizePolicy::Maximum</enum>
+            </property>
+            <property name="sizeHint" stdset="0">
+             <size>
+              <width>40</width>
+              <height>20</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
+          <item>
+           <widget class="QLineEdit" name="edit_pubkey">
+            <property name="enabled">
+             <bool>false</bool>
+            </property>
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <property name="inputMask">
+             <string/>
+            </property>
+            <property name="text">
+             <string/>
+            </property>
+            <property name="placeholderText">
+             <string>Key</string>
+            </property>
+           </widget>
+          </item>
+         </layout>
         </item>
         <item>
-         <widget class="QLineEdit" name="edit_pubkey">
-          <property name="enabled">
-           <bool>false</bool>
-          </property>
-          <property name="inputMask">
-           <string/>
-          </property>
-          <property name="text">
-           <string/>
-          </property>
-          <property name="placeholderText">
-           <string>Key</string>
+         <layout class="QHBoxLayout" name="horizontalLayout_3">
+          <property name="topMargin">
+           <number>6</number>
           </property>
-         </widget>
+          <item>
+           <widget class="QRadioButton" name="radio_search">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <property name="text">
+             <string>S&amp;earch user</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <spacer name="horizontalSpacer_3">
+            <property name="orientation">
+             <enum>Qt::Horizontal</enum>
+            </property>
+            <property name="sizeType">
+             <enum>QSizePolicy::Maximum</enum>
+            </property>
+            <property name="sizeHint" stdset="0">
+             <size>
+              <width>40</width>
+              <height>20</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
+          <item>
+           <widget class="SearchUserWidget" name="search_user" native="true">
+            <property name="enabled">
+             <bool>false</bool>
+            </property>
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+           </widget>
+          </item>
+         </layout>
         </item>
        </layout>
       </item>
@@ -98,73 +210,16 @@
    </item>
   </layout>
  </widget>
+ <customwidgets>
+  <customwidget>
+   <class>SearchUserWidget</class>
+   <extends>QWidget</extends>
+   <header>sakia.gui.widgets.search_user</header>
+   <container>1</container>
+  </customwidget>
+ </customwidgets>
  <resources/>
- <connections>
-  <connection>
-   <sender>button_box</sender>
-   <signal>accepted()</signal>
-   <receiver>CertificationDialog</receiver>
-   <slot>accept()</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>248</x>
-     <y>254</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>157</x>
-     <y>274</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
-   <sender>button_box</sender>
-   <signal>rejected()</signal>
-   <receiver>CertificationDialog</receiver>
-   <slot>reject()</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>316</x>
-     <y>260</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>286</x>
-     <y>274</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
-   <sender>radio_pubkey</sender>
-   <signal>toggled(bool)</signal>
-   <receiver>CertificationDialog</receiver>
-   <slot>recipient_mode_changed(bool)</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>87</x>
-     <y>51</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>199</x>
-     <y>244</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
-   <sender>combo_community</sender>
-   <signal>currentIndexChanged(int)</signal>
-   <receiver>CertificationDialog</receiver>
-   <slot>change_current_community(int)</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>199</x>
-     <y>50</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>199</x>
-     <y>165</y>
-    </hint>
-   </hints>
-  </connection>
- </connections>
+ <connections/>
  <slots>
   <slot>open_manage_wallet_coins()</slot>
   <slot>change_displayed_wallet(int)</slot>
diff --git a/res/ui/identities_tab.ui b/res/ui/identities_tab.ui
index 5f3f2e072c5778a32cbea7c6f2bfc1b77a0750c5..0dab4a2d41ed7e07fe2da897b2dc8bad20aa7496 100644
--- a/res/ui/identities_tab.ui
+++ b/res/ui/identities_tab.ui
@@ -63,8 +63,19 @@
      </attribute>
     </widget>
    </item>
+   <item>
+    <widget class="Busy" name="busy" native="true"/>
+   </item>
   </layout>
  </widget>
+ <customwidgets>
+  <customwidget>
+   <class>Busy</class>
+   <extends>QWidget</extends>
+   <header>sakia.gui.widgets.busy</header>
+   <container>1</container>
+  </customwidget>
+ </customwidgets>
  <resources/>
  <connections/>
 </ui>
diff --git a/res/ui/member.ui b/res/ui/member.ui
index ca9b92019f0ad59dbb5e57fa2061ac2c2c5ef38b..23bb9d1769f46c84eca8ca91a172ae5612de9dce 100644
--- a/res/ui/member.ui
+++ b/res/ui/member.ui
@@ -1,17 +1,17 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <ui version="4.0">
- <class>DialogMember</class>
- <widget class="QDialog" name="DialogMember">
+ <class>MemberView</class>
+ <widget class="QWidget" name="MemberView">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>501</width>
-    <height>288</height>
+    <width>392</width>
+    <height>251</height>
    </rect>
   </property>
   <property name="windowTitle">
-   <string>Informations</string>
+   <string>Member informations</string>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout">
    <item>
@@ -34,8 +34,14 @@ QGroupBox::title {
       <string>Member</string>
      </property>
      <layout class="QGridLayout" name="gridLayout">
-      <item row="0" column="0">
+      <item row="0" column="1">
        <widget class="QLabel" name="label_icon">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
         <property name="maximumSize">
          <size>
           <width>81</width>
@@ -53,7 +59,17 @@ QGroupBox::title {
         </property>
        </widget>
       </item>
-      <item row="0" column="1">
+      <item row="2" column="1" colspan="2">
+       <widget class="QLabel" name="label_properties">
+        <property name="text">
+         <string/>
+        </property>
+        <property name="alignment">
+         <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="2">
        <widget class="QLabel" name="label_uid">
         <property name="maximumSize">
          <size>
@@ -62,17 +78,14 @@ QGroupBox::title {
          </size>
         </property>
         <property name="text">
-         <string>uid</string>
+         <string/>
         </property>
        </widget>
       </item>
-      <item row="1" column="0" colspan="2">
-       <widget class="QLabel" name="label_properties">
+      <item row="3" column="1" colspan="2">
+       <widget class="QLabel" name="label_path">
         <property name="text">
-         <string>properties</string>
-        </property>
-        <property name="alignment">
-         <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+         <string/>
         </property>
        </widget>
       </item>
@@ -83,7 +96,6 @@ QGroupBox::title {
  </widget>
  <resources>
   <include location="../icons/icons.qrc"/>
-  <include location="../icons/icons.qrc"/>
  </resources>
  <connections/>
 </ui>
diff --git a/res/ui/transactions_tab.ui b/res/ui/transactions_tab.ui
index f32e7ebae129d4805b8fd1d023e548617972a9bb..737ecfa4aa93d0e094da40eed917ae4b71e16457 100644
--- a/res/ui/transactions_tab.ui
+++ b/res/ui/transactions_tab.ui
@@ -37,6 +37,9 @@
         </property>
        </widget>
       </item>
+      <item>
+       <widget class="Busy" name="busy_balance" native="true"/>
+      </item>
      </layout>
     </widget>
    </item>
@@ -105,61 +108,16 @@
    </item>
   </layout>
  </widget>
+ <customwidgets>
+  <customwidget>
+   <class>Busy</class>
+   <extends>QWidget</extends>
+   <header>sakia.gui.widgets</header>
+   <container>1</container>
+  </customwidget>
+ </customwidgets>
  <resources>
   <include location="../icons/icons.qrc"/>
  </resources>
- <connections>
-  <connection>
-   <sender>table_history</sender>
-   <signal>customContextMenuRequested(QPoint)</signal>
-   <receiver>transactionsTabWidget</receiver>
-   <slot>history_context_menu()</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>273</x>
-     <y>183</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>830</x>
-     <y>802</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
-   <sender>date_from</sender>
-   <signal>dateChanged(QDate)</signal>
-   <receiver>transactionsTabWidget</receiver>
-   <slot>dates_changed()</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>102</x>
-     <y>28</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>199</x>
-     <y>149</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
-   <sender>date_to</sender>
-   <signal>dateChanged(QDate)</signal>
-   <receiver>transactionsTabWidget</receiver>
-   <slot>dates_changed()</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>297</x>
-     <y>28</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>199</x>
-     <y>149</y>
-    </hint>
-   </hints>
-  </connection>
- </connections>
- <slots>
-  <slot>history_context_menu()</slot>
-  <slot>dates_changed()</slot>
- </slots>
+ <connections/>
 </ui>
diff --git a/res/ui/transfer.ui b/res/ui/transfer.ui
index d258290a8cd86addfc12749be43ec20cf359f106..64837315bef1d008698f420be49e8bcd95fc2b09 100644
--- a/res/ui/transfer.ui
+++ b/res/ui/transfer.ui
@@ -7,7 +7,7 @@
     <x>0</x>
     <y>0</y>
     <width>496</width>
-    <height>440</height>
+    <height>485</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -36,6 +36,12 @@
        <layout class="QHBoxLayout" name="horizontalLayout_2">
         <item>
          <widget class="QRadioButton" name="radio_contact">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
           <property name="text">
            <string>Con&amp;tact</string>
           </property>
@@ -44,11 +50,33 @@
           </property>
          </widget>
         </item>
+        <item>
+         <spacer name="horizontalSpacer_3">
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeType">
+           <enum>QSizePolicy::Maximum</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>40</width>
+            <height>20</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
         <item>
          <widget class="QComboBox" name="combo_contact">
           <property name="enabled">
            <bool>true</bool>
           </property>
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
          </widget>
         </item>
        </layout>
@@ -57,6 +85,12 @@
        <layout class="QHBoxLayout" name="horizontalLayout">
         <item>
          <widget class="QRadioButton" name="radio_pubkey">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
           <property name="text">
            <string>&amp;Recipient public key</string>
           </property>
@@ -65,11 +99,33 @@
           </property>
          </widget>
         </item>
+        <item>
+         <spacer name="horizontalSpacer_2">
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeType">
+           <enum>QSizePolicy::Maximum</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>40</width>
+            <height>20</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
         <item>
          <widget class="QLineEdit" name="edit_pubkey">
           <property name="enabled">
            <bool>false</bool>
           </property>
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
           <property name="inputMask">
            <string/>
           </property>
@@ -83,6 +139,52 @@
         </item>
        </layout>
       </item>
+      <item>
+       <layout class="QHBoxLayout" name="horizontalLayout_5">
+        <property name="topMargin">
+         <number>6</number>
+        </property>
+        <item>
+         <widget class="QRadioButton" name="radio_search">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+          <property name="text">
+           <string>S&amp;earch user</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <spacer name="horizontalSpacer">
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeType">
+           <enum>QSizePolicy::Maximum</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>40</width>
+            <height>20</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+        <item>
+         <widget class="SearchUserWidget" name="search_user" native="true">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </item>
      </layout>
     </widget>
    </item>
@@ -188,121 +290,16 @@
    </item>
   </layout>
  </widget>
+ <customwidgets>
+  <customwidget>
+   <class>SearchUserWidget</class>
+   <extends>QWidget</extends>
+   <header>sakia.gui.widgets.search_user</header>
+   <container>1</container>
+  </customwidget>
+ </customwidgets>
  <resources/>
- <connections>
-  <connection>
-   <sender>button_box</sender>
-   <signal>accepted()</signal>
-   <receiver>TransferMoneyDialog</receiver>
-   <slot>accept()</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>248</x>
-     <y>254</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>157</x>
-     <y>274</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
-   <sender>button_box</sender>
-   <signal>rejected()</signal>
-   <receiver>TransferMoneyDialog</receiver>
-   <slot>reject()</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>316</x>
-     <y>260</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>286</x>
-     <y>274</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
-   <sender>combo_wallets</sender>
-   <signal>currentIndexChanged(int)</signal>
-   <receiver>TransferMoneyDialog</receiver>
-   <slot>change_displayed_wallet(int)</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>82</x>
-     <y>264</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>199</x>
-     <y>244</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
-   <sender>radio_pubkey</sender>
-   <signal>toggled(bool)</signal>
-   <receiver>TransferMoneyDialog</receiver>
-   <slot>recipient_mode_changed(bool)</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>87</x>
-     <y>51</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>199</x>
-     <y>244</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
-   <sender>combo_community</sender>
-   <signal>currentIndexChanged(int)</signal>
-   <receiver>TransferMoneyDialog</receiver>
-   <slot>change_current_community(int)</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>199</x>
-     <y>50</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>199</x>
-     <y>165</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
-   <sender>spinbox_relative</sender>
-   <signal>valueChanged(double)</signal>
-   <receiver>TransferMoneyDialog</receiver>
-   <slot>relative_amount_changed()</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>320</x>
-     <y>269</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>199</x>
-     <y>165</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
-   <sender>spinbox_amount</sender>
-   <signal>valueChanged(double)</signal>
-   <receiver>TransferMoneyDialog</receiver>
-   <slot>amount_changed()</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>209</x>
-     <y>292</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>247</x>
-     <y>219</y>
-    </hint>
-   </hints>
-  </connection>
- </connections>
+ <connections/>
  <slots>
   <slot>open_manage_wallet_coins()</slot>
   <slot>change_displayed_wallet(int)</slot>
diff --git a/setup.py b/setup.py
index dca0a8308b46987df54a3e7daafef65b5270428c..4cdfe1a466d7d481e36be932054b2f88af6d086c 100644
--- a/setup.py
+++ b/setup.py
@@ -1,5 +1,4 @@
 import sys, os, subprocess, multiprocessing, site
-from cx_Freeze import setup, Executable
 from PyQt5 import QtCore
 from os import listdir
 from os.path import isfile, join
@@ -8,11 +7,19 @@ import unittest
 sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), 'src')))
 
 if "test" in sys.argv:
+    print(sys.path)
+    if "XDG_CONFIG_HOME" in os.environ:
+        os.environ["XDG_CONFIG_HOME"] = os.path.abspath(os.path.join(os.path.dirname(__file__), 'tmp'))
+    elif "HOME" in os.environ:
+        os.environ["HOME"] = os.path.abspath(os.path.join(os.path.dirname(__file__), 'tmp'))
+    elif "APPDATA" in os.environ:
+        os.environ["APPDATA"] = os.path.abspath(os.path.join(os.path.dirname(__file__), 'tmp'))
     runner = unittest.TextTestRunner().run(unittest.defaultTestLoader.discover(start_dir='sakia.tests',
                                                                                pattern='test_*'))
 
     sys.exit(not runner.wasSuccessful())
 else:
+    from cx_Freeze import setup, Executable
     print(sys.path)
     print("Environnement:")
     print(os.environ)
@@ -117,7 +124,7 @@ else:
 
     setup(
         name = "sakia",
-        version = "0.11.4",
+        version = "0.12.0",
         description = "UCoin client",
         author = "Inso",
         options = {"build_exe": options},
diff --git a/src/sakia/__init__.py b/src/sakia/__init__.py
index e92e1772fccf93ff2627cba943fed2e5091cbfbf..d4c85e473175c7b0fccd54e9748b783ab229ab3d 100644
--- a/src/sakia/__init__.py
+++ b/src/sakia/__init__.py
@@ -1,2 +1,2 @@
-__version_info__ = ('0', '11', '3')
+__version_info__ = ('0', '12', '0')
 __version__ = '.'.join(__version_info__)
diff --git a/src/sakia/core/account.py b/src/sakia/core/account.py
index 15a20055ba1bb70056c84f9ee35471792a811ee7..e713d64a4966c596c3d67068395eece17d7bff00 100644
--- a/src/sakia/core/account.py
+++ b/src/sakia/core/account.py
@@ -11,6 +11,7 @@ from ucoinpy.key import SigningKey
 import logging
 import time
 import asyncio
+from distutils.version import StrictVersion
 
 from PyQt5.QtCore import QObject, pyqtSignal
 
@@ -18,7 +19,8 @@ from . import money
 from .wallet import Wallet
 from .community import Community
 from .registry import LocalState
-from ..tools.exceptions import ContactAlreadyExists, NoPeerAvailable
+from ..tools.exceptions import ContactAlreadyExists
+from .. import __version__
 from ucoinpy.api import bma
 from ucoinpy.api.bma import PROTOCOL_VERSION
 from aiohttp.errors import ClientError
@@ -61,6 +63,19 @@ class Account(QObject):
         self._identities_registry = identities_registry
         self._current_ref = 0
 
+        self.notifications = {'membership_expire_soon':
+                                  [
+                                      self.tr("Warning : Your membership is expiring soon."),
+                                      0
+                                   ],
+                            'warning_certifications':
+                                    [
+                                        self.tr("Warning : Your could miss certifications soon."),
+                                        0
+                                    ],
+                            'warning_certifying_first_time': True,
+                            }
+
     @classmethod
     def create(cls, name, identities_registry):
         """
@@ -89,6 +104,10 @@ class Account(QObject):
         """
         salt = json_data['salt']
         pubkey = json_data['pubkey']
+        if 'file_version' in json_data:
+            file_version = StrictVersion(json_data['file_version'])
+        else:
+            file_version = StrictVersion('0.11.5')
 
         name = json_data['name']
         contacts = []
@@ -102,7 +121,7 @@ class Account(QObject):
 
         communities = []
         for data in json_data['communities']:
-            community = Community.load(data)
+            community = Community.load(data, file_version)
             communities.append(community)
 
         account = cls(salt, pubkey, name, communities, wallets,
@@ -497,7 +516,7 @@ class Account(QObject):
                     await r.release()
             return result
         else:
-            return (False, self.tr("Could not find user self certification."))
+            return False, self.tr("Could not find user self certification.")
 
     async def revoke(self, password, community):
         """
@@ -564,5 +583,6 @@ class Account(QObject):
                 'pubkey': self.pubkey,
                 'communities': data_communities,
                 'wallets': data_wallets,
-                'contacts': self.contacts}
+                'contacts': self.contacts,
+                'file_version': __version__}
         return data
diff --git a/src/sakia/core/app.py b/src/sakia/core/app.py
index 9aa906e29e5fbf21d78d9756f6e8abbd9ba018ef..a5ac832eaa100403a5d86b70ffba408cf184dced 100644
--- a/src/sakia/core/app.py
+++ b/src/sakia/core/app.py
@@ -10,17 +10,15 @@ import tarfile
 import shutil
 import json
 import datetime
-import asyncio
 import aiohttp
-import time
+from distutils.version import StrictVersion
 
-from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot, \
-QUrl, QTranslator, QCoreApplication, QLocale
+from PyQt5.QtCore import QObject, pyqtSignal, QTranslator, QCoreApplication, QLocale
 from ucoinpy.api.bma import API
 from aiohttp.connector import ProxyConnector
 from . import config
 from .account import Account
-from .registry.identities import IdentitiesRegistry
+from .registry import IdentitiesRegistry, Identity
 from .. import __version__
 from ..tools.exceptions import NameAlreadyExists, BadAccountFile
 from ..tools.decorators import asyncify
@@ -36,6 +34,7 @@ class Application(QObject):
     """
 
     version_requested = pyqtSignal()
+    view_identity_in_wot = pyqtSignal(Identity)
 
     def __init__(self, qapp, loop, identities_registry):
         """
@@ -71,18 +70,6 @@ class Application(QObject):
                             'auto_refresh': False
                             }
 
-        self.notifications = {'membership_expire_soon':
-                                  [
-                                      self.tr("Warning : Your membership is expiring soon."),
-                                      0
-                                   ],
-                            'warning_certifications':
-                                    [
-                                        self.tr("Warning : Your could miss certifications soon."),
-                                        0
-                                    ]
-                            }
-
     @classmethod
     def startup(cls, argv, qapp, loop):
         config.parse_arguments(argv)
@@ -204,6 +191,7 @@ class Application(QObject):
         and stop the coroutines
         """
         self.save_cache(self.current_account)
+        self.save_notifications(self.current_account)
         self.current_account.stop_coroutines()
 
     def load(self):
@@ -261,6 +249,17 @@ class Application(QObject):
                                                               account.rollback_transaction(self, co))
                 community.network.root_nodes_changed.connect(lambda acc=account: self.save(acc))
 
+        account_notifications_path = os.path.join(config.parameters['home'],
+                                    account_name, '__notifications__')
+
+        try:
+            with open(account_notifications_path, 'r') as json_data:
+                data = json.load(json_data)
+                account.notifications = data
+        except FileNotFoundError:
+            logging.debug("Could not find notifications file")
+            pass
+
     def load_cache(self, account):
         """
         Load an account cache
@@ -280,7 +279,7 @@ class Application(QObject):
                 with open(network_path, 'r') as json_data:
                     data = json.load(json_data)
                     logging.debug("Merging network : {0}".format(data))
-                    community.network.merge_with_json(data['network'])
+                    community.network.merge_with_json(data['network'], StrictVersion(data['version']))
 
             if os.path.exists(bma_path):
                 with open(bma_path, 'r') as json_data:
@@ -350,6 +349,18 @@ class Application(QObject):
             account_path = os.path.join(config.parameters['home'], account.name)
             shutil.rmtree(account_path)
 
+    def save_notifications(self, account):
+        """
+        Save an account notifications
+
+        :param account: The account object to save
+        """
+        account_path = os.path.join(config.parameters['home'],
+                                account.name)
+        notifications_path = os.path.join(account_path, '__notifications__')
+        with open(notifications_path, 'w') as outfile:
+            json.dump(account.notifications, outfile, indent=4, sort_keys=True)
+
     def save_registries(self):
         """
         Save the registries
@@ -524,3 +535,5 @@ class Application(QObject):
                 self.version_requested.emit()
         except (aiohttp.errors.ClientError, aiohttp.errors.TimeoutError) as e:
             logging.debug("Could not connect to github : {0}".format(str(e)))
+        except Exception as e:
+            pass
diff --git a/src/sakia/core/community.py b/src/sakia/core/community.py
index bc97eddeb913a1d9a7976a7e4c9772b4ef674204..cbc86b64e31cc79f449a7aa8ecd38924a411ccc6 100644
--- a/src/sakia/core/community.py
+++ b/src/sakia/core/community.py
@@ -57,28 +57,19 @@ class Community(QObject):
         return community
 
     @classmethod
-    def load(cls, json_data):
+    def load(cls, json_data, file_version):
         """
         Load a community from json
 
         :param dict json_data: The community as a dict in json format
+        :param distutils.version.StrictVersion file_version: the file sakia version
         """
         currency = json_data['currency']
-        network = Network.from_json(currency, json_data['peers'])
+        network = Network.from_json(currency, json_data['peers'], file_version)
         bma_access = BmaAccess.create(network)
         community = cls(currency, network, bma_access)
         return community
 
-    def load_cache(self, bma_access_cache, network_cache):
-        """
-        Load the community cache.
-
-        :param dict bma_access_cache: The BmaAccess cache in json
-        :param dict network_cache: The network cache in json
-        """
-        self._bma_access.load_from_json(bma_access_cache)
-        self._network.merge_with_json(network_cache)
-
     @property
     def name(self):
         """
@@ -116,13 +107,16 @@ class Community(QObject):
         u = ord('\u24B6') + ord(letter) - ord('A')
         return chr(u)
 
-    async def dividend(self):
+    async def dividend(self, block_number=None):
         """
-        Get the last generated community universal dividend.
+        Get the last generated community universal dividend before block_number.
+        If block_number is None, returns the last block_number.
+
+        :param int block_number: The block at which we get the latest dividend
 
         :return: The last UD or 1 if no UD was generated.
         """
-        block = await self.get_ud_block()
+        block = await self.get_ud_block(block_number=block_number)
         if block:
             return block['dividend']
         else:
@@ -152,18 +146,24 @@ class Community(QObject):
         else:
             return 1
 
-    async def get_ud_block(self, x=0):
+    async def get_ud_block(self, x=0, block_number=None):
         """
         Get a block with universal dividend
+        If x and block_number are passed to the result,
+        it returns the 'x' older block with UD in it BEFORE block_number
 
         :param int x: Get the 'x' older block with UD in it
+        :param int block_number: Get the latest dividend before this block number
         :return: The last block with universal dividend.
+        :rtype: dict
         """
         try:
             udblocks = await self.bma_access.future_request(bma.blockchain.UD)
             blocks = udblocks['result']['blocks']
+            if block_number:
+                blocks = [b for b in blocks if b <= block_number]
             if len(blocks) > 0:
-                index = len(blocks)-(1+x)
+                index = len(blocks) - (1+x)
                 if index < 0:
                     index = 0
                 block_number = blocks[index]
diff --git a/src/sakia/core/money/__init__.py b/src/sakia/core/money/__init__.py
index 05a4b506a6ff4f03c503992f6cae11774a6a4ab1..21b04a8f501cfb26ba65419a6e3590b5d54bb331 100644
--- a/src/sakia/core/money/__init__.py
+++ b/src/sakia/core/money/__init__.py
@@ -2,5 +2,6 @@ from .quantitative import Quantitative
 from .relative import Relative
 from .quant_zerosum import QuantitativeZSum
 from .relative_zerosum import RelativeZSum
+from .relative_to_past import RelativeToPast
 
-Referentials = (Quantitative, Relative, QuantitativeZSum, RelativeZSum)
+Referentials = (Quantitative, Relative, QuantitativeZSum, RelativeZSum, RelativeToPast)
diff --git a/src/sakia/core/money/base_referential.py b/src/sakia/core/money/base_referential.py
new file mode 100644
index 0000000000000000000000000000000000000000..4040074b7695f74c10cd3d464da2cb4fbe3bed37
--- /dev/null
+++ b/src/sakia/core/money/base_referential.py
@@ -0,0 +1,41 @@
+from PyQt5.QtCore import QCoreApplication, QT_TRANSLATE_NOOP, QObject, QLocale
+import asyncio
+
+
+class BaseReferential:
+    """
+    Interface to all referentials
+    """
+    def __init__(self, amount, community, app, block_number=None):
+        self.amount = amount
+        self.community = community
+        self.app = app
+        self._block_number = block_number
+
+    @classmethod
+    def translated_name(self):
+        pass
+
+    @property
+    def units(self):
+        pass
+
+    @property
+    def diff_units(self):
+        pass
+
+    async def value(self):
+        pass
+
+    async def differential(self):
+        pass
+
+    @staticmethod
+    def to_si(value, digits):
+        pass
+
+    async def localized(self, units=False, international_system=False):
+        pass
+
+    async def diff_localized(self, units=False, international_system=False):
+        pass
diff --git a/src/sakia/core/money/quant_zerosum.py b/src/sakia/core/money/quant_zerosum.py
index 2c63322514e1d69c2952869965da43c8d61ab421..98f1f1c26569db4de65c5c729e314d31d4b5ef9e 100644
--- a/src/sakia/core/money/quant_zerosum.py
+++ b/src/sakia/core/money/quant_zerosum.py
@@ -1,29 +1,27 @@
 from PyQt5.QtCore import QCoreApplication, QT_TRANSLATE_NOOP, QLocale
 from . import Quantitative
-import asyncio
+from .base_referential import BaseReferential
 
 
-class QuantitativeZSum:
+class QuantitativeZSum(BaseReferential):
     _NAME_STR_ = QT_TRANSLATE_NOOP('QuantitativeZSum', 'Quant Z-sum')
-    _REF_STR_ = QT_TRANSLATE_NOOP('QuantitativeZSum', "{0} Q0 {1}")
+    _REF_STR_ = QT_TRANSLATE_NOOP('QuantitativeZSum', "{0} {1}Q0 {2}")
     _UNITS_STR_ = QT_TRANSLATE_NOOP('QuantitativeZSum', "Q0 {0}")
 
-    def __init__(self, amount, community, app):
-        self.amount = amount
-        self.community = community
-        self.app = app
+    def __init__(self, amount, community, app, block_number=None):
+        super().__init__(amount, community, app, block_number)
 
     @classmethod
     def translated_name(cls):
         return QCoreApplication.translate('QuantitativeZSum', QuantitativeZSum._NAME_STR_)
 
-    @classmethod
-    def units(cls, currency):
-        return QCoreApplication.translate("QuantitativeZSum", QuantitativeZSum._UNITS_STR_).format(currency)
+    @property
+    def units(self):
+        return QCoreApplication.translate("QuantitativeZSum", QuantitativeZSum._UNITS_STR_).format(self.community.short_currency)
 
-    @classmethod
-    def diff_units(cls, currency):
-        return Quantitative.units(currency)
+    @property
+    def diff_units(self):
+        return self.units
 
     async def value(self):
         """
@@ -43,7 +41,7 @@ class QuantitativeZSum:
         ud_block = await self.community.get_ud_block()
         if ud_block and ud_block['membersCount'] > 0:
             monetary_mass = await self.community.monetary_mass()
-            average = monetary_mass / ud_block['membersCount']
+            average = int(monetary_mass / ud_block['membersCount'])
         else:
             average = 0
         return self.amount - average
@@ -60,10 +58,11 @@ class QuantitativeZSum:
         else:
             localized_value = QLocale().toString(float(value), 'f', 0)
 
-        if units:
+        if units or international_system:
             return QCoreApplication.translate("QuantitativeZSum",
                                               QuantitativeZSum._REF_STR_) \
                 .format(localized_value,
+                        prefix,
                         self.community.short_currency if units else "")
         else:
             return localized_value
diff --git a/src/sakia/core/money/quantitative.py b/src/sakia/core/money/quantitative.py
index 811ff8f0c9cd2473410576f7d513f5ce176373ca..d1d07c151059c58ed1336fcf0da2b981c5b6666e 100644
--- a/src/sakia/core/money/quantitative.py
+++ b/src/sakia/core/money/quantitative.py
@@ -1,28 +1,26 @@
-from PyQt5.QtCore import QCoreApplication, QT_TRANSLATE_NOOP, QObject, QLocale
-import asyncio
+from PyQt5.QtCore import QCoreApplication, QT_TRANSLATE_NOOP, QLocale
+from .base_referential import BaseReferential
 
 
-class Quantitative():
+class Quantitative(BaseReferential):
     _NAME_STR_ = QT_TRANSLATE_NOOP('Quantitative', 'Units')
     _REF_STR_ = QT_TRANSLATE_NOOP('Quantitative', "{0} {1}{2}")
     _UNITS_STR_ = QT_TRANSLATE_NOOP('Quantitative', "{0}")
 
-    def __init__(self, amount, community, app):
-        self.amount = amount
-        self.community = community
-        self.app = app
+    def __init__(self, amount, community, app, block_number=None):
+        super().__init__(amount, community, app, block_number)
 
     @classmethod
     def translated_name(cls):
         return QCoreApplication.translate('Quantitative', Quantitative._NAME_STR_)
 
-    @classmethod
-    def units(cls, currency):
-        return QCoreApplication.translate("Quantitative", Quantitative._UNITS_STR_).format(currency)
+    @property
+    def units(self):
+        return QCoreApplication.translate("Quantitative", Quantitative._UNITS_STR_).format(self.community.short_currency)
 
-    @classmethod
-    def diff_units(cls, currency):
-        return Quantitative.units(currency)
+    @property
+    def diff_units(self):
+        return self.units
 
     async def value(self):
         """
diff --git a/src/sakia/core/money/relative.py b/src/sakia/core/money/relative.py
index 29b7d3f0d001d87a8d75b1341df748b0adff35d7..a757b762a1166bd1081c8773e6bd7d2dfecc1285 100644
--- a/src/sakia/core/money/relative.py
+++ b/src/sakia/core/money/relative.py
@@ -1,28 +1,26 @@
 from PyQt5.QtCore import QObject, QCoreApplication, QT_TRANSLATE_NOOP, QLocale
-import asyncio
+from .base_referential import BaseReferential
 
 
-class Relative:
+class Relative(BaseReferential):
     _NAME_STR_ = QT_TRANSLATE_NOOP('Relative', 'UD')
     _REF_STR_ = QT_TRANSLATE_NOOP('Relative',  "{0} {1}UD {2}")
     _UNITS_STR_ = QT_TRANSLATE_NOOP('Relative',  "UD {0}")
 
-    def __init__(self, amount, community, app):
-        self.amount = amount
-        self.community = community
-        self.app = app
+    def __init__(self, amount, community, app, block_number=None):
+        super().__init__(amount, community, app, block_number)
 
     @classmethod
     def translated_name(cls):
         return QCoreApplication.translate('Relative', Relative._NAME_STR_)
 
-    @classmethod
-    def units(self, currency):
-        return QCoreApplication.translate("Relative", Relative._UNITS_STR_).format(currency)
+    @property
+    def units(self):
+        return QCoreApplication.translate("Relative", Relative._UNITS_STR_).format(self.community.short_currency)
 
-    @classmethod
-    def diff_units(self, currency):
-        return self.units(currency)
+    @property
+    def diff_units(self):
+        return self.units
 
     async def value(self):
         """
@@ -42,7 +40,7 @@ class Relative:
 
     @staticmethod
     def to_si(value, digits):
-        prefixes = ['', 'd', 'c', 'm', 'µ', 'n', 'p', 'f', 'a', 'z', 'y']
+        prefixes = ['', 'm', 'µ', 'n', 'p', 'f', 'a', 'z', 'y']
         if value < 0:
             value = -value
             multiplier = -1
@@ -53,10 +51,7 @@ class Relative:
         prefix = ""
 
         while int(scientific_value) == 0 and scientific_value > 0.0:
-            if prefix_index > 3:
-                scientific_value *= 1000
-            else:
-                scientific_value *= 10
+            scientific_value *= 1000
             prefix_index += 1
 
         if prefix_index < len(prefixes):
diff --git a/src/sakia/core/money/relative_to_past.py b/src/sakia/core/money/relative_to_past.py
new file mode 100644
index 0000000000000000000000000000000000000000..8fdae53c34b54ec1aa3b136ac2219936b945494c
--- /dev/null
+++ b/src/sakia/core/money/relative_to_past.py
@@ -0,0 +1,91 @@
+from PyQt5.QtCore import QObject, QCoreApplication, QT_TRANSLATE_NOOP, QLocale, QDateTime
+from .base_referential import BaseReferential
+from . import Relative
+
+
+class RelativeToPast(BaseReferential):
+    _NAME_STR_ = QT_TRANSLATE_NOOP('RelativeToPast', 'Past UD')
+    _REF_STR_ = QT_TRANSLATE_NOOP('RelativeToPast', "{0} {1}UD({2}) {3}")
+    _UNITS_STR_ = QT_TRANSLATE_NOOP('RelativeToPast', "UD({0}) {1}")
+
+    def __init__(self, amount, community, app, block_number=None):
+        super().__init__(amount, community, app, block_number)
+
+    @classmethod
+    def translated_name(cls):
+        return QCoreApplication.translate('RelativeToPast', RelativeToPast._NAME_STR_)
+
+    @property
+    def units(self):
+        return QCoreApplication.translate("RelativeToPast", RelativeToPast._UNITS_STR_).format('t',
+                                                                                               self.community.short_currency)
+
+    @property
+    def diff_units(self):
+        return self.units
+
+    async def value(self):
+        """
+        Return relative to past value of amount
+        :return: float
+        """
+        dividend = await self.community.dividend()
+        if dividend > 0:
+            return self.amount / float(dividend)
+        else:
+            return self.amount
+
+    async def differential(self):
+        """
+        Return relative to past differential value of amount
+        :return: float
+        """
+        dividend = await self.community.dividend(self._block_number)
+        if dividend > 0:
+            return self.amount / float(dividend)
+        else:
+            return self.amount
+
+    async def localized(self, units=False, international_system=False):
+        value = await self.value()
+        block = await self.community.get_block()
+        prefix = ""
+        if international_system:
+            localized_value, prefix = Relative.to_si(value, self.app.preferences['digits_after_comma'])
+        else:
+            localized_value = QLocale().toString(float(value), 'f', self.app.preferences['digits_after_comma'])
+
+        if units or international_system:
+            return QCoreApplication.translate("RelativeToPast", RelativeToPast._REF_STR_) \
+                .format(localized_value,
+                        prefix,
+                        QLocale.toString(
+                            QLocale(),
+                            QDateTime.fromTime_t(block['medianTime']).date(),
+                            QLocale.dateFormat(QLocale(), QLocale.ShortFormat)
+                        ),
+                        self.community.short_currency if units else "")
+        else:
+            return localized_value
+
+    async def diff_localized(self, units=False, international_system=False):
+        value = await self.differential()
+        block = await self.community.get_block(self._block_number)
+        prefix = ""
+        if international_system and value != 0:
+            localized_value, prefix = Relative.to_si(value, self.app.preferences['digits_after_comma'])
+        else:
+            localized_value = QLocale().toString(float(value), 'f', self.app.preferences['digits_after_comma'])
+
+        if units or international_system:
+            return QCoreApplication.translate("RelativeToPast", RelativeToPast._REF_STR_)\
+                .format(localized_value,
+                    prefix,
+                    QLocale.toString(
+                        QLocale(),
+                        QDateTime.fromTime_t(block['medianTime']).date(),
+                        QLocale.dateFormat(QLocale(), QLocale.ShortFormat)
+                    ),
+                    self.community.short_currency if units else "")
+        else:
+            return localized_value
diff --git a/src/sakia/core/money/relative_zerosum.py b/src/sakia/core/money/relative_zerosum.py
index 5a6b823985ec04ade40327397fffe1337c2df790..797f7cb4d80fa78622c2b76b9a909b8702267b79 100644
--- a/src/sakia/core/money/relative_zerosum.py
+++ b/src/sakia/core/money/relative_zerosum.py
@@ -1,29 +1,27 @@
 from PyQt5.QtCore import QCoreApplication, QT_TRANSLATE_NOOP, QLocale
 from .relative import Relative
-import asyncio
+from .base_referential import BaseReferential
 
 
-class RelativeZSum:
+class RelativeZSum(BaseReferential):
     _NAME_STR_ = QT_TRANSLATE_NOOP('RelativeZSum', 'Relat Z-sum')
-    _REF_STR_ = QT_TRANSLATE_NOOP('RelativeZSum', "{0} R0 {1}")
+    _REF_STR_ = QT_TRANSLATE_NOOP('RelativeZSum', "{0} {1}R0 {2}")
     _UNITS_STR_ = QT_TRANSLATE_NOOP('RelativeZSum', "R0 {0}")
 
-    def __init__(self, amount, community, app):
-        self.amount = amount
-        self.community = community
-        self.app = app
+    def __init__(self, amount, community, app, block_number=None):
+        super().__init__(amount, community, app, block_number)
 
     @classmethod
     def translated_name(cls):
         return QCoreApplication.translate('RelativeZSum', RelativeZSum._NAME_STR_)
 
-    @classmethod
-    def units(cls, currency):
-        return QCoreApplication.translate("RelativeZSum", RelativeZSum._UNITS_STR_).format(currency)
+    @property
+    def units(self):
+        return QCoreApplication.translate("RelativeZSum", RelativeZSum._UNITS_STR_).format(self.community.short_currency)
 
-    @classmethod
-    def diff_units(cls, currency):
-        return Relative.units(currency)
+    @property
+    def diff_units(self):
+        return self.units
 
     async def value(self):
         """
@@ -41,7 +39,7 @@ class RelativeZSum:
         :return: float
         """
         ud_block = await self.community.get_ud_block()
-        ud_block_minus_1 = await self.community.get_ud_block(1)
+        ud_block_minus_1 = await self.community.get_ud_block(x=1)
         if ud_block_minus_1 and ud_block['membersCount'] > 0:
             median = ud_block_minus_1['monetaryMass'] / ud_block['membersCount']
             relative_value = self.amount / float(ud_block['dividend'])
@@ -63,9 +61,10 @@ class RelativeZSum:
         else:
             localized_value = QLocale().toString(float(value), 'f', self.app.preferences['digits_after_comma'])
 
-        if units:
+        if units or international_system:
             return QCoreApplication.translate("RelativeZSum", RelativeZSum._REF_STR_)\
                 .format(localized_value,
+                        prefix,
                         self.community.short_currency if units else "")
         else:
             return localized_value
@@ -79,8 +78,8 @@ class RelativeZSum:
         else:
             localized_value = QLocale().toString(float(value), 'f', self.app.preferences['digits_after_comma'])
 
-        if units:
+        if units or international_system:
             return QCoreApplication.translate("RelativeZSum", RelativeZSum._REF_STR_)\
-                .format(localized_value, self.community.short_currency if units else "")
+                .format(localized_value, prefix, self.community.short_currency if units else "")
         else:
             return localized_value
diff --git a/src/sakia/core/net/api/bma/access.py b/src/sakia/core/net/api/bma/access.py
index f6d645e0654bb49e83a9d06ca12512a7def01d16..409380126cbf5cada8504519fe0f96f41277bb20 100644
--- a/src/sakia/core/net/api/bma/access.py
+++ b/src/sakia/core/net/api/bma/access.py
@@ -1,5 +1,4 @@
 from PyQt5.QtCore import QObject, pyqtSlot
-from PyQt5.QtNetwork import QNetworkReply
 from ucoinpy.api import bma
 from .....tools.exceptions import NoPeerAvailable
 from ..... import __version__
@@ -259,7 +258,7 @@ class BmaAccess(QObject):
         :param class request: A bma request class calling for data
         :param dict req_args: Arguments to pass to the request constructor
         :param dict get_args: Arguments to pass to the request __get__ method
-        :return: The returned data if cached = True else return the QNetworkReply
+        :return: The returned data
         """
         nodes = self.filter_nodes(request, self._network.synced_nodes)
         if len(nodes) > 0:
@@ -293,12 +292,14 @@ class BmaAccess(QObject):
         :param req_args: Arguments to pass to the request constructor
         :param post_args: Arguments to pass to the request __post__ method
         :return: All nodes replies
-        :rtype: tuple of QNetworkReply
+        :rtype: tuple of aiohttp replies
 
         .. note:: If one node accept the requests (returns 200),
         the broadcast should be considered accepted by the network.
         """
-        nodes = self._network.online_nodes
+        nodes = random.sample(self._network.synced_nodes, 6) \
+            if len(self._network.synced_nodes) > 6 \
+            else self._network.synced_nodes
         replies = []
         if len(nodes) > 0:
             for node in nodes:
diff --git a/src/sakia/core/net/network.py b/src/sakia/core/net/network.py
index eeb9d3a50c4b70420f53898ad0091e188d4028c8..4ba45bff087dddbe73a8d167f7854003cf43e1d9 100644
--- a/src/sakia/core/net/network.py
+++ b/src/sakia/core/net/network.py
@@ -57,15 +57,16 @@ class Network(QObject):
         network = cls(node.currency, nodes)
         return network
 
-    def merge_with_json(self, json_data):
+    def merge_with_json(self, json_data, file_version):
         """
         We merge with knew nodes when we
         last stopped sakia
 
         :param dict json_data: Nodes in json format
+        :param distutils.version.StrictVersion file_version: The node version
         """
         for data in json_data:
-            node = Node.from_json(self.currency, data)
+            node = Node.from_json(self.currency, data, file_version)
             if node.pubkey not in [n.pubkey for n in self.nodes]:
                 self.add_node(node)
                 logging.debug("Loading : {:}".format(data['pubkey']))
@@ -74,6 +75,7 @@ class Network(QObject):
                 other_node._uid = node.uid
                 other_node._version = node.version
                 other_node._software = node.software
+                other_node._peer = node.peer
                 switch = False
                 if other_node.block and node.block:
                     if other_node.block['hash'] != node.block['hash']:
@@ -86,16 +88,17 @@ class Network(QObject):
                     other_node.state = node.state
 
     @classmethod
-    def from_json(cls, currency, json_data):
+    def from_json(cls, currency, json_data, file_version):
         """
         Load a network from a configured community
 
         :param str currency: The currency name of a community
         :param dict json_data: A json_data view of a network
+        :param distutils.version.StrictVersion file_version: the version of the json file
         """
         nodes = []
         for data in json_data:
-            node = Node.from_json(currency, data)
+            node = Node.from_json(currency, data, file_version)
             nodes.append(node)
         network = cls(currency, nodes)
         return network
@@ -340,6 +343,10 @@ class Network(QObject):
                 self.nodes_changed.emit()
             except InvalidNodeCurrency as e:
                 logging.debug(str(e))
+        else:
+            node = [n for n in self.nodes if n.pubkey == pubkey][0]
+            if BlockId.from_str(node.peer.blockid).number < BlockId.from_str(peer.blockid).number:
+                node.peer = peer
 
     @pyqtSlot()
     def handle_identity_change(self):
diff --git a/src/sakia/core/net/node.py b/src/sakia/core/net/node.py
index 80983ec5f922fb9f65dc92f984c235a622947509..37fdce2275e2cc1378d1cb5626b5dd9c44f24099 100644
--- a/src/sakia/core/net/node.py
+++ b/src/sakia/core/net/node.py
@@ -5,6 +5,7 @@ Created on 21 févr. 2015
 """
 
 from ucoinpy.documents.peer import Peer, Endpoint, BMAEndpoint
+from ucoinpy.documents import Block, BlockId
 from ...tools.exceptions import InvalidNodeCurrency
 from ...tools.decorators import asyncify
 from ucoinpy.api import bma as bma
@@ -12,11 +13,14 @@ from ucoinpy.api.bma import ConnectionHandler
 
 from aiohttp.errors import ClientError, DisconnectedError, TimeoutError, \
     WSClientDisconnectedError, WSServerHandshakeError, ClientResponseError
+from aiohttp.errors import ClientError, DisconnectedError
+from asyncio import TimeoutError
 import logging
 import time
 import jsonschema
 import asyncio
 import aiohttp
+from distutils.version import StrictVersion
 from socket import gaierror
 
 from PyQt5.QtCore import QObject, pyqtSignal
@@ -42,26 +46,27 @@ class Node(QObject):
     identity_changed = pyqtSignal()
     neighbour_found = pyqtSignal(Peer, str)
 
-    def __init__(self, currency, endpoints, uid, pubkey, block,
+    def __init__(self, peer, uid, pubkey, block,
                  state, last_change, last_merkle, software, version, fork_window):
         """
         Constructor
         """
         super().__init__()
-        self._endpoints = endpoints
+        self._peer = peer
         self._uid = uid
         self._pubkey = pubkey
         self._block = block
         self.main_chain_previous_block = None
         self._state = state
         self._neighbours = []
-        self._currency = currency
         self._last_change = last_change
         self._last_merkle = last_merkle
         self._software = software
         self._version = version
         self._fork_window = fork_window
         self._refresh_counter = 0
+        self._ws_opened = {'block': False,
+                           'peer': False}
 
     @classmethod
     async def from_address(cls, currency, address, port):
@@ -84,8 +89,7 @@ class Node(QObject):
             if peer.currency != currency:
                 raise InvalidNodeCurrency(peer.currency, currency)
 
-        node = cls(peer.currency,
-                   [Endpoint.from_inline(e.inline()) for e in peer.endpoints],
+        node = cls(peer,
                    "", peer.pubkey, None, Node.ONLINE, time.time(),
                    {'root': "", 'leaves': []}, "", "", 0)
         logging.debug("Node from address : {:}".format(str(node)))
@@ -106,8 +110,7 @@ class Node(QObject):
             if peer.currency != currency:
                 raise InvalidNodeCurrency(peer.currency, currency)
 
-        node = cls(peer.currency, peer.endpoints,
-                   "", pubkey, None,
+        node = cls(peer, "", pubkey, None,
                    Node.OFFLINE, time.time(),
                    {'root': "", 'leaves': []},
                    "", "", 0)
@@ -115,7 +118,16 @@ class Node(QObject):
         return node
 
     @classmethod
-    def from_json(cls, currency, data):
+    def from_json(cls, currency, data, file_version):
+        """
+        Loads a node from json data
+
+        :param str currency: the currency of the community
+        :param dict data: the json data of the node
+        :param StrictVersion file_version: the version of the file
+        :return: A new node
+        :rtype: Node
+        """
         endpoints = []
         uid = ""
         pubkey = ""
@@ -126,12 +138,6 @@ class Node(QObject):
         last_change = time.time()
         state = Node.OFFLINE
         logging.debug(data)
-        for endpoint_data in data['endpoints']:
-            endpoints.append(Endpoint.from_inline(endpoint_data))
-
-        if currency in data:
-            currency = data['currency']
-
         if 'uid' in data:
             uid = data['uid']
 
@@ -156,11 +162,23 @@ class Node(QObject):
         if 'fork_window' in data:
             fork_window = data['fork_window']
 
-        node = cls(currency, endpoints,
-                   uid, pubkey, block,
+        if file_version < StrictVersion("0.12"):
+            for endpoint_data in data['endpoints']:
+                endpoints.append(Endpoint.from_inline(endpoint_data))
+
+            if currency in data:
+                currency = data['currency']
+
+            peer = Peer("1", currency, pubkey, str(BlockId(0, Block.Empty_Hash)), endpoints, "SOMEFAKESIGNATURE")
+        else:
+            if 'peer' in data:
+                peer = Peer.from_signed_raw(data['peer'])
+
+        node = cls(peer, uid, pubkey, block,
                    state, last_change,
                    {'root': "", 'leaves': []},
                    software, version, fork_window)
+
         logging.debug("Node from json : {:}".format(str(node)))
         return node
 
@@ -168,18 +186,14 @@ class Node(QObject):
         logging.debug("Saving root node : {:}".format(str(self)))
         data = {'pubkey': self._pubkey,
                 'uid': self._uid,
-                'currency': self._currency}
-        endpoints = []
-        for e in self._endpoints:
-            endpoints.append(e.inline())
-        data['endpoints'] = endpoints
+                'peer': self._peer.signed_raw()}
         return data
 
     def jsonify(self):
         logging.debug("Saving node : {:}".format(str(self)))
         data = {'pubkey': self._pubkey,
                 'uid': self._uid,
-                'currency': self._currency,
+                'peer': self._peer.signed_raw(),
                 'state': self._state,
                 'last_change': self._last_change,
                 'block': self.block,
@@ -187,10 +201,6 @@ class Node(QObject):
                 'version': self._version,
                 'fork_window': self._fork_window
                 }
-        endpoints = []
-        for e in self._endpoints:
-            endpoints.append(e.inline())
-        data['endpoints'] = endpoints
         return data
 
     @property
@@ -199,7 +209,7 @@ class Node(QObject):
 
     @property
     def endpoint(self) -> BMAEndpoint:
-        return next((e for e in self._endpoints if type(e) is BMAEndpoint))
+        return next((e for e in self._peer.endpoints if type(e) is BMAEndpoint))
 
     @property
     def block(self):
@@ -214,7 +224,7 @@ class Node(QObject):
 
     @property
     def currency(self):
-        return self._currency
+        return self._peer.currency
 
     @property
     def neighbours(self):
@@ -232,6 +242,16 @@ class Node(QObject):
     def software(self):
         return self._software
 
+    @property
+    def peer(self):
+        return self._peer
+
+    @peer.setter
+    def peer(self, new_peer):
+        if self._peer != new_peer:
+            self._peer = new_peer
+            self.changed.emit()
+
     @software.setter
     def software(self, new_soft):
         if self._software != new_soft:
@@ -260,8 +280,6 @@ class Node(QObject):
         #                                                               self.state, new_state))
 
         if self._state != new_state:
-            if self.pubkey[:5] in ("6YfbK", "J78bP"):
-                pass
             self.last_change = time.time()
             self._state = new_state
             self.changed.emit()
@@ -283,7 +301,7 @@ class Node(QObject):
         Refresh all data of this node
         :param bool manual: True if the refresh was manually initiated
         """
-        asyncio.ensure_future(self.connect_current_block())
+        self.connect_current_block()
         self.refresh_peers()
 
         if self._refresh_counter % 20 == 0 or manual:
@@ -294,62 +312,41 @@ class Node(QObject):
         else:
             self._refresh_counter += 1
 
-    async def connect_current_block(self):
-        try:
-            conn_handler = self.endpoint.conn_handler()
-            async with bma.websocket.Block(conn_handler).connect() as ws:
-                async for msg in ws:
-                    if msg.tp == aiohttp.MsgType.text:
-                        pass
-                    elif msg.tp == aiohttp.MsgType.closed:
-                        break
-                    elif msg.tp == aiohttp.MsgType.error:
-                        break
-                    else:
-                        pass
-        except (WSServerHandshakeError, WSClientDisconnectedError) as e:
-            logging.debug("Websocket error : {0}".format(str(e)))
-        except ClientResponseError as e:
-            logging.debug("Client response error : {0}".format(str(e)))
-
-
     @asyncify
-    async def refresh_block(self):
+    async def connect_current_block(self):
         """
-        Refresh the blocks of this node
+        Connects to the websocket entry point of the node
+        If the connection fails, it tries the fallback mode on HTTP GET
+        """
+        if not self._ws_opened['block']:
+            try:
+                conn_handler = self.endpoint.conn_handler()
+                self._ws_opened['block'] = True
+                block_websocket = bma.websocket.Block(conn_handler)
+                async with block_websocket.connect() as ws:
+                    async for msg in ws:
+                        if msg.tp == aiohttp.MsgType.text:
+                            block_data = block_websocket.parse(msg.data)
+                            await self.refresh_block(block_data)
+                        elif msg.tp == aiohttp.MsgType.closed:
+                            break
+                        elif msg.tp == aiohttp.MsgType.error:
+                            break
+            except (WSServerHandshakeError, WSClientDisconnectedError, ClientResponseError) as e:
+                logging.debug("Websocket error : {0}".format(str(e)))
+                self.request_current_block()
+            finally:
+                self._ws_opened['block'] = False
+
+    async def request_current_block(self):
+        """
+        Request a node on the HTTP GET interface
+        If an error occurs, the node is considered offline
         """
-        conn_handler = self.endpoint.conn_handler()
-
-        logging.debug("Requesting {0}".format(conn_handler))
         try:
+            conn_handler = self.endpoint.conn_handler()
             block_data = await bma.blockchain.Current(conn_handler).get()
-            block_hash = block_data['hash']
-            self.state = Node.ONLINE
-
-            if not self.block or block_hash != self.block['hash']:
-                try:
-                    if self.block:
-                        self.main_chain_previous_block = await bma.blockchain.Block(conn_handler,
-                                                                                     self.block['number']).get()
-                except ValueError as e:
-                    if '404' in str(e):
-                        self.main_chain_previous_block = None
-                    else:
-                        self.state = Node.OFFLINE
-                    logging.debug("Error in previous block reply :  {0}".format(self.pubkey))
-                    logging.debug(str(e))
-                    self.changed.emit()
-                except (ClientError, gaierror, TimeoutError, DisconnectedError) as e:
-                    logging.debug("{0} : {1}".format(str(e), self.pubkey))
-                    self.state = Node.OFFLINE
-                except jsonschema.ValidationError:
-                    logging.debug("Validation error : {0}".format(self.pubkey))
-                    self.state = Node.CORRUPTED
-                finally:
-                    self.set_block(block_data)
-                    logging.debug("Changed block {0} -> {1}".format(self.block['number'],
-                                                                    block_data['number']))
-                    self.changed.emit()
+            await self.refresh_block(block_data)
         except ValueError as e:
             if '404' in str(e):
                 self.main_chain_previous_block = None
@@ -366,6 +363,42 @@ class Node(QObject):
             logging.debug("Validation error : {0}".format(self.pubkey))
             self.state = Node.CORRUPTED
 
+    async def refresh_block(self, block_data):
+        """
+        Refresh the blocks of this node
+        :param dict block_data: The block data in json format
+        """
+        conn_handler = self.endpoint.conn_handler()
+
+        logging.debug("Requesting {0}".format(conn_handler))
+        block_hash = block_data['hash']
+        self.state = Node.ONLINE
+
+        if not self.block or block_hash != self.block['hash']:
+            try:
+                if self.block:
+                    self.main_chain_previous_block = await bma.blockchain.Block(conn_handler,
+                                                                                 self.block['number']).get()
+            except ValueError as e:
+                if '404' in str(e):
+                    self.main_chain_previous_block = None
+                else:
+                    self.state = Node.OFFLINE
+                logging.debug("Error in previous block reply :  {0}".format(self.pubkey))
+                logging.debug(str(e))
+                self.changed.emit()
+            except (ClientError, gaierror, TimeoutError, DisconnectedError) as e:
+                logging.debug("{0} : {1}".format(str(e), self.pubkey))
+                self.state = Node.OFFLINE
+            except jsonschema.ValidationError:
+                logging.debug("Validation error : {0}".format(self.pubkey))
+                self.state = Node.CORRUPTED
+            finally:
+                self.set_block(block_data)
+                logging.debug("Changed block {0} -> {1}".format(self.block['number'],
+                                                                block_data['number']))
+                self.changed.emit()
+
     @asyncify
     async def refresh_informations(self):
         """
@@ -379,6 +412,11 @@ class Node(QObject):
             node_currency = peering_data["currency"]
             self.state = Node.ONLINE
 
+            if peering_data['raw'] != self.peer.raw():
+                peer = Peer.from_signed_raw("{0}{1}\n".format(peering_data['raw'], peering_data['signature']))
+                if BlockId.from_str(peer.blockid).number > BlockId.from_str(self.peer.blockid).number:
+                    self.peer = Peer.from_signed_raw("{0}{1}\n".format(peering_data['raw'], peering_data['signature']))
+
             if node_pubkey != self.pubkey:
                 self._pubkey = node_pubkey
                 self.identity_changed.emit()
@@ -393,7 +431,7 @@ class Node(QObject):
             self.state = Node.OFFLINE
             self.changed.emit()
         except (ClientError, gaierror, TimeoutError, DisconnectedError) as e:
-            logging.debug("{0} : {1}".format(str(e), self.pubkey))
+            logging.debug("{0} : {1}".format(type(e).__name__, self.pubkey))
             self.state = Node.OFFLINE
         except jsonschema.ValidationError:
             logging.debug("Validation error : {0}".format(self.pubkey))
@@ -420,7 +458,7 @@ class Node(QObject):
             self.state = Node.OFFLINE
             self.changed.emit()
         except (ClientError, gaierror, TimeoutError, DisconnectedError) as e:
-            logging.debug("{0} : {1}".format(str(e), self.pubkey))
+            logging.debug("{0} : {1}".format(type(e).__name__, self.pubkey))
             self.state = Node.OFFLINE
         except jsonschema.ValidationError:
             logging.debug("Validation error : {0}".format(self.pubkey))
@@ -455,7 +493,7 @@ class Node(QObject):
                 self.state = Node.OFFLINE
                 self.identity_changed.emit()
         except (ClientError, gaierror, TimeoutError, DisconnectedError) as e:
-            logging.debug("{0} : {1}".format(str(e), self.pubkey))
+            logging.debug("{0} : {1}".format(type(e).__name__, self.pubkey))
             self.state = Node.OFFLINE
         except jsonschema.ValidationError:
             logging.debug("Validation error : {0}".format(self.pubkey))
@@ -491,7 +529,7 @@ class Node(QObject):
                         self.state = Node.OFFLINE
                         self.changed.emit()
                     except (ClientError, gaierror, TimeoutError, DisconnectedError) as e:
-                        logging.debug("{0} : {1}".format(str(e), self.pubkey))
+                        logging.debug("{0} : {1}".format(type(e).__name__, self.pubkey))
                         self.state = Node.OFFLINE
                     except jsonschema.ValidationError:
                         logging.debug("Validation error : {0}".format(self.pubkey))
@@ -503,7 +541,7 @@ class Node(QObject):
             self.state = Node.OFFLINE
             self.changed.emit()
         except (ClientError, gaierror, TimeoutError, DisconnectedError) as e:
-            logging.debug("{0} : {1}".format(str(e), self.pubkey))
+            logging.debug("{0} : {1}".format(type(e).__name__, self.pubkey))
             self.state = Node.OFFLINE
         except jsonschema.ValidationError:
             logging.debug("Validation error : {0}".format(self.pubkey))
diff --git a/src/sakia/core/registry/identities.py b/src/sakia/core/registry/identities.py
index bb2608e906e0e2277c22e80da3320d5d031e1d13..8ef736f2ead3abbbc9caff83b9c21c6f1f494651 100644
--- a/src/sakia/core/registry/identities.py
+++ b/src/sakia/core/registry/identities.py
@@ -1,4 +1,3 @@
-from PyQt5.QtNetwork import QNetworkReply, QNetworkRequest
 from ucoinpy.api import bma
 from .identity import Identity, LocalState, BlockchainState
 
diff --git a/src/sakia/core/transfer.py b/src/sakia/core/transfer.py
index 53d130111371bfb547180b3d6cf434365f569d5f..f86bb625ed444ed3671f5ef16eee2f9124dd3b9d 100644
--- a/src/sakia/core/transfer.py
+++ b/src/sakia/core/transfer.py
@@ -352,5 +352,16 @@ class Transfer(QObject):
             else:
                 await r.text()
         self.run_state_transitions(([r.status for r in responses], block_doc))
-        self.run_state_transitions(([r.status for r in responses]))
+        self.run_state_transitions(([r.status for r in responses], ))
         return result
+
+    async def get_raw_document(self, community):
+        """
+        Get the raw documents of this transfer
+        """
+        block = await community.get_block(self.blockid.number)
+        if block:
+            block_doc = Block.from_signed_raw("{0}{1}\n".format(block['raw'], block['signature']))
+            for tx in block_doc.transactions:
+                if tx.sha_hash == self.sha_hash:
+                    return tx
diff --git a/src/sakia/gui/certification.py b/src/sakia/gui/certification.py
index da2bbfba295e91475f53d1a45dcc6270f6b5abe8..4b847b300bf28b50e7a4356b38cfd87730d779a1 100644
--- a/src/sakia/gui/certification.py
+++ b/src/sakia/gui/certification.py
@@ -6,89 +6,174 @@ Created on 24 dec. 2014
 import asyncio
 import logging
 
-from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QApplication
+from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QApplication, QMessageBox
 
-from PyQt5.QtCore import Qt
+from PyQt5.QtCore import Qt, QObject
 
 from ..gen_resources.certification_uic import Ui_CertificationDialog
-from sakia.gui.widgets import toast
-from sakia.gui.widgets.dialogs import QAsyncMessageBox
+from .widgets import toast
+from .widgets.dialogs import QAsyncMessageBox
+from .member import MemberDialog
 from ..tools.decorators import asyncify, once_at_a_time
 from ..tools.exceptions import NoPeerAvailable
 
 
-class CertificationDialog(QDialog, Ui_CertificationDialog):
+class CertificationDialog(QObject):
     """
-    classdocs
+    A dialog to certify individuals
     """
 
-    def __init__(self, app, certifier, password_asker):
+    def __init__(self, app, account, password_asker, widget, ui):
         """
-        Constructor
+        Constructor if a certification dialog
+
+        :param sakia.core.Application app:
+        :param sakia.core.Account account:
+        :param sakia.gui.password_asker.PasswordAsker password_asker:
+        :param PyQt5.QtWidgets widget: the widget of the dialog
+        :param sakia.gen_resources.certification_uic.Ui_CertificationDialog view: the view of the certification dialog
+        :return:
         """
         super().__init__()
-        self.setupUi(self)
+        self.widget = widget
+        self.ui = ui
+        self.ui.setupUi(self.widget)
         self.app = app
-        self.account = certifier
+        self.account = account
         self.password_asker = password_asker
         self.community = self.account.communities[0]
 
+        self.ui.radio_contact.toggled.connect(lambda c, radio="contact": self.recipient_mode_changed(radio))
+        self.ui.radio_pubkey.toggled.connect(lambda c, radio="pubkey": self.recipient_mode_changed(radio))
+        self.ui.radio_search.toggled.connect(lambda c, radio="search": self.recipient_mode_changed(radio))
+        self.ui.button_box.accepted.connect(self.accept)
+        self.ui.button_box.rejected.connect(self.widget.reject)
+
         for community in self.account.communities:
-            self.combo_community.addItem(community.currency)
+            self.ui.combo_community.addItem(community.currency)
+
+        for contact_name in sorted([c['name'] for c in account.contacts], key=str.lower):
+            self.ui.combo_contact.addItem(contact_name)
+
+        if len(account.contacts) == 0:
+            self.ui.radio_pubkey.setChecked(True)
+            self.ui.radio_contact.setEnabled(False)
+
+        self.ui.member_widget = MemberDialog.as_widget(self.ui.groupBox, self.app, self.account, self.community, None)
+        self.ui.horizontalLayout_5.addWidget(self.ui.member_widget.widget)
+
+        self.ui.search_user.button_reset.hide()
+        self.ui.search_user.init(self.app)
+        self.ui.search_user.change_account(self.account)
+        self.ui.search_user.change_community(self.community)
+        self.ui.combo_contact.currentIndexChanged.connect(self.refresh_member)
+        self.ui.edit_pubkey.textChanged.connect(self.refresh_member)
+        self.ui.search_user.identity_selected.connect(self.refresh_member)
+        self.ui.radio_contact.toggled.connect(self.refresh_member)
+        self.ui.radio_search.toggled.connect(self.refresh_member)
+        self.ui.radio_pubkey.toggled.connect(self.refresh_member)
+        self.ui.combo_community.currentIndexChanged.connect(self.change_current_community)
 
-        for contact_name in sorted([c['name'] for c in certifier.contacts], key=str.lower):
-            self.combo_contact.addItem(contact_name)
-        if len(certifier.contacts) == 0:
-            self.radio_pubkey.setChecked(True)
-            self.radio_contact.setEnabled(False)
+    @classmethod
+    def open_dialog(cls, app, account, password_asker):
+        """
+        Certify and identity
+        :param sakia.core.Application app: the application
+        :param sakia.core.Account account: the account certifying the identity
+        :param sakia.gui.password_asker.PasswordAsker password_asker: the password asker
+        :return:
+        """
+        dialog = cls(app, account, password_asker, QDialog(), Ui_CertificationDialog())
+        return dialog.exec()
 
     @classmethod
     async def certify_identity(cls, app, account, password_asker, community, identity):
-        dialog = cls(app, account, password_asker)
-        dialog.combo_community.setCurrentText(community.name)
-        dialog.edit_pubkey.setText(identity.pubkey)
-        dialog.radio_pubkey.setChecked(True)
-        return (await dialog.async_exec())
+        """
+        Certify and identity
+        :param sakia.core.Application app: the application
+        :param sakia.core.Account account: the account certifying the identity
+        :param sakia.gui.password_asker.PasswordAsker password_asker: the password asker
+        :param sakia.core.Community community: the community
+        :param sakia.core.registry.Identity identity: the identity certified
+        :return:
+        """
+        dialog = cls(app, account, password_asker, QDialog(), Ui_CertificationDialog())
+        dialog.ui.combo_community.setCurrentText(community.name)
+        dialog.ui.edit_pubkey.setText(identity.pubkey)
+        dialog.ui.radio_pubkey.setChecked(True)
+        return await dialog.async_exec()
 
     @asyncify
     async def accept(self):
-        if self.radio_contact.isChecked():
-            for contact in self.account.contacts:
-                if contact['name'] == self.combo_contact.currentText():
-                    pubkey = contact['pubkey']
-                    break
-        else:
-            pubkey = self.edit_pubkey.text()
-
-        password = await self.password_asker.async_exec()
-        if password == "":
-            return
-        QApplication.setOverrideCursor(Qt.WaitCursor)
-        result = await self.account.certify(password, self.community, pubkey)
-        if result[0]:
-            if self.app.preferences['notifications']:
-                toast.display(self.tr("Certification"),
-                              self.tr("Success sending certification"))
-            else:
-                await QAsyncMessageBox.information(self, self.tr("Certification"),
-                                             self.tr("Success sending certification"))
-            QApplication.restoreOverrideCursor()
-            super().accept()
-        else:
-            if self.app.preferences['notifications']:
-                toast.display(self.tr("Certification"), self.tr("Could not broadcast certification : {0}"
-                                                                .format(result[1])))
+        """
+        Validate the dialog
+        """
+        pubkey = self.selected_pubkey()
+        if pubkey:
+            password = await self.password_asker.async_exec()
+            if password == "":
+                self.ui.button_box.setEnabled(True)
+                return
+            QApplication.setOverrideCursor(Qt.WaitCursor)
+            result = await self.account.certify(password, self.community, pubkey)
+            if result[0]:
+                if self.app.preferences['notifications']:
+                    toast.display(self.tr("Certification"),
+                                  self.tr("Success sending certification"))
+                else:
+                    await QAsyncMessageBox.information(self.widget, self.tr("Certification"),
+                                                 self.tr("Success sending certification"))
+                QApplication.restoreOverrideCursor()
+                self.widget.accept()
             else:
-                await QAsyncMessageBox.critical(self, self.tr("Certification"),
-                                          self.tr("Could not broadcast certification : {0}"
-                                                                .format(result[1])))
-            QApplication.restoreOverrideCursor()
+                if self.app.preferences['notifications']:
+                    toast.display(self.tr("Certification"), self.tr("Could not broadcast certification : {0}"
+                                                                    .format(result[1])))
+                else:
+                    await QAsyncMessageBox.critical(self.widget, self.tr("Certification"),
+                                              self.tr("Could not broadcast certification : {0}"
+                                                                    .format(result[1])))
+                QApplication.restoreOverrideCursor()
+                self.ui.button_box.setEnabled(True)
 
     def change_current_community(self, index):
         self.community = self.account.communities[index]
+        self.ui.search_user.change_community(self.community)
         if self.isVisible():
             self.refresh()
 
+    def selected_pubkey(self):
+        """
+        Get selected pubkey in the widgets of the window
+        :return: the current pubkey
+        :rtype: str
+        """
+        pubkey = None
+        if self.ui.radio_contact.isChecked():
+            for contact in self.account.contacts:
+                if contact['name'] == self.ui.combo_contact.currentText():
+                    pubkey = contact['pubkey']
+                    break
+        elif self.ui.radio_search.isChecked():
+            if self.ui.search_user.current_identity():
+                pubkey = self.ui.search_user.current_identity().pubkey
+        else:
+            pubkey = self.ui.edit_pubkey.text()
+        return pubkey
+
+    @asyncify
+    async def refresh_member(self, checked=False):
+        """
+        Refresh the member widget
+        """
+        current_pubkey = self.selected_pubkey()
+        if current_pubkey:
+            identity = await self.app.identities_registry.future_find(current_pubkey, self.community)
+        else:
+            identity = None
+        self.ui.member_widget.identity = identity
+        self.ui.member_widget.refresh()
+
     @once_at_a_time
     @asyncify
     async def refresh(self):
@@ -104,19 +189,39 @@ class CertificationDialog(QDialog, Ui_CertificationDialog):
             block_0 = None
 
         if is_member or not block_0:
-            self.button_box.button(QDialogButtonBox.Ok).setEnabled(True)
-            self.button_box.button(QDialogButtonBox.Ok).setText(self.tr("&Ok"))
+            self.ui.button_box.button(QDialogButtonBox.Ok).setEnabled(True)
+            self.ui.button_box.button(QDialogButtonBox.Ok).setText(self.tr("&Ok"))
         else:
-            self.button_box.button(QDialogButtonBox.Ok).setEnabled(False)
-            self.button_box.button(QDialogButtonBox.Ok).setText(self.tr("Not a member"))
-
-    def recipient_mode_changed(self, pubkey_toggled):
-        self.edit_pubkey.setEnabled(pubkey_toggled)
-        self.combo_contact.setEnabled(not pubkey_toggled)
+            self.ui.button_box.button(QDialogButtonBox.Ok).setEnabled(False)
+            self.ui.button_box.button(QDialogButtonBox.Ok).setText(self.tr("Not a member"))
+
+    def showEvent(self, event):
+        super().showEvent(event)
+        self.first_certification_check()
+
+    def first_certification_check(self):
+        if self.account.notifications['warning_certifying_first_time']:
+            self.account.notifications['warning_certifying_first_time'] = False
+            QMessageBox.warning(self, "Certifying individuals", """Please follow the following guidelines :
+1.) Don't certify an account if you believe the issuers identity might be faked.
+2.) Don't certify an account if you believe the issuer already has another certified account.
+3.) Don't certify an account if you believe the issuer purposely or carelessly violates rule 1 or 2 (the issuer certifies faked or double accounts
+""")
+
+    def recipient_mode_changed(self, radio):
+        """
+        :param str radio:
+        """
+        self.ui.edit_pubkey.setEnabled(radio == "pubkey")
+        self.ui.combo_contact.setEnabled(radio == "contact")
+        self.ui.search_user.setEnabled(radio == "search")
 
     def async_exec(self):
         future = asyncio.Future()
-        self.finished.connect(lambda r: future.set_result(r))
-        self.open()
+        self.widget.finished.connect(lambda r: future.set_result(r))
+        self.widget.open()
         self.refresh()
         return future
+
+    def exec(self):
+        self.widget.exec()
diff --git a/src/sakia/gui/certifications_tab.py b/src/sakia/gui/certifications_tab.py
deleted file mode 100644
index 5690f71ccbbbd62248e288a7545892e47e953275..0000000000000000000000000000000000000000
--- a/src/sakia/gui/certifications_tab.py
+++ /dev/null
@@ -1,272 +0,0 @@
-import logging
-import asyncio
-
-from PyQt5.QtWidgets import QWidget, QAbstractItemView, QHeaderView, QDialog, \
-    QMenu, QAction, QApplication, QMessageBox
-from PyQt5.QtCore import Qt, QDateTime, QTime, QModelIndex, pyqtSignal, pyqtSlot, QEvent
-
-from PyQt5.QtGui import QCursor
-
-from ..gen_resources.certifications_tab_uic import Ui_certificationsTabWidget
-from ..models.certifications import HistoryTableModel, CertsFilterProxyModel
-from .contact import ConfigureContactDialog
-from .member import MemberDialog
-from .certification import CertificationDialog
-from ..core.wallet import Wallet
-from ..core.registry import Identity
-from ..tools.exceptions import NoPeerAvailable
-from ..tools.decorators import asyncify, once_at_a_time, cancel_once_task
-from .transfer import TransferMoneyDialog
-from sakia.gui.widgets import toast
-from sakia.gui.widgets.busy import Busy
-
-
-class CertificationsTabWidget(QWidget, Ui_certificationsTabWidget):
-    """
-    classdocs
-    """
-    view_in_wot = pyqtSignal(Identity)
-
-    def __init__(self, app):
-        """
-        Init
-
-        :param sakia.core.app.Application app: Application instance
-        :return:
-        """
-
-        super().__init__()
-        self.setupUi(self)
-        self.app = app
-        self.account = None
-        self.community = None
-        self.password_asker = None
-        self.busy_resume = Busy(self.groupbox_balance)
-        self.busy_resume.hide()
-
-        ts_from = self.date_from.dateTime().toTime_t()
-        ts_to = self.date_to.dateTime().toTime_t()
-
-        model = HistoryTableModel(self.app, self.account, self.community)
-        proxy = CertsFilterProxyModel(ts_from, ts_to)
-        proxy.setSourceModel(model)
-        proxy.setDynamicSortFilter(True)
-        proxy.setSortRole(Qt.DisplayRole)
-
-        self.table_history.setModel(proxy)
-        self.table_history.setSelectionBehavior(QAbstractItemView.SelectRows)
-        self.table_history.setSortingEnabled(True)
-        self.table_history.horizontalHeader().setSectionResizeMode(QHeaderView.Interactive)
-        self.table_history.resizeColumnsToContents()
-
-        model.modelAboutToBeReset.connect(lambda: self.table_history.setEnabled(False))
-        model.modelReset.connect(lambda: self.table_history.setEnabled(True))
-
-        self.progressbar.hide()
-        self.refresh()
-
-    def cancel_once_tasks(self):
-        cancel_once_task(self, self.refresh_minimum_maximum)
-        cancel_once_task(self, self.refresh_resume)
-        cancel_once_task(self, self.history_context_menu)
-
-    def change_account(self, account, password_asker):
-        self.cancel_once_tasks()
-        self.account = account
-        self.password_asker = password_asker
-        self.table_history.model().sourceModel().change_account(account)
-        if account:
-            self.connect_progress()
-
-    def change_community(self, community):
-        self.cancel_once_tasks()
-        self.community = community
-        self.progressbar.hide()
-        self.table_history.model().sourceModel().change_community(self.community)
-        self.refresh()
-
-    @once_at_a_time
-    @asyncify
-    async def refresh_minimum_maximum(self):
-        try:
-            block = await self.community.get_block(1)
-            minimum_datetime = QDateTime()
-            minimum_datetime.setTime_t(block['medianTime'])
-            minimum_datetime.setTime(QTime(0, 0))
-
-            self.date_from.setMinimumDateTime(minimum_datetime)
-            self.date_from.setDateTime(minimum_datetime)
-            self.date_from.setMaximumDateTime(QDateTime().currentDateTime())
-
-            self.date_to.setMinimumDateTime(minimum_datetime)
-            tomorrow_datetime = QDateTime().currentDateTime().addDays(1)
-            self.date_to.setDateTime(tomorrow_datetime)
-            self.date_to.setMaximumDateTime(tomorrow_datetime)
-        except NoPeerAvailable as e:
-            logging.debug(str(e))
-        except ValueError as e:
-            logging.debug(str(e))
-
-    def refresh(self):
-        if self.community:
-            self.table_history.model().sourceModel().refresh_transfers()
-            self.table_history.resizeColumnsToContents()
-            self.refresh_minimum_maximum()
-            self.refresh_resume()
-
-    def connect_progress(self):
-        def progressing(community, value, maximum):
-            if community == self.community:
-                self.progressbar.show()
-                self.progressbar.setValue(value)
-                self.progressbar.setMaximum(maximum)
-        self.account.loading_progressed.connect(progressing)
-        self.account.loading_finished.connect(self.stop_progress)
-
-    def stop_progress(self, community, received_list):
-        if community == self.community:
-            self.progressbar.hide()
-            self.table_history.model().sourceModel().refresh_transfers()
-            self.table_history.resizeColumnsToContents()
-            self.notification_reception(received_list)
-
-    @asyncify
-    @asyncio.coroutine
-    def notification_reception(self, received_list, sent_list):
-        if len(received_list) > 0:
-            text = self.tr("Received {nb_received} ; Sent {nb_sent}").format(nb_received=len(received_list) ,
-                                                                            nb_sent=len(sent_list))
-            if self.app.preferences['notifications']:
-                toast.display(self.tr("New certifications"), text)
-
-    @once_at_a_time
-    @asyncify
-    async def refresh_resume(self):
-        self.busy_resume.show()
-        self.busy_resume.hide()
-
-    @once_at_a_time
-    @asyncify
-    async def history_context_menu(self, point):
-        index = self.table_history.indexAt(point)
-        model = self.table_history.model()
-        if index.row() < model.rowCount(QModelIndex()):
-            menu = QMenu(self.tr("Actions"), self)
-            source_index = model.mapToSource(index)
-            state_col = model.sourceModel().columns_types.index('state')
-            state_index = model.sourceModel().index(source_index.row(),
-                                                   state_col)
-            state_data = model.sourceModel().data(state_index, Qt.DisplayRole)
-
-            pubkey_col = model.sourceModel().columns_types.index('pubkey')
-            pubkey_index = model.sourceModel().index(source_index.row(),
-                                                    pubkey_col)
-            pubkey = model.sourceModel().data(pubkey_index, Qt.DisplayRole)
-            identity = await self.app.identities_registry.future_find(pubkey, self.community)
-
-            if isinstance(identity, Identity):
-                informations = QAction(self.tr("Informations"), self)
-                informations.triggered.connect(self.menu_informations)
-                informations.setData(identity)
-                menu.addAction(informations)
-
-                add_as_contact = QAction(self.tr("Add as contact"), self)
-                add_as_contact.triggered.connect(self.menu_add_as_contact)
-                add_as_contact.setData(identity)
-                menu.addAction(add_as_contact)
-
-            send_money = QAction(self.tr("Send money"), self)
-            send_money.triggered.connect(self.menu_send_money)
-            send_money.setData(identity)
-            menu.addAction(send_money)
-
-            if isinstance(identity, Identity):
-                view_wot = QAction(self.tr("View in Web of Trust"), self)
-                view_wot.triggered.connect(self.view_wot)
-                view_wot.setData(identity)
-                menu.addAction(view_wot)
-
-            copy_pubkey = QAction(self.tr("Copy pubkey to clipboard"), self)
-            copy_pubkey.triggered.connect(self.copy_pubkey_to_clipboard)
-            copy_pubkey.setData(identity)
-            menu.addAction(copy_pubkey)
-
-            # Show the context menu.
-            menu.popup(QCursor.pos())
-
-    def copy_pubkey_to_clipboard(self):
-        data = self.sender().data()
-        clipboard = QApplication.clipboard()
-        if data.__class__ is Wallet:
-            clipboard.setText(data.pubkey)
-        elif data.__class__ is Identity:
-            clipboard.setText(data.pubkey)
-        elif data.__class__ is str:
-            clipboard.setText(data)
-
-    def menu_informations(self):
-        person = self.sender().data()
-        self.identity_informations(person)
-
-    def menu_add_as_contact(self):
-        person = self.sender().data()
-        self.add_identity_as_contact({'name': person.uid,
-                                    'pubkey': person.pubkey})
-
-    def menu_send_money(self):
-        identity = self.sender().data()
-        self.send_money_to_identity(identity)
-
-    def identity_informations(self, person):
-        dialog = MemberDialog(self.app, self.account, self.community, person)
-        dialog.exec_()
-
-    def add_identity_as_contact(self, person):
-        dialog = ConfigureContactDialog(self.account, self.window(), person)
-        result = dialog.exec_()
-        if result == QDialog.Accepted:
-            self.window().refresh_contacts()
-
-    @asyncify
-    async def send_money_to_identity(self, identity):
-        await TransferMoneyDialog.send_money_to_identity(self.app, self.account, self.password_asker,
-                                                            self.community, identity)
-        self.table_history.model().sourceModel().refresh_transfers()
-
-    @asyncify
-    async def certify_identity(self, identity):
-        await CertificationDialog.certify_identity(self.app, self.account, self.password_asker,
-                                             self.community, identity)
-
-    def view_wot(self):
-        identity = self.sender().data()
-        self.view_in_wot.emit(identity)
-
-    def dates_changed(self):
-        logging.debug("Changed dates")
-        if self.table_history.model():
-            qdate_from = self.date_from
-            qdate_from.setTime(QTime(0, 0, 0))
-            qdate_to = self.date_to
-            qdate_to.setTime(QTime(0, 0, 0))
-            ts_from = qdate_from.dateTime().toTime_t()
-            ts_to = qdate_to.dateTime().toTime_t()
-
-            self.table_history.model().set_period(ts_from, ts_to)
-
-            self.refresh_resume()
-
-    def resizeEvent(self, event):
-        self.busy_resume.resize(event.size())
-        super().resizeEvent(event)
-
-    def changeEvent(self, event):
-        """
-        Intercepte LanguageChange event to translate UI
-        :param QEvent QEvent: Event
-        :return:
-        """
-        if event.type() == QEvent.LanguageChange:
-            self.retranslateUi(self)
-            self.refresh()
-        return super(CertificationsTabWidget, self).changeEvent(event)
diff --git a/src/sakia/gui/community_view.py b/src/sakia/gui/community_view.py
index 5db08b0bb898ec57593cb1ac92cd9937ce34e607..9c26feeb7157d86a47b31b5ce3caac94a7fdf267 100644
--- a/src/sakia/gui/community_view.py
+++ b/src/sakia/gui/community_view.py
@@ -7,14 +7,13 @@ Created on 2 févr. 2014
 import logging
 import time
 
-from PyQt5.QtCore import pyqtSlot, QDateTime, QLocale, QEvent, QT_TRANSLATE_NOOP
-from PyQt5.QtGui import QIcon
+from PyQt5.QtCore import pyqtSlot, QDateTime, QLocale, QEvent, QT_TRANSLATE_NOOP, Qt
+from PyQt5.QtGui import QIcon, QPixmap
 from PyQt5.QtWidgets import QWidget, QMessageBox, QDialog, QPushButton, QTabBar, QAction
 
 from .graphs.wot_tab import WotTabWidget
 from .widgets import toast
 from .widgets.dialogs import QAsyncMessageBox
-from .certifications_tab import CertificationsTabWidget
 from .identities_tab import IdentitiesTabWidget
 from .informations_tab import InformationsTabWidget
 from .network_tab import NetworkTabWidget
@@ -41,8 +40,7 @@ class CommunityWidget(QWidget, Ui_CommunityWidget):
     _action_publish_uid_text = QT_TRANSLATE_NOOP("CommunityWidget", "Publish UID")
     _action_revoke_uid_text = QT_TRANSLATE_NOOP("CommunityWidget", "Revoke UID")
 
-
-    def __init__(self, app, status_label):
+    def __init__(self, app, status_label, label_icon):
         """
         Constructor
         """
@@ -52,6 +50,7 @@ class CommunityWidget(QWidget, Ui_CommunityWidget):
         self.community = None
         self.password_asker = None
         self.status_label = status_label
+        self.label_icon = label_icon
 
         self.status_info = []
 
@@ -59,7 +58,6 @@ class CommunityWidget(QWidget, Ui_CommunityWidget):
         self.tab_identities = IdentitiesTabWidget(self.app)
         self.tab_history = TransactionsTabWidget(self.app)
         self.tab_informations = InformationsTabWidget(self.app)
-        self.tab_certifications = CertificationsTabWidget(self.app)
         self.tab_network = NetworkTabWidget(self.app)
         self.tab_explorer = ExplorerTabWidget(self.app)
 
@@ -71,21 +69,21 @@ class CommunityWidget(QWidget, Ui_CommunityWidget):
         super().setupUi(self)
 
         self.tab_identities.view_in_wot.connect(self.tab_wot.draw_graph)
-        self.tab_identities.view_in_wot.connect(lambda: self.tabs.setCurrentWidget(self.tab_wot))
+        self.tab_identities.view_in_wot.connect(lambda: self.tabs.setCurrentWidget(self.tab_wot.widget))
         self.tab_history.view_in_wot.connect(self.tab_wot.draw_graph)
-        self.tab_history.view_in_wot.connect(lambda: self.tabs.setCurrentWidget(self.tab_wot))
-        self.tab_identities.money_sent.connect(lambda: self.tab_history.table_history.model().sourceModel().refresh_transfers())
-        self.tab_wot.money_sent.connect(lambda: self.tab_history.table_history.model().sourceModel().refresh_transfers())
+        self.tab_history.view_in_wot.connect(lambda: self.tabs.setCurrentWidget(self.tab_wot.widget))
+        self.tab_identities.money_sent.connect(lambda: self.tab_history.widget.table_history.model().sourceModel().refresh_transfers())
+        self.tab_wot.money_sent.connect(lambda: self.tab_history.widget.table_history.model().sourceModel().refresh_transfers())
 
-        self.tabs.addTab(self.tab_history,
+        self.tabs.addTab(self.tab_history.widget,
                                  QIcon(':/icons/tx_icon'),
                                 self.tr(CommunityWidget._tab_history_label))
 
-        self.tabs.addTab(self.tab_wot,
+        self.tabs.addTab(self.tab_wot.widget,
                          QIcon(':/icons/wot_icon'),
                          self.tr(CommunityWidget._tab_wot_label))
 
-        self.tabs.addTab(self.tab_identities,
+        self.tabs.addTab(self.tab_identities.widget,
                          QIcon(':/icons/members_icon'),
                          self.tr(CommunityWidget._tab_identities_label))
 
@@ -99,7 +97,7 @@ class CommunityWidget(QWidget, Ui_CommunityWidget):
         self.toolbutton_menu.addAction(action_showinfo)
 
         action_showexplorer = QAction(self.tr("Show explorer"), self.toolbutton_menu)
-        action_showexplorer.triggered.connect(lambda : self.show_closable_tab(self.tab_explorer,
+        action_showexplorer.triggered.connect(lambda : self.show_closable_tab(self.tab_explorer.widget,
                                     QIcon(":/icons/explorer_icon"), self.tr("Explorer")))
         self.toolbutton_menu.addAction(action_showexplorer)
 
@@ -190,10 +188,10 @@ class CommunityWidget(QWidget, Ui_CommunityWidget):
                         self.status_info.append('membership_expire_soon')
 
                     if self.app.preferences['notifications'] and\
-                            self.app.notifications['membership_expire_soon'][1]+24*3600 < time.time():
+                            self.account.notifications['membership_expire_soon'][1]+24*3600 < time.time():
                         toast.display(self.tr("Membership expiration"),
                                   self.tr("<b>Warning : Membership expiration in {0} days</b>").format(days))
-                        self.app.notifications['membership_expire_soon'][1] = time.time()
+                        self.account.notifications['membership_expire_soon'][1] = time.time()
 
             certifiers_of = await person.unique_valid_certifiers_of(self.app.identities_registry,
                                                                          self.community)
@@ -201,12 +199,12 @@ class CommunityWidget(QWidget, Ui_CommunityWidget):
                 if 'warning_certifications' not in self.status_info:
                     self.status_info.append('warning_certifications')
                 if self.app.preferences['notifications'] and\
-                        self.app.notifications['warning_certifications'][1]+24*3600 < time.time():
+                        self.account.notifications['warning_certifications'][1]+24*3600 < time.time():
                     toast.display(self.tr("Certifications number"),
                               self.tr("<b>Warning : You are certified by only {0} persons, need {1}</b>")
                               .format(len(certifiers_of),
                                      parameters['sigQty']))
-                    self.app.notifications['warning_certifications'][1] = time.time()
+                    self.account.notifications['warning_certifications'][1] = time.time()
 
         except MembershipNotFoundError as e:
             pass
@@ -257,14 +255,14 @@ class CommunityWidget(QWidget, Ui_CommunityWidget):
                 self.button_send_money.setEnabled(True)
 
             if self.community.network.quality > 0.66:
-                icon = '<img src=":/icons/connected" width="12" height="12"/>'
+                icon = ':/icons/connected'
             elif self.community.network.quality > 0.33:
-                icon = '<img src=":/icons/weak_connect" width="12" height="12"/>'
+                icon = ':/icons/weak_connect'
             else:
-                icon = '<img src=":/icons/disconnected" width="12" height="12"/>'
+                icon = ':/icons/disconnected'
 
             status_infotext = " - ".join([self.app.notifications[info][0] for info in self.status_info])
-            label_text = "{0}{1}".format(icon, text)
+            label_text = text
             if status_infotext != "":
                 label_text += " - {0}".format(status_infotext)
 
@@ -279,6 +277,7 @@ class CommunityWidget(QWidget, Ui_CommunityWidget):
                         .format("#")
 
             self.status_label.setText(label_text)
+            self.label_icon.setPixmap(QPixmap(icon).scaled(24, 24, Qt.KeepAspectRatio, Qt.SmoothTransformation))
 
     @once_at_a_time
     @asyncify
@@ -410,11 +409,11 @@ The process to join back the community later will have to be done again.""")
         :param widget:
         :return:
         """
-        self.tabs.setTabText(self.tabs.indexOf(self.tab_wot), self.tr(CommunityWidget._tab_wot_label))
+        self.tabs.setTabText(self.tabs.indexOf(self.tab_wot.widget), self.tr(CommunityWidget._tab_wot_label))
         self.tabs.setTabText(self.tabs.indexOf(self.tab_network), self.tr(CommunityWidget._tab_network_label))
         self.tabs.setTabText(self.tabs.indexOf(self.tab_informations), self.tr(CommunityWidget._tab_informations_label))
-        self.tabs.setTabText(self.tabs.indexOf(self.tab_history), self.tr(CommunityWidget._tab_history_label))
-        self.tabs.setTabText(self.tabs.indexOf(self.tab_identities), self.tr(CommunityWidget._tab_identities_label))
+        self.tabs.setTabText(self.tabs.indexOf(self.tab_history.widget), self.tr(CommunityWidget._tab_history_label))
+        self.tabs.setTabText(self.tabs.indexOf(self.tab_identities.widget), self.tr(CommunityWidget._tab_identities_label))
         self.action_publish_uid.setText(self.tr(CommunityWidget._action_publish_uid_text))
         self.action_revoke_uid.setText(self.tr(CommunityWidget._action_revoke_uid_text))
         self.action_showinfo.setText(self.tr(CommunityWidget._action_showinfo_text))
diff --git a/src/sakia/gui/contact.py b/src/sakia/gui/contact.py
index bc6f550e84995a28f26d5a1c9fbd9a3817c2f721..457a8002a3390f1818f9e9ca32e5c070b3d85b87 100644
--- a/src/sakia/gui/contact.py
+++ b/src/sakia/gui/contact.py
@@ -37,6 +37,14 @@ class ConfigureContactDialog(QDialog, Ui_ConfigureContactDialog):
             self.edit_name.setText(self.contact['name'])
             self.edit_pubkey.setText(self.contact['pubkey'])
 
+    @classmethod
+    def from_identity(cls, parent, account, identity):
+        contact = {
+            'name': identity.uid,
+            'pubkey': identity.pubkey
+        }
+        return ConfigureContactDialog(account, parent, contact)
+
     def accept(self):
         name = self.edit_name.text()
         pubkey = self.edit_pubkey.text()
diff --git a/src/sakia/gui/graphs/explorer_tab.py b/src/sakia/gui/graphs/explorer_tab.py
index 75321719cb4994d532b1b4e070209e5a437735a5..b39ee555759d06f08b01380046b79748f6e76628 100644
--- a/src/sakia/gui/graphs/explorer_tab.py
+++ b/src/sakia/gui/graphs/explorer_tab.py
@@ -1,11 +1,9 @@
 import logging
 
-from PyQt5.QtCore import QEvent, pyqtSignal, QT_TRANSLATE_NOOP
-
-from ucoinpy.api import bma
+from PyQt5.QtCore import QEvent, pyqtSignal
+from PyQt5.QtWidgets import QWidget
 
 from ...tools.decorators import asyncify, once_at_a_time, cancel_once_task
-from ...tools.exceptions import NoPeerAvailable
 from ...core.graph import ExplorerGraph
 from .graph_tab import GraphTabWidget
 from ...gen_resources.explorer_tab_uic import Ui_ExplorerTabWidget
@@ -15,20 +13,22 @@ class ExplorerTabWidget(GraphTabWidget, Ui_ExplorerTabWidget):
 
     money_sent = pyqtSignal()
 
-    def __init__(self, app):
+    def __init__(self, app, account=None, community=None, password_asker=None,
+                 widget=QWidget, view=Ui_ExplorerTabWidget):
         """
         :param sakia.core.app.Application app: Application instance
+        :param sakia.core.app.Application app: Application instance
+        :param sakia.core.Account account: The account displayed in the widget
+        :param sakia.core.Community community: The community displayed in the widget
+        :param sakia.gui.Password_Asker: password_asker: The widget to ask for passwords
         """
         # construct from qtDesigner
-        super().__init__(app)
-        self.setupUi(self)
-        self.search_user_widget.init(app)
-
-        self.set_scene(self.graphicsView.scene())
+        super().__init__(app, account, community, password_asker, widget)
+        self.ui = view()
+        self.ui.setupUi(self.widget)
+        self.ui.search_user_widget.init(app)
 
-        self.account = None
-        self.community = None
-        self.password_asker = None
+        self.set_scene(self.ui.graphicsView.scene())
         self.graph = None
         self.app = app
         self.draw_task = None
@@ -38,16 +38,16 @@ class ExplorerTabWidget(GraphTabWidget, Ui_ExplorerTabWidget):
 
         # create node metadata from account
         self._current_identity = None
-        self.button_go.clicked.connect(self.go_clicked)
-        self.search_user_widget.identity_selected.connect(self.draw_graph)
-        self.search_user_widget.reset.connect(self.reset)
+        self.ui.button_go.clicked.connect(self.go_clicked)
+        self.ui.search_user_widget.identity_selected.connect(self.draw_graph)
+        self.ui.search_user_widget.reset.connect(self.reset)
 
     def cancel_once_tasks(self):
         cancel_once_task(self, self.refresh_informations_frame)
         cancel_once_task(self, self.reset)
 
     def change_account(self, account, password_asker):
-        self.search_user_widget.change_account(account)
+        self.ui.search_user_widget.change_account(account)
         self.account = account
         self.password_asker = password_asker
 
@@ -57,8 +57,8 @@ class ExplorerTabWidget(GraphTabWidget, Ui_ExplorerTabWidget):
             self.graph.stop_exploration()
         self.graph = ExplorerGraph(self.app, self.community)
         self.graph.graph_changed.connect(self.refresh)
-        self.search_user_widget.change_community(community)
-        self.graph.current_identity_changed.connect(self.graphicsView.scene().update_current_identity)
+        self.ui.search_user_widget.change_community(community)
+        self.graph.current_identity_changed.connect(self.ui.graphicsView.scene().update_current_identity)
         self.reset()
 
     def go_clicked(self):
@@ -79,11 +79,11 @@ class ExplorerTabWidget(GraphTabWidget, Ui_ExplorerTabWidget):
             if self._current_identity != identity:
                 self._current_identity = identity
 
-            self.graph.start_exploration(identity, self.steps_slider.value())
+            self.graph.start_exploration(identity, self.ui.steps_slider.value())
 
             # draw graph in qt scene
-            self.graphicsView.scene().clear()
-            self.graphicsView.scene().update_wot(self.graph.nx_graph, identity, self.steps_slider.maximum())
+            self.ui.graphicsView.scene().clear()
+            self.ui.graphicsView.scene().update_wot(self.graph.nx_graph, identity, self.ui.steps_slider.maximum())
 
     def refresh(self):
         """
@@ -91,7 +91,7 @@ class ExplorerTabWidget(GraphTabWidget, Ui_ExplorerTabWidget):
         """
         if self._current_identity:
             # draw graph in qt scene
-            self.graphicsView.scene().update_wot(self.graph.nx_graph, self._current_identity, self.steps_slider.maximum())
+            self.ui.graphicsView.scene().update_wot(self.graph.nx_graph, self._current_identity, self.ui.steps_slider.maximum())
         else:
             self.reset()
 
@@ -103,8 +103,8 @@ class ExplorerTabWidget(GraphTabWidget, Ui_ExplorerTabWidget):
         """
         if self.account and self.community:
             parameters = await self.community.parameters()
-            self.steps_slider.setMaximum(parameters['stepMax'])
-            self.steps_slider.setValue(int(0.33 * parameters['stepMax']))
+            self.ui.steps_slider.setMaximum(parameters['stepMax'])
+            self.ui.steps_slider.setValue(int(0.33 * parameters['stepMax']))
             identity = await self.account.identity(self.community)
             self.draw_graph(identity)
 
diff --git a/src/sakia/gui/graphs/graph_tab.py b/src/sakia/gui/graphs/graph_tab.py
index 18ec848cfaf37cbc6da5c248fde16fd58cf15ecf..d308245b821fb6a43169b3780b0204436cc7c47a 100644
--- a/src/sakia/gui/graphs/graph_tab.py
+++ b/src/sakia/gui/graphs/graph_tab.py
@@ -1,35 +1,44 @@
-from PyQt5.QtWidgets import QWidget, QDialog
-from PyQt5.QtCore import pyqtSlot, QEvent, QLocale, QDateTime, pyqtSignal
+from PyQt5.QtWidgets import QWidget
+from PyQt5.QtCore import pyqtSlot, QEvent, QLocale, QDateTime, pyqtSignal, QObject
+from PyQt5.QtGui import QCursor
 
 from ...tools.exceptions import MembershipNotFoundError
 from ...tools.decorators import asyncify, once_at_a_time
 from ...core.registry import BlockchainState
-from ...gui.member import MemberDialog
-from ...gui.certification import CertificationDialog
-from ...gui.transfer import TransferMoneyDialog
-from ...gui.contact import ConfigureContactDialog
+from ..widgets.context_menu import ContextMenu
 
 
-class GraphTabWidget(QWidget):
+class GraphTabWidget(QObject):
 
     money_sent = pyqtSignal()
-    def __init__(self, app):
+
+    def __init__(self, app, account=None, community=None, password_asker=None, widget=QWidget):
         """
         :param sakia.core.app.Application app: Application instance
+        :param sakia.core.app.Application app: Application instance
+        :param sakia.core.Account account: The account displayed in the widget
+        :param sakia.core.Community community: The community displayed in the widget
+        :param sakia.gui.Password_Asker: password_asker: The widget to ask for passwords
+        :param class widget: The class of the graph tab
         """
         super().__init__()
 
-        self.password_asker = None
+        self.widget = widget()
+        self.account = account
+        self.community = community
+        self.password_asker = password_asker
+
         self.app = app
 
     def set_scene(self, scene):
+        """
+        Set the scene and connects the signals
+        :param sakia.gui.views.scenes.base_scene.BaseScene scene: the scene
+        :return:
+        """
         # add scene events
+        scene.node_context_menu_requested.connect(self.node_context_menu)
         scene.node_clicked.connect(self.handle_node_click)
-        scene.node_signed.connect(self.sign_node)
-        scene.node_transaction.connect(self.send_money_to_node)
-        scene.node_contact.connect(self.add_node_as_contact)
-        scene.node_member.connect(self.identity_informations)
-        scene.node_copy_pubkey.connect(self.copy_node_pubkey)
 
     @once_at_a_time
     @asyncify
@@ -147,59 +156,19 @@ class GraphTabWidget(QWidget):
         """
         pass
 
-    def identity_informations(self, pubkey, metadata):
-        identity = self.app.identities_registry.from_handled_data(
-            metadata['text'],
-            pubkey,
-            None,
-            BlockchainState.VALIDATED,
-            self.community
-        )
-        dialog = MemberDialog(self.app, self.account, self.community, identity)
-        dialog.exec_()
-
     @asyncify
-    async def sign_node(self, pubkey, metadata):
-        identity = self.app.identities_registry.from_handled_data(
-            metadata['text'],
-            pubkey,
-            None,
-            BlockchainState.VALIDATED,
-            self.community
-        )
-        await CertificationDialog.certify_identity(self.app, self.account, self.password_asker,
-                                             self.community, identity)
+    async def node_context_menu(self, pubkey):
+        """
+        Open the node context menu
+        :param str pubkey: the pubkey of the node to open
+        """
+        identity = await self.app.identities_registry.future_find(pubkey, self.community)
+        menu = ContextMenu.from_data(self.widget, self.app, self.account, self.community, self.password_asker,
+                                     (identity,))
+        menu.view_identity_in_wot.connect(self.draw_graph)
 
-    @asyncify
-    async def send_money_to_node(self, pubkey, metadata):
-        identity = self.app.identities_registry.from_handled_data(
-            metadata['text'],
-            pubkey,
-            None,
-            BlockchainState.VALIDATED,
-            self.community
-        )
-        result = await TransferMoneyDialog.send_money_to_identity(self.app, self.account, self.password_asker,
-                                                            self.community, identity)
-        if result == QDialog.Accepted:
-            self.money_sent.emit()
-
-    def copy_node_pubkey(self, pubkey):
-        cb = self.app.qapp.clipboard()
-        cb.clear(mode=cb.Clipboard)
-        cb.setText(pubkey, mode=cb.Clipboard)
-
-    def add_node_as_contact(self, pubkey, metadata):
-        # check if contact already exists...
-        if pubkey == self.account.pubkey \
-                or pubkey in [contact['pubkey'] for contact in self.account.contacts]:
-            return False
-        dialog = ConfigureContactDialog(self.account, self.window(), {'name': metadata['text'],
-                                                                      'pubkey': pubkey,
-                                                                      })
-        result = dialog.exec_()
-        if result == QDialog.Accepted:
-            self.window().refresh_contacts()
+        # Show the context menu.
+        menu.qmenu.popup(QCursor.pos())
 
     def changeEvent(self, event):
         """
diff --git a/src/sakia/gui/graphs/wot_tab.py b/src/sakia/gui/graphs/wot_tab.py
index ce12bd290e659bde210edc643d3f2d9b80427e2b..a3119357ab7964b474c826e578bbb92443d7cc14 100644
--- a/src/sakia/gui/graphs/wot_tab.py
+++ b/src/sakia/gui/graphs/wot_tab.py
@@ -1,7 +1,8 @@
 import logging
 import asyncio
 
-from PyQt5.QtCore import QEvent, pyqtSignal, QT_TRANSLATE_NOOP
+from PyQt5.QtCore import QEvent, pyqtSignal, QT_TRANSLATE_NOOP, QObject
+from PyQt5.QtWidgets import QWidget
 from ...tools.decorators import asyncify, once_at_a_time, cancel_once_task
 from ...core.graph import WoTGraph
 from ...gen_resources.wot_tab_uic import Ui_WotTabWidget
@@ -9,31 +10,40 @@ from ...gui.widgets.busy import Busy
 from .graph_tab import GraphTabWidget
 
 
-class WotTabWidget(GraphTabWidget, Ui_WotTabWidget):
+class WotTabWidget(GraphTabWidget):
 
     money_sent = pyqtSignal()
 
-    def __init__(self, app):
+    def __init__(self, app, account=None, community=None, password_asker=None, widget=QWidget, view=Ui_WotTabWidget):
         """
         :param sakia.core.app.Application app: Application instance
+        :param sakia.core.app.Application app: Application instance
+        :param sakia.core.Account account: The account displayed in the widget
+        :param sakia.core.Community community: The community displayed in the widget
+        :param sakia.gui.Password_Asker: password_asker: The widget to ask for passwords
+        :param class widget: The class of the PyQt5 widget used for this tab
+        :param class view: The class of the UI View for this tab
         """
-        super().__init__(app)
+        super().__init__(app, account, community, password_asker, widget)
         # construct from qtDesigner
-        self.setupUi(self)
-        self.search_user_widget.init(app)
-        self.busy = Busy(self.graphicsView)
+        self.ui = view()
+        self.ui.setupUi(self.widget)
+
+        self.ui.search_user_widget.init(app)
+        self.widget.installEventFilter(self)
+        self.busy = Busy(self.ui.graphicsView)
         self.busy.hide()
 
-        self.set_scene(self.graphicsView.scene())
+        self.set_scene(self.ui.graphicsView.scene())
 
-        self.account = None
-        self.community = None
-        self.password_asker = None
+        self.account = account
+        self.community = community
+        self.password_asker = password_asker
         self.app = app
         self.draw_task = None
 
-        self.search_user_widget.identity_selected.connect(self.draw_graph)
-        self.search_user_widget.reset.connect(self.reset)
+        self.ui.search_user_widget.identity_selected.connect(self.draw_graph)
+        self.ui.search_user_widget.reset.connect(self.reset)
 
         # create node metadata from account
         self._current_identity = None
@@ -45,13 +55,13 @@ class WotTabWidget(GraphTabWidget, Ui_WotTabWidget):
 
     def change_account(self, account, password_asker):
         self.cancel_once_tasks()
-        self.search_user_widget.change_account(account)
+        self.ui.search_user_widget.change_account(account)
         self.account = account
         self.password_asker = password_asker
 
     def change_community(self, community):
         self.cancel_once_tasks()
-        self.search_user_widget.change_community(community)
+        self.ui.search_user_widget.change_community(community)
         self._auto_refresh(community)
         self.community = community
         self.reset()
@@ -87,14 +97,14 @@ class WotTabWidget(GraphTabWidget, Ui_WotTabWidget):
             graph = WoTGraph(self.app, self.community)
             await graph.initialize(identity, identity_account)
             # draw graph in qt scene
-            self.graphicsView.scene().update_wot(graph.nx_graph, identity)
+            self.ui.graphicsView.scene().update_wot(graph.nx_graph, identity)
 
             # if selected member is not the account member...
             if identity.pubkey != identity_account.pubkey:
                 # add path from selected member to account member
                 path = await graph.get_shortest_path_to_identity(identity_account, identity)
                 if path:
-                    self.graphicsView.scene().update_path(graph.nx_graph, path)
+                    self.ui.graphicsView.scene().update_path(graph.nx_graph, path)
         self.busy.hide()
 
     @once_at_a_time
@@ -116,9 +126,11 @@ class WotTabWidget(GraphTabWidget, Ui_WotTabWidget):
         else:
             self.reset()
 
-    def resizeEvent(self, event):
-        self.busy.resize(event.size())
-        super().resizeEvent(event)
+    def eventFilter(self, source, event):
+        if event.type() == QEvent.Resize:
+            self.busy.resize(event.size())
+            self.widget.resizeEvent(event)
+        return self.widget.eventFilter(source, event)
 
     def changeEvent(self, event):
         """
diff --git a/src/sakia/gui/identities_tab.py b/src/sakia/gui/identities_tab.py
index a84857fed2875cddf865ea9055fcdc2755750245..02badc49cf9e7b5c52531f7ca038002c00097377 100644
--- a/src/sakia/gui/identities_tab.py
+++ b/src/sakia/gui/identities_tab.py
@@ -4,10 +4,9 @@ Created on 2 févr. 2014
 @author: inso
 """
 
-import asyncio
 import logging
 
-from PyQt5.QtCore import Qt, pyqtSignal, QEvent, QT_TRANSLATE_NOOP
+from PyQt5.QtCore import Qt, pyqtSignal, QEvent, QT_TRANSLATE_NOOP, QObject
 from PyQt5.QtGui import QCursor
 from PyQt5.QtWidgets import QWidget, QAction, QMenu, QDialog, \
                             QAbstractItemView
@@ -15,62 +14,62 @@ from ucoinpy.api import bma
 
 from ..models.identities import IdentitiesFilterProxyModel, IdentitiesTableModel
 from ..gen_resources.identities_tab_uic import Ui_IdentitiesTab
-from .contact import ConfigureContactDialog
-from .member import MemberDialog
-from .transfer import TransferMoneyDialog
-from sakia.gui.widgets.busy import Busy
-from .certification import CertificationDialog
 from ..core.registry import Identity, BlockchainState
 from ..tools.exceptions import NoPeerAvailable
 from ..tools.decorators import asyncify, once_at_a_time, cancel_once_task
+from .widgets.context_menu import ContextMenu
 
 
-class IdentitiesTabWidget(QWidget, Ui_IdentitiesTab):
+class IdentitiesTabWidget(QObject):
 
     """
     classdocs
     """
-    view_in_wot = pyqtSignal(Identity)
+    view_in_wot = pyqtSignal(object)
     money_sent = pyqtSignal()
 
     _direct_connections_text = QT_TRANSLATE_NOOP("IdentitiesTabWidget", "Search direct certifications")
     _search_placeholder = QT_TRANSLATE_NOOP("IdentitiesTabWidget", "Research a pubkey, an uid...")
 
-    def __init__(self, app):
+    def __init__(self, app, account=None, community=None, password_asker=None,
+                 widget=QWidget, view=Ui_IdentitiesTab):
         """
         Init
-        :param sakia.core.account.Account account: Account instance
-        :param sakia.core.community.Community community: Community instance
-        :param sakia.gui.password_asker.PasswordAskerDialog password_asker: Password asker dialog
-        :return:
+
+        :param sakia.core.app.Application app: Application instance
+        :param sakia.core.Account account: The account displayed in the widget
+        :param sakia.core.Community community: The community displayed in the widget
+        :param sakia.gui.Password_Asker: password_asker: The widget to ask for passwords
+        :param class widget: The class of the PyQt5 widget used for this tab
+        :param class view: The class of the UI View for this tab
         """
         super().__init__()
+        self.widget = widget()
+        self.ui = view()
+        self.ui.setupUi(self.widget)
+
         self.app = app
-        self.community = None
-        self.account = None
-        self.password_asker = None
+        self.community = community
+        self.account = account
+        self.password_asker = password_asker
 
         self.direct_connections = QAction(self.tr(IdentitiesTabWidget._direct_connections_text), self)
-        self.setupUi(self)
-        self.edit_textsearch.setPlaceholderText(self.tr(IdentitiesTabWidget._search_placeholder))
+        self.ui.edit_textsearch.setPlaceholderText(self.tr(IdentitiesTabWidget._search_placeholder))
 
         identities_model = IdentitiesTableModel()
         proxy = IdentitiesFilterProxyModel()
         proxy.setSourceModel(identities_model)
-        self.table_identities.setModel(proxy)
-        self.table_identities.setSelectionBehavior(QAbstractItemView.SelectRows)
-        self.table_identities.customContextMenuRequested.connect(self.identity_context_menu)
-        self.table_identities.sortByColumn(0, Qt.AscendingOrder)
-        self.table_identities.resizeColumnsToContents()
-        identities_model.modelAboutToBeReset.connect(lambda: self.table_identities.setEnabled(False))
-        identities_model.modelReset.connect(lambda: self.table_identities.setEnabled(True))
+        self.ui.table_identities.setModel(proxy)
+        self.ui.table_identities.setSelectionBehavior(QAbstractItemView.SelectRows)
+        self.ui.table_identities.customContextMenuRequested.connect(self.identity_context_menu)
+        self.ui.table_identities.sortByColumn(0, Qt.AscendingOrder)
+        self.ui.table_identities.resizeColumnsToContents()
+        identities_model.modelAboutToBeReset.connect(lambda: self.ui.table_identities.setEnabled(False))
+        identities_model.modelReset.connect(lambda: self.ui.table_identities.setEnabled(True))
 
         self.direct_connections.triggered.connect(self._async_search_direct_connections)
-        self.button_search.addAction(self.direct_connections)
-        self.button_search.clicked.connect(self._async_execute_search_text)
-
-        self.busy = Busy(self.table_identities)
-        self.busy.hide()
+        self.ui.button_search.addAction(self.direct_connections)
+        self.ui.button_search.clicked.connect(self._async_execute_search_text)
 
     def cancel_once_tasks(self):
         cancel_once_task(self, self.identity_context_menu)
@@ -88,14 +87,14 @@ class IdentitiesTabWidget(QWidget, Ui_IdentitiesTab):
     def change_community(self, community):
         self.cancel_once_tasks()
         self.community = community
-        self.table_identities.model().change_community(community)
+        self.ui.table_identities.model().change_community(community)
         self._async_search_direct_connections()
 
     @once_at_a_time
     @asyncify
     async def identity_context_menu(self, point):
-        index = self.table_identities.indexAt(point)
-        model = self.table_identities.model()
+        index = self.ui.table_identities.indexAt(point)
+        model = self.ui.table_identities.model()
         if index.isValid() and index.row() < model.rowCount():
             source_index = model.mapToSource(index)
             pubkey_col = model.sourceModel().columns_ids.index('pubkey')
@@ -103,102 +102,20 @@ class IdentitiesTabWidget(QWidget, Ui_IdentitiesTab):
                                                    pubkey_col)
             pubkey = model.sourceModel().data(pubkey_index, Qt.DisplayRole)
             identity = await self.app.identities_registry.future_find(pubkey, self.community)
-            menu = QMenu(self)
-
-            informations = QAction(self.tr("Informations"), self)
-            informations.triggered.connect(self.menu_informations)
-            informations.setData(identity)
-            add_contact = QAction(self.tr("Add as contact"), self)
-            add_contact.triggered.connect(self.menu_add_as_contact)
-            add_contact.setData(identity)
-
-            send_money = QAction(self.tr("Send money"), self)
-            send_money.triggered.connect(self.menu_send_money)
-            send_money.setData(identity)
-
-            certify = QAction(self.tr("Certify identity"), self)
-            certify.triggered.connect(self.menu_certify_member)
-            certify.setData(identity)
-
-            view_wot = QAction(self.tr("View in Web of Trust"), self)
-            view_wot.triggered.connect(self.view_wot)
-            view_wot.setData(identity)
-
-            copy_pubkey = QAction(self.tr("Copy pubkey"), self)
-            copy_pubkey.triggered.connect(self.copy_identity_pubkey)
-            copy_pubkey.setData(identity)
-
-            menu.addAction(informations)
-            menu.addAction(add_contact)
-            menu.addAction(send_money)
-            menu.addAction(certify)
-            menu.addAction(view_wot)
-            menu.addAction(copy_pubkey)
+            menu = ContextMenu.from_data(self.widget, self.app, self.account, self.community, self.password_asker,
+                                         (identity,))
+            menu.view_identity_in_wot.connect(self.view_in_wot)
 
             # Show the context menu.
-            menu.popup(QCursor.pos())
-
-    def menu_informations(self):
-        person = self.sender().data()
-        self.identity_informations(person)
-
-    def menu_add_as_contact(self):
-        person = self.sender().data()
-        self.add_identity_as_contact({'name': person.uid,
-                                    'pubkey': person.pubkey})
-
-    def menu_send_money(self):
-        person = self.sender().data()
-        self.send_money_to_identity(person)
-
-    def menu_certify_member(self):
-        person = self.sender().data()
-        self.certify_identity(person)
-
-    def identity_informations(self, person):
-        dialog = MemberDialog(self.app, self.account, self.community, person)
-        dialog.exec_()
-
-    def add_identity_as_contact(self, person):
-        dialog = ConfigureContactDialog(self.account, self.window(), person)
-        result = dialog.exec_()
-        if result == QDialog.Accepted:
-            self.window().refresh_contacts()
-
-    @asyncify
-    async def send_money_to_identity(self, identity):
-        result = await TransferMoneyDialog.send_money_to_identity(self.app, self.account, self.password_asker,
-                                                            self.community, identity)
-        if result == QDialog.Accepted:
-            self.money_sent.emit()
-
-    @asyncify
-    async def certify_identity(self, identity):
-        await CertificationDialog.certify_identity(self.app, self.account, self.password_asker,
-                                             self.community, identity)
-
-    def copy_identity_pubkey(self):
-        """
-        Copy the identity pubkey to the clipboard
-
-        :param sakia.core.registry.Identity identity: The identity
-        """
-        identity = self.sender().data()
-        cb = self.app.qapp.clipboard()
-        cb.clear(mode=cb.Clipboard)
-        cb.setText(identity.pubkey, mode=cb.Clipboard)
-
-    def view_wot(self):
-        identity = self.sender().data()
-        self.view_in_wot.emit(identity)
+            menu.qmenu.popup(QCursor.pos())
 
     @once_at_a_time
     @asyncify
     async def _async_execute_search_text(self, checked):
         cancel_once_task(self, self._async_search_direct_connections)
 
-        self.busy.show()
-        text = self.edit_textsearch.text()
+        self.ui.busy.show()
+        text = self.ui.edit_textsearch.text()
         if len(text) < 2:
             return
         try:
@@ -212,13 +129,13 @@ class IdentitiesTabWidget(QWidget, Ui_IdentitiesTab):
                                                          BlockchainState.BUFFERED)
                     identities.append(identity)
 
-            self.edit_textsearch.clear()
-            self.edit_textsearch.setPlaceholderText(text)
+            self.ui.edit_textsearch.clear()
+            self.ui.edit_textsearch.setPlaceholderText(text)
             await self.refresh_identities(identities)
         except ValueError as e:
             logging.debug(str(e))
         finally:
-            self.busy.hide()
+            self.ui.busy.hide()
 
     @once_at_a_time
     @asyncify
@@ -230,9 +147,9 @@ class IdentitiesTabWidget(QWidget, Ui_IdentitiesTab):
 
         if self.account and self.community:
             try:
-                self.edit_textsearch.setPlaceholderText(self.tr(IdentitiesTabWidget._search_placeholder))
+                self.ui.edit_textsearch.setPlaceholderText(self.tr(IdentitiesTabWidget._search_placeholder))
                 await self.refresh_identities([])
-                self.busy.show()
+                self.ui.busy.show()
                 self_identity = await self.account.identity(self.community)
                 account_connections = []
                 certs_of = await self_identity.unique_valid_certifiers_of(self.app.identities_registry, self.community)
@@ -245,25 +162,25 @@ class IdentitiesTabWidget(QWidget, Ui_IdentitiesTab):
                 certified_by = [p for p in account_connections
                           if p.pubkey not in [i.pubkey for i in certifiers_of]]
                 identities = certifiers_of + certified_by
-                self.busy.hide()
+                self.ui.busy.hide()
                 await self.refresh_identities(identities)
             except NoPeerAvailable:
-                self.busy.hide()
+                self.ui.busy.hide()
 
     async def refresh_identities(self, identities):
         """
         Refresh the table with specified identities.
         If no identities is passed, use the account connections.
         """
-        await self.table_identities.model().sourceModel().refresh_identities(identities)
-        self.table_identities.resizeColumnsToContents()
+        await self.ui.table_identities.model().sourceModel().refresh_identities(identities)
+        self.ui.table_identities.resizeColumnsToContents()
 
     def retranslateUi(self, widget):
         self.direct_connections.setText(self.tr(IdentitiesTabWidget._direct_connections_text))
         super().retranslateUi(self)
 
     def resizeEvent(self, event):
-        self.busy.resize(event.size())
+        self.ui.busy.resize(event.size())
         super().resizeEvent(event)
 
     def changeEvent(self, event):
diff --git a/src/sakia/gui/informations_tab.py b/src/sakia/gui/informations_tab.py
index bfad9b2f535dcc205a324538fe00a965aac780fd..790556d52ccf8e4de8b76b6354fa73bc49796139 100644
--- a/src/sakia/gui/informations_tab.py
+++ b/src/sakia/gui/informations_tab.py
@@ -70,7 +70,7 @@ class InformationsTabWidget(QWidget, Ui_InformationsTabWidget):
             logging.debug('community get_ud_block error : ' + str(e))
             return False
         try:
-            block_ud_minus_1 = await self.community.get_ud_block(1)
+            block_ud_minus_1 = await self.community.get_ud_block(x=1)
         except NoPeerAvailable as e:
             logging.debug('community get_ud_block error : ' + str(e))
             return False
@@ -125,15 +125,15 @@ class InformationsTabWidget(QWidget, Ui_InformationsTabWidget):
                 """).format(
                     localized_ud,
                     self.tr('Universal Dividend UD(t) in'),
-                    self.account.current_ref.diff_units(self.community.currency),
+                    self.account.current_ref(0, self.community, self.app, None).diff_units,
                     localized_mass_minus_1,
                     self.tr('Monetary Mass M(t-1) in'),
-                    self.account.current_ref.diff_units(self.community.currency),
+                    self.account.current_ref(0, self.community, self.app, None).units,
                     block_ud['membersCount'],
                     self.tr('Members N(t)'),
                     localized_mass_minus_1_per_member,
                     self.tr('Monetary Mass per member M(t-1)/N(t) in'),
-                    self.account.current_ref.diff_units(self.community.currency),
+                    self.account.current_ref(0, self.community, self.app, None).diff_units,
                     float(0) if block_ud['membersCount'] == 0 or block_ud_minus_1['monetaryMass'] == 0 else
                     block_ud['dividend'] / (block_ud_minus_1['monetaryMass'] / block_ud['membersCount']),
 
@@ -179,10 +179,10 @@ class InformationsTabWidget(QWidget, Ui_InformationsTabWidget):
                     self.tr('{:} = MAX {{ {:} {:} ; {:2.0%} &#215; {:} {:} / {:} }}').format(
                         localized_ud_plus_1,
                         localized_ud,
-                        self.account.current_ref.diff_units(self.community.currency),
+                        self.account.current_ref(0, self.community, self.app, None).diff_units,
                         params['c'],
                         localized_mass,
-                        self.account.current_ref.diff_units(self.community.currency),
+                        self.account.current_ref(0, self.community, self.app, None).diff_units,
                         block_ud['membersCount']
                     ),
                     self.tr('Universal Dividend (computed)')
diff --git a/src/sakia/gui/mainwindow.py b/src/sakia/gui/mainwindow.py
index a7f6e69ef671ec613ee7fd21e60a4f57e6b7ae49..808ce45a8cd7eaae3ae479da77da5133e1d943eb 100644
--- a/src/sakia/gui/mainwindow.py
+++ b/src/sakia/gui/mainwindow.py
@@ -54,9 +54,12 @@ class MainWindow(QMainWindow, Ui_MainWindow):
 
         self.app.version_requested.connect(self.latest_version_requested)
 
+        self.label_icon = QLabel("", self)
+        self.statusbar.addPermanentWidget(self.label_icon, 1)
+
         self.status_label = QLabel("", self)
         self.status_label.setTextFormat(Qt.RichText)
-        self.statusbar.addPermanentWidget(self.status_label, 1)
+        self.statusbar.addPermanentWidget(self.status_label, 2)
 
         self.label_time = QLabel("", self)
         self.statusbar.addPermanentWidget(self.label_time)
@@ -76,7 +79,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
         self.centralWidget().layout().addWidget(self.homescreen)
         self.homescreen.toolbutton_connect.setMenu(self.menu_change_account)
 
-        self.community_view = CommunityWidget(self.app, self.status_label)
+        self.community_view = CommunityWidget(self.app, self.status_label, self.label_icon)
         self.community_view.button_home.clicked.connect(lambda: self.change_community(None))
         self.community_view.button_certification.clicked.connect(self.open_certification_dialog)
         self.community_view.button_send_money.clicked.connect(self.open_transfer_money_dialog)
@@ -173,14 +176,13 @@ class MainWindow(QMainWindow, Ui_MainWindow):
                                      self.password_asker,
                                      self.community_view.community,
                                      None)
-        if dialog.exec_() == QDialog.Accepted:
+        if dialog.exec() == QDialog.Accepted:
             self.community_view.tab_history.table_history.model().sourceModel().refresh_transfers()
 
     def open_certification_dialog(self):
-        dialog = CertificationDialog(self.app,
+        CertificationDialog.open_dialog(self.app,
                                      self.app.current_account,
                                      self.password_asker)
-        dialog.exec_()
 
     def open_add_contact_dialog(self):
         dialog = ConfigureContactDialog(self.app.current_account, self)
diff --git a/src/sakia/gui/member.py b/src/sakia/gui/member.py
index 0b7fe87e4ef59d1db500e8628fa09ee8554b8e66..406ab6abafa8d40ae376d72c01da008cfee83f0d 100644
--- a/src/sakia/gui/member.py
+++ b/src/sakia/gui/member.py
@@ -1,20 +1,21 @@
 import datetime
-import asyncio
 
-from PyQt5.QtWidgets import QDialog
+from PyQt5.QtCore import QObject, QEvent, QLocale, QDateTime
+from PyQt5.QtWidgets import QDialog, QWidget
 
 from ..core.graph import WoTGraph
+from .widgets.busy import Busy
 from ..tools.decorators import asyncify
-from ..gen_resources.member_uic import Ui_DialogMember
+from ..gen_resources.member_uic import Ui_MemberView
 from ..tools.exceptions import MembershipNotFoundError
 
 
-class MemberDialog(QDialog, Ui_DialogMember):
+class MemberDialog(QObject):
     """
-    classdocs
+    A widget showing informations about a member
     """
 
-    def __init__(self, app, account, community, identity):
+    def __init__(self, app, account, community, identity, widget, ui):
         """
         Init MemberDialog
 
@@ -22,30 +23,80 @@ class MemberDialog(QDialog, Ui_DialogMember):
         :param sakia.core.account.Account account:   Account instance
         :param sakia.core.community.Community community: Community instance
         :param sakia.core.registry.identity.Identity identity: Identity instance
+        :param PyQt5.QtWidget widget: The class of the widget
+        :param sakia.gen_resources.member_uic.Ui_DialogMember ui: the class of the ui applyed to the widget
         :return:
         """
         super().__init__()
-        self.setupUi(self)
+        self.widget = widget
+        self.ui = ui
+        self.ui.setupUi(self.widget)
+        self.ui.busy = Busy(self.widget)
+        self.widget.installEventFilter(self)
         self.app = app
         self.community = community
         self.account = account
         self.identity = identity
-        self.label_uid.setText(identity.uid)
-        self.refresh()
+
+    @classmethod
+    def open_dialog(cls, app, account, community, identity):
+        dialog = cls(app, account, community, identity, QDialog(), Ui_MemberView())
+        dialog.refresh()
+        dialog.refresh_path()
+        dialog.exec()
+
+    @classmethod
+    def as_widget(cls, parent_widget, app, account, community, identity):
+        return cls(app, account, community, identity, QWidget(parent_widget), Ui_MemberView())
 
     @asyncify
     async def refresh(self):
+        if self.identity:
+            self.ui.busy.show()
+            self.ui.label_uid.setText(self.identity.uid)
+            self.ui.label_properties.setText("")
+            try:
+                join_date = await self.identity.get_join_date(self.community)
+            except MembershipNotFoundError:
+                join_date = None
+
+            if join_date is None:
+                join_date = self.tr('not a member')
+            else:
+                join_date = datetime.datetime.fromtimestamp(join_date).strftime("%d/%m/%Y %I:%M")
+
 
-        try:
-            join_date = await self.identity.get_join_date(self.community)
-        except MembershipNotFoundError:
-            join_date = None
+            identity_selfcert = await self.identity.selfcert(self.community)
+            uid_publish_date = QLocale.toString(
+                    QLocale(),
+                    QDateTime.fromTime_t(identity_selfcert.timestamp),
+                    QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat)
+                )
 
-        if join_date is None:
-            join_date = self.tr('not a member')
-        else:
-            join_date = datetime.datetime.fromtimestamp(join_date).strftime("%d/%m/%Y %I:%M")
+            text = self.tr("""
+                <table cellpadding="5">
+                <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr>
+                <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr>
+                <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr>
+                """).format(
+                self.tr('Public key'),
+                self.identity.pubkey,
+                self.tr('UID Published on'),
+                uid_publish_date,
+                self.tr('Join date'),
+                join_date
+            )
+            # close html text
+            text += "</table>"
 
+            # set text in label
+            self.ui.label_properties.setText(text)
+            self.ui.busy.hide()
+
+    @asyncify
+    async def refresh_path(self):
+        text = ""
+        self.ui.label_path.setText("")
         # calculate path to account member
         graph = WoTGraph(self.app, self.community)
         path = None
@@ -56,17 +107,6 @@ class MemberDialog(QDialog, Ui_DialogMember):
             path = await graph.get_shortest_path_to_identity(self.identity,
                                                             account_identity)
 
-        text = self.tr("""
-            <table cellpadding="5">
-            <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr>
-            <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr>
-            """).format(
-            self.tr('Public key'),
-            self.identity.pubkey,
-            self.tr('Join date'),
-            join_date
-        )
-
         if path:
             distance = len(path) - 1
             text += self.tr(
@@ -76,18 +116,26 @@ class MemberDialog(QDialog, Ui_DialogMember):
                 index = 0
                 for node in path:
                     if index == 0:
-                        text += self.tr("""<tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr>""").format(
+                        text += self.tr("""<tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr>""")\
+                            .format(
                             self.tr('Path'), node['text'])
                     else:
-                        text += self.tr("""<tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr>""").format('',
-                                                                                                                   node[
-                                                                                                                       'text'])
+                        text += self.tr("""<tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr>""")\
+                            .format('',
+                                   node[
+                                       'text'])
                     if index == distance and node['id'] != self.account.pubkey:
-                        text += self.tr("""<tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr>""").format('',
-                                                                                                                   self.account.name)
+                        text += self.tr("""<tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr>""")\
+                            .format('',
+                                   self.account.name)
                     index += 1
-        # close html text
-        text += "</table>"
+        self.ui.label_path.setText(text)
+
+    def eventFilter(self, source, event):
+        if event.type() == QEvent.Resize:
+            self.ui.busy.resize(event.size())
+            self.widget.resizeEvent(event)
+        return self.widget.eventFilter(source, event)
 
-        # set text in label
-        self.label_properties.setText(text)
+    def exec(self):
+        self.widget.exec()
diff --git a/src/sakia/gui/transactions_tab.py b/src/sakia/gui/transactions_tab.py
index b35cf48c9538690e6699c68cfce87addf051c401..cead5a8578d629063199e5d4382f8432e65ec0c6 100644
--- a/src/sakia/gui/transactions_tab.py
+++ b/src/sakia/gui/transactions_tab.py
@@ -1,68 +1,69 @@
 import logging
 import asyncio
 
-from PyQt5.QtWidgets import QWidget, QAbstractItemView, QHeaderView, QDialog, \
-    QMenu, QAction, QApplication, QMessageBox
-from PyQt5.QtCore import Qt, QDateTime, QTime, QModelIndex, pyqtSignal, pyqtSlot, QEvent
-
+from PyQt5.QtWidgets import QWidget, QAbstractItemView, QHeaderView
+from PyQt5.QtCore import Qt, QObject, QDateTime, QTime, QModelIndex, pyqtSignal, pyqtSlot, QEvent
 from PyQt5.QtGui import QCursor
 
 from ..gen_resources.transactions_tab_uic import Ui_transactionsTabWidget
 from ..models.txhistory import HistoryTableModel, TxFilterProxyModel
-from ..core.transfer import Transfer, TransferState
-from .contact import ConfigureContactDialog
-from .member import MemberDialog
-from .certification import CertificationDialog
-from ..core.wallet import Wallet
-from ..core.registry import Identity
 from ..tools.exceptions import NoPeerAvailable
 from ..tools.decorators import asyncify, once_at_a_time, cancel_once_task
-from .transfer import TransferMoneyDialog
+from .widgets.context_menu import ContextMenu
 from sakia.gui.widgets import toast
-from sakia.gui.widgets.busy import Busy
 
 
-class TransactionsTabWidget(QWidget, Ui_transactionsTabWidget):
+class TransactionsTabWidget(QObject):
     """
     classdocs
     """
-    view_in_wot = pyqtSignal(Identity)
+    view_in_wot = pyqtSignal(object)
 
-    def __init__(self, app):
+    def __init__(self, app, account=None, community=None, password_asker=None,
+                 widget=QWidget, view=Ui_transactionsTabWidget):
         """
         Init
 
         :param sakia.core.app.Application app: Application instance
-        :return:
+        :param sakia.core.Account account: The account displayed in the widget
+        :param sakia.core.Community community: The community displayed in the widget
+        :param sakia.gui.Password_Asker: password_asker: The widget to ask for passwords
+        :param class widget: The class of the PyQt5 widget used for this tab
+        :param class view: The class of the UI View for this tab
         """
 
         super().__init__()
-        self.setupUi(self)
+        self.widget = widget()
+        self.ui = view()
+        self.ui.setupUi(self.widget)
         self.app = app
-        self.account = None
-        self.community = None
-        self.password_asker = None
-        self.busy_balance = Busy(self.groupbox_balance)
-        self.busy_balance.hide()
-
-        ts_from = self.date_from.dateTime().toTime_t()
-        ts_to = self.date_to.dateTime().toTime_t()
+        self.account = account
+        self.community = community
+        self.password_asker = password_asker
+        self.ui.busy_balance.hide()
+
+        ts_from = self.ui.date_from.dateTime().toTime_t()
+        ts_to = self.ui.date_to.dateTime().toTime_t()
         model = HistoryTableModel(self.app, self.account, self.community)
         proxy = TxFilterProxyModel(ts_from, ts_to)
         proxy.setSourceModel(model)
         proxy.setDynamicSortFilter(True)
         proxy.setSortRole(Qt.DisplayRole)
 
-        self.table_history.setModel(proxy)
-        self.table_history.setSelectionBehavior(QAbstractItemView.SelectRows)
-        self.table_history.setSortingEnabled(True)
-        self.table_history.horizontalHeader().setSectionResizeMode(QHeaderView.Interactive)
-        self.table_history.resizeColumnsToContents()
+        self.ui.table_history.setModel(proxy)
+        self.ui.table_history.setSelectionBehavior(QAbstractItemView.SelectRows)
+        self.ui.table_history.setSortingEnabled(True)
+        self.ui.table_history.horizontalHeader().setSectionResizeMode(QHeaderView.Interactive)
+        self.ui.table_history.resizeColumnsToContents()
 
-        model.modelAboutToBeReset.connect(lambda: self.table_history.setEnabled(False))
-        model.modelReset.connect(lambda: self.table_history.setEnabled(True))
+        self.ui.table_history.customContextMenuRequested['QPoint'].connect(self.history_context_menu)
+        self.ui.date_from.dateChanged['QDate'].connect(self.dates_changed)
+        self.ui.date_to.dateChanged['QDate'].connect(self.dates_changed)
 
-        self.progressbar.hide()
+        model.modelAboutToBeReset.connect(lambda: self.ui.table_history.setEnabled(False))
+        model.modelReset.connect(lambda: self.ui.table_history.setEnabled(True))
+
+        self.ui.progressbar.hide()
         self.refresh()
 
     def cancel_once_tasks(self):
@@ -74,15 +75,15 @@ class TransactionsTabWidget(QWidget, Ui_transactionsTabWidget):
         self.cancel_once_tasks()
         self.account = account
         self.password_asker = password_asker
-        self.table_history.model().sourceModel().change_account(account)
+        self.ui.table_history.model().sourceModel().change_account(account)
         if account:
             self.connect_progress()
 
     def change_community(self, community):
         self.cancel_once_tasks()
         self.community = community
-        self.progressbar.hide()
-        self.table_history.model().sourceModel().change_community(self.community)
+        self.ui.progressbar.hide()
+        self.ui.table_history.model().sourceModel().change_community(self.community)
         self.refresh()
 
     @once_at_a_time
@@ -94,14 +95,14 @@ class TransactionsTabWidget(QWidget, Ui_transactionsTabWidget):
             minimum_datetime.setTime_t(block['medianTime'])
             minimum_datetime.setTime(QTime(0, 0))
 
-            self.date_from.setMinimumDateTime(minimum_datetime)
-            self.date_from.setDateTime(minimum_datetime)
-            self.date_from.setMaximumDateTime(QDateTime().currentDateTime())
+            self.ui.date_from.setMinimumDateTime(minimum_datetime)
+            self.ui.date_from.setDateTime(minimum_datetime)
+            self.ui.date_from.setMaximumDateTime(QDateTime().currentDateTime())
 
-            self.date_to.setMinimumDateTime(minimum_datetime)
+            self.ui.date_to.setMinimumDateTime(minimum_datetime)
             tomorrow_datetime = QDateTime().currentDateTime().addDays(1)
-            self.date_to.setDateTime(tomorrow_datetime)
-            self.date_to.setMaximumDateTime(tomorrow_datetime)
+            self.ui.date_to.setDateTime(tomorrow_datetime)
+            self.ui.date_to.setMaximumDateTime(tomorrow_datetime)
         except NoPeerAvailable as e:
             logging.debug(str(e))
         except ValueError as e:
@@ -109,25 +110,25 @@ class TransactionsTabWidget(QWidget, Ui_transactionsTabWidget):
 
     def refresh(self):
         if self.community:
-            self.table_history.model().sourceModel().refresh_transfers()
-            self.table_history.resizeColumnsToContents()
+            self.ui.table_history.model().sourceModel().refresh_transfers()
+            self.ui.table_history.resizeColumnsToContents()
             self.refresh_minimum_maximum()
             self.refresh_balance()
 
     def connect_progress(self):
         def progressing(community, value, maximum):
             if community == self.community:
-                self.progressbar.show()
-                self.progressbar.setValue(value)
-                self.progressbar.setMaximum(maximum)
+                self.ui.progressbar.show()
+                self.ui.progressbar.setValue(value)
+                self.ui.progressbar.setMaximum(maximum)
         self.account.loading_progressed.connect(progressing)
         self.account.loading_finished.connect(self.stop_progress)
 
     def stop_progress(self, community, received_list):
         if community == self.community:
-            self.progressbar.hide()
-            self.table_history.model().sourceModel().refresh_transfers()
-            self.table_history.resizeColumnsToContents()
+            self.ui.progressbar.hide()
+            self.ui.table_history.model().sourceModel().refresh_transfers()
+            self.ui.table_history.resizeColumnsToContents()
             self.notification_reception(received_list)
 
     @asyncify
@@ -148,162 +149,60 @@ class TransactionsTabWidget(QWidget, Ui_transactionsTabWidget):
     @once_at_a_time
     @asyncify
     async def refresh_balance(self):
-        self.busy_balance.show()
+        self.ui.busy_balance.show()
         amount = await self.app.current_account.amount(self.community)
         localized_amount = await self.app.current_account.current_ref(amount, self.community,
                                                                            self.app).localized(units=True,
                                         international_system=self.app.preferences['international_system_of_units'])
 
         # set infos in label
-        self.label_balance.setText(
+        self.ui.label_balance.setText(
             self.tr("{:}")
             .format(
                 localized_amount
             )
         )
-        self.busy_balance.hide()
+        self.ui.busy_balance.hide()
 
     @once_at_a_time
     @asyncify
     async def history_context_menu(self, point):
-        index = self.table_history.indexAt(point)
-        model = self.table_history.model()
+        index = self.ui.table_history.indexAt(point)
+        model = self.ui.table_history.model()
         if index.isValid() and index.row() < model.rowCount(QModelIndex()):
-            menu = QMenu(self.tr("Actions"), self)
             source_index = model.mapToSource(index)
-            state_col = model.sourceModel().columns_types.index('state')
-            state_index = model.sourceModel().index(source_index.row(),
-                                                   state_col)
-            state_data = model.sourceModel().data(state_index, Qt.DisplayRole)
 
             pubkey_col = model.sourceModel().columns_types.index('pubkey')
             pubkey_index = model.sourceModel().index(source_index.row(),
                                                     pubkey_col)
             pubkey = model.sourceModel().data(pubkey_index, Qt.DisplayRole)
+
             identity = await self.app.identities_registry.future_find(pubkey, self.community)
 
             transfer = model.sourceModel().transfers()[source_index.row()]
-            if state_data == TransferState.REFUSED or state_data == TransferState.TO_SEND:
-                send_back = QAction(self.tr("Send again"), self)
-                send_back.triggered.connect(lambda checked, tr=transfer: self.send_again(checked, tr))
-                send_back.setData(transfer)
-                menu.addAction(send_back)
-
-                cancel = QAction(self.tr("Cancel"), self)
-                cancel.triggered.connect(self.cancel_transfer)
-                cancel.setData(transfer)
-                menu.addAction(cancel)
-            else:
-                if isinstance(identity, Identity):
-                    informations = QAction(self.tr("Informations"), self)
-                    informations.triggered.connect(self.menu_informations)
-                    informations.setData(identity)
-                    menu.addAction(informations)
-
-                    add_as_contact = QAction(self.tr("Add as contact"), self)
-                    add_as_contact.triggered.connect(self.menu_add_as_contact)
-                    add_as_contact.setData(identity)
-                    menu.addAction(add_as_contact)
-
-                send_money = QAction(self.tr("Send money"), self)
-                send_money.triggered.connect(self.menu_send_money)
-                send_money.setData(identity)
-                menu.addAction(send_money)
-
-                if isinstance(identity, Identity):
-                    view_wot = QAction(self.tr("View in Web of Trust"), self)
-                    view_wot.triggered.connect(self.view_wot)
-                    view_wot.setData(identity)
-                    menu.addAction(view_wot)
-
-            copy_pubkey = QAction(self.tr("Copy pubkey to clipboard"), self)
-            copy_pubkey.triggered.connect(self.copy_pubkey_to_clipboard)
-            copy_pubkey.setData(identity)
-            menu.addAction(copy_pubkey)
+            menu = ContextMenu.from_data(self.widget, self.app, self.account, self.community, self.password_asker,
+                                         (identity, transfer))
+            menu.view_identity_in_wot.connect(self.view_in_wot)
 
             # Show the context menu.
-            menu.popup(QCursor.pos())
-
-    def copy_pubkey_to_clipboard(self):
-        data = self.sender().data()
-        clipboard = QApplication.clipboard()
-        if data.__class__ is Wallet:
-            clipboard.setText(data.pubkey)
-        elif data.__class__ is Identity:
-            clipboard.setText(data.pubkey)
-        elif data.__class__ is str:
-            clipboard.setText(data)
-
-    def menu_informations(self):
-        person = self.sender().data()
-        self.identity_informations(person)
-
-    def menu_add_as_contact(self):
-        person = self.sender().data()
-        self.add_identity_as_contact({'name': person.uid,
-                                    'pubkey': person.pubkey})
-
-    def menu_send_money(self):
-        identity = self.sender().data()
-        self.send_money_to_identity(identity)
-
-    def identity_informations(self, person):
-        dialog = MemberDialog(self.app, self.account, self.community, person)
-        dialog.exec_()
-
-    def add_identity_as_contact(self, person):
-        dialog = ConfigureContactDialog(self.account, self.window(), person)
-        result = dialog.exec_()
-        if result == QDialog.Accepted:
-            self.window().refresh_contacts()
-
-    @asyncify
-    async def send_money_to_identity(self, identity):
-        await TransferMoneyDialog.send_money_to_identity(self.app, self.account, self.password_asker,
-                                                            self.community, identity)
-        self.table_history.model().sourceModel().refresh_transfers()
-
-    @asyncify
-    async def certify_identity(self, identity):
-        await CertificationDialog.certify_identity(self.app, self.account, self.password_asker,
-                                             self.community, identity)
-
-    def view_wot(self):
-        identity = self.sender().data()
-        self.view_in_wot.emit(identity)
-
-    @asyncify
-    async def send_again(self, checked=False, transfer=None):
-        result = await TransferMoneyDialog.send_transfer_again(self.app, self.app.current_account,
-                                     self.password_asker, self.community, transfer)
-        self.table_history.model().sourceModel().refresh_transfers()
-
-    def cancel_transfer(self):
-        reply = QMessageBox.warning(self, self.tr("Warning"),
-                             self.tr("""Are you sure ?
-This money transfer will be removed and not sent."""),
-QMessageBox.Ok | QMessageBox.Cancel)
-        if reply == QMessageBox.Ok:
-            transfer = self.sender().data()
-            transfer.cancel()
-            self.table_history.model().sourceModel().refresh_transfers()
+            menu.qmenu.popup(QCursor.pos())
 
     def dates_changed(self):
         logging.debug("Changed dates")
-        if self.table_history.model():
-            qdate_from = self.date_from
+        if self.ui.table_history.model():
+            qdate_from = self.ui.date_from
             qdate_from.setTime(QTime(0, 0, 0))
-            qdate_to = self.date_to
+            qdate_to = self.ui.date_to
             qdate_to.setTime(QTime(0, 0, 0))
             ts_from = qdate_from.dateTime().toTime_t()
             ts_to = qdate_to.dateTime().toTime_t()
 
-            self.table_history.model().set_period(ts_from, ts_to)
+            self.ui.table_history.model().set_period(ts_from, ts_to)
 
             self.refresh_balance()
 
     def resizeEvent(self, event):
-        self.busy_balance.resize(event.size())
+        self.ui.busy_balance.resize(event.size())
         super().resizeEvent(event)
 
     def changeEvent(self, event):
diff --git a/src/sakia/gui/transfer.py b/src/sakia/gui/transfer.py
index e97939ee51759746d6628e34d4fc24195c274b2f..69847078168e6ddf58397af743d08c758fcd2156 100644
--- a/src/sakia/gui/transfer.py
+++ b/src/sakia/gui/transfer.py
@@ -6,7 +6,7 @@ Created on 2 févr. 2014
 import asyncio
 
 from PyQt5.QtWidgets import QDialog, QApplication
-from PyQt5.QtCore import QRegExp, Qt
+from PyQt5.QtCore import QRegExp, Qt, QObject
 
 from PyQt5.QtGui import QRegExpValidator
 
@@ -16,24 +16,31 @@ from sakia.gui.widgets.dialogs import QAsyncMessageBox, QMessageBox
 from ..tools.decorators import asyncify
 
 
-class TransferMoneyDialog(QDialog, Ui_TransferMoneyDialog):
+class TransferMoneyDialog(QObject):
 
     """
     classdocs
     """
 
-    def __init__(self, app, sender, password_asker, community, transfer):
+    def __init__(self, app, account, password_asker, community, transfer, widget=QDialog, view=Ui_TransferMoneyDialog):
         """
         Constructor
         :param sakia.core.Application app: The application
-        :param sakia.core.Account sender: The sender
+        :param sakia.core.Account account: The account
         :param sakia.gui.password_asker.Password_Asker password_asker: The password asker
+        :param sakia.core.Community community:
+        :param sakia.core.Transfer transfer:
+        :param class widget:
+        :param class view:
         :return:
         """
         super().__init__()
-        self.setupUi(self)
+        self.widget = widget()
+        self.ui = view()
+        self.ui.setupUi(self.widget)
+
         self.app = app
-        self.account = sender
+        self.account = account
         self.password_asker = password_asker
         self.recipient_trusts = []
         self.transfer = transfer
@@ -41,41 +48,54 @@ class TransferMoneyDialog(QDialog, Ui_TransferMoneyDialog):
         self.community = community if community else self.account.communities[0]
         self.wallet = self.account.wallets[0]
 
+        self.ui.radio_contact.toggled.connect(lambda c, radio="contact": self.recipient_mode_changed(radio))
+        self.ui.radio_pubkey.toggled.connect(lambda c, radio="pubkey": self.recipient_mode_changed(radio))
+        self.ui.radio_search.toggled.connect(lambda c, radio="search": self.recipient_mode_changed(radio))
+        self.ui.button_box.accepted.connect(self.accept)
+        self.ui.button_box.rejected.connect(self.widget.reject)
+        self.ui.combo_wallets.currentIndexChanged.connect(self.change_displayed_wallet)
+        self.ui.combo_community.currentIndexChanged.connect(self.change_current_community)
+        self.ui.spinbox_relative.valueChanged.connect(self.relative_amount_changed)
+        self.ui.spinbox_amount.valueChanged.connect(self.amount_changed)
+        self.ui.search_user.button_reset.hide()
+        self.ui.search_user.init(self.app)
+        self.ui.search_user.change_account(self.account)
+        self.ui.search_user.change_community(self.community)
+
         regexp = QRegExp('^([ a-zA-Z0-9-_:/;*?\[\]\(\)\\\?!^+=@&~#{}|<>%.]{0,255})$')
         validator = QRegExpValidator(regexp)
-        self.edit_message.setValidator(validator)
+        self.ui.edit_message.setValidator(validator)
 
         for community in self.account.communities:
-            self.combo_community.addItem(community.currency)
+            self.ui.combo_community.addItem(community.currency)
 
         for wallet in self.account.wallets:
-            self.combo_wallets.addItem(wallet.name)
+            self.ui.combo_wallets.addItem(wallet.name)
 
-        for contact_name in sorted([c['name'] for c in sender.contacts], key=str.lower):
-            self.combo_contact.addItem(contact_name)
+        for contact_name in sorted([c['name'] for c in account.contacts], key=str.lower):
+            self.ui.combo_contact.addItem(contact_name)
 
         if len(self.account.contacts) == 0:
-            self.combo_contact.setEnabled(False)
-            self.radio_contact.setEnabled(False)
-            self.radio_pubkey.setChecked(True)
+            self.ui.combo_contact.setEnabled(False)
+            self.ui.radio_contact.setEnabled(False)
+            self.ui.radio_pubkey.setChecked(True)
 
-        self.combo_community.setCurrentText(self.community.name)
+        self.ui.combo_community.setCurrentText(self.community.name)
 
         if self.transfer:
-            sender = self.transfer.metadata['issuer']
-            wallet_index = [w.pubkey for w in app.current_account.wallets].index(sender)
-            self.combo_wallets.setCurrentIndex(wallet_index)
-            self.edit_pubkey.setText(transfer.metadata['receiver'])
-            self.radio_pubkey.setChecked(True)
-            self.edit_message.setText(transfer.metadata['comment'])
-
+            account = self.transfer.metadata['issuer']
+            wallet_index = [w.pubkey for w in app.current_account.wallets].index(account)
+            self.ui.combo_wallets.setCurrentIndex(wallet_index)
+            self.ui.edit_pubkey.setText(transfer.metadata['receiver'])
+            self.ui.radio_pubkey.setChecked(True)
+            self.ui.edit_message.setText(transfer.metadata['comment'])
 
     @classmethod
     async def send_money_to_identity(cls, app, account, password_asker, community, identity):
         dialog = cls(app, account, password_asker, community, None)
         dialog.edit_pubkey.setText(identity.pubkey)
         dialog.radio_pubkey.setChecked(True)
-        return (await dialog.async_exec())
+        return await dialog.async_exec()
 
     @classmethod
     async def send_transfer_again(cls, app, account, password_asker, community, transfer):
@@ -86,25 +106,32 @@ class TransferMoneyDialog(QDialog, Ui_TransferMoneyDialog):
         dialog.spinbox_relative.setMaximum(relative)
         dialog.spinbox_amount.setValue(transfer.metadata['amount'])
 
-        return (await dialog.async_exec())
+        return await dialog.async_exec()
 
     @asyncify
     async def accept(self):
-        comment = self.edit_message.text()
+        self.ui.button_box.setEnabled(False)
+        comment = self.ui.edit_message.text()
 
-        if self.radio_contact.isChecked():
+        if self.ui.radio_contact.isChecked():
             for contact in self.account.contacts:
-                if contact['name'] == self.combo_contact.currentText():
+                if contact['name'] == self.ui.combo_contact.currentText():
                     recipient = contact['pubkey']
                     break
+        elif self.ui.radio_search.isChecked():
+            if self.ui.search_user.current_identity():
+                recipient = self.ui.search_user.current_identity().pubkey
+            else:
+                return
         else:
-            recipient = self.edit_pubkey.text()
-        amount = self.spinbox_amount.value()
+            recipient = self.ui.edit_pubkey.text()
+        amount = self.ui.spinbox_amount.value()
 
         if not amount:
             await QAsyncMessageBox.critical(self, self.tr("Money transfer"),
                                  self.tr("No amount. Please give the transfert amount"),
                                  QMessageBox.Ok)
+            self.ui.button_box.setEnabled(True)
             return
 
         password = await self.password_asker.async_exec()
@@ -120,7 +147,7 @@ class TransferMoneyDialog(QDialog, Ui_TransferMoneyDialog):
                 toast.display(self.tr("Transfer"),
                           self.tr("Success sending money to {0}").format(recipient))
             else:
-                await QAsyncMessageBox.information(self, self.tr("Transfer"),
+                await QAsyncMessageBox.information(self.widget, self.tr("Transfer"),
                           self.tr("Success sending money to {0}").format(recipient))
             QApplication.restoreOverrideCursor()
 
@@ -128,30 +155,31 @@ class TransferMoneyDialog(QDialog, Ui_TransferMoneyDialog):
             if self.transfer:
                 self.transfer.cancel()
 
-            super().accept()
+            self.widget.accept()
         else:
             if self.app.preferences['notifications']:
                 toast.display(self.tr("Transfer"), "Error : {0}".format(result[1]))
             else:
-                await QAsyncMessageBox.critical(self, self.tr("Transfer"), result[1])
+                await QAsyncMessageBox.critical(self.widget, self.tr("Transfer"), result[1])
 
             QApplication.restoreOverrideCursor()
+            self.ui.button_box.setEnabled(True)
 
     @asyncify
     async def amount_changed(self, value):
         dividend = await self.community.dividend()
         relative = value / dividend
-        self.spinbox_relative.blockSignals(True)
-        self.spinbox_relative.setValue(relative)
-        self.spinbox_relative.blockSignals(False)
+        self.ui.spinbox_relative.blockSignals(True)
+        self.ui.spinbox_relative.setValue(relative)
+        self.ui.spinbox_relative.blockSignals(False)
 
     @asyncify
     async def relative_amount_changed(self, value):
         dividend = await self.community.dividend()
         amount = value * dividend
-        self.spinbox_amount.blockSignals(True)
-        self.spinbox_amount.setValue(amount)
-        self.spinbox_amount.blockSignals(False)
+        self.ui.spinbox_amount.blockSignals(True)
+        self.ui.spinbox_amount.setValue(amount)
+        self.ui.spinbox_amount.blockSignals(False)
 
     @asyncify
     async def change_current_community(self, index):
@@ -161,13 +189,13 @@ class TransferMoneyDialog(QDialog, Ui_TransferMoneyDialog):
         ref_text = await self.account.current_ref(amount, self.community, self.app)\
             .diff_localized(units=True,
                             international_system=self.app.preferences['international_system_of_units'])
-        self.label_total.setText("{0}".format(ref_text))
-        self.spinbox_amount.setSuffix(" " + self.community.currency)
+        self.ui.label_total.setText("{0}".format(ref_text))
+        self.ui.spinbox_amount.setSuffix(" " + self.community.currency)
         amount = await self.wallet.value(self.community)
         dividend = await self.community.dividend()
         relative = amount / dividend
-        self.spinbox_amount.setMaximum(amount)
-        self.spinbox_relative.setMaximum(relative)
+        self.ui.spinbox_amount.setMaximum(amount)
+        self.ui.spinbox_relative.setMaximum(relative)
 
     @asyncify
     async def change_displayed_wallet(self, index):
@@ -176,19 +204,23 @@ class TransferMoneyDialog(QDialog, Ui_TransferMoneyDialog):
         ref_text = await self.account.current_ref(amount, self.community, self.app)\
             .diff_localized(units=True,
                             international_system=self.app.preferences['international_system_of_units'])
-        self.label_total.setText("{0}".format(ref_text))
+        self.ui.label_total.setText("{0}".format(ref_text))
         amount = await self.wallet.value(self.community)
         dividend = await self.community.dividend()
         relative = amount / dividend
-        self.spinbox_amount.setMaximum(amount)
-        self.spinbox_relative.setMaximum(relative)
+        self.ui.spinbox_amount.setMaximum(amount)
+        self.ui.spinbox_relative.setMaximum(relative)
 
-    def recipient_mode_changed(self, pubkey_toggled):
-        self.edit_pubkey.setEnabled(pubkey_toggled)
-        self.combo_contact.setEnabled(not pubkey_toggled)
+    def recipient_mode_changed(self, radio):
+        self.ui.edit_pubkey.setEnabled(radio == "pubkey")
+        self.ui.combo_contact.setEnabled(radio == "contact")
+        self.ui.search_user.setEnabled(radio == "search")
 
     def async_exec(self):
         future = asyncio.Future()
-        self.finished.connect(lambda r: future.set_result(r))
-        self.open()
+        self.widget.finished.connect(lambda r: future.set_result(r))
+        self.widget.open()
         return future
+
+    def exec(self):
+        self.widget.exec()
\ No newline at end of file
diff --git a/src/sakia/gui/views/nodes/base_node.py b/src/sakia/gui/views/nodes/base_node.py
index f486d1c556f02bb0d5876a8b953e0ebda91bd42e..04aadd2f43f37099306b6751f48bda7d4972658b 100644
--- a/src/sakia/gui/views/nodes/base_node.py
+++ b/src/sakia/gui/views/nodes/base_node.py
@@ -1,9 +1,8 @@
-from PyQt5.QtWidgets import QGraphicsEllipseItem, \
-    QMenu, QAction, QGraphicsSceneHoverEvent, \
+from PyQt5.QtWidgets import QGraphicsEllipseItem, QGraphicsSceneHoverEvent, \
     QGraphicsSceneContextMenuEvent
-from PyQt5.QtCore import Qt, QCoreApplication, QT_TRANSLATE_NOOP, pyqtSignal
+from PyQt5.QtCore import Qt
 from PyQt5.QtGui import QMouseEvent
-from sakia.core.graph.constants import NodeStatus
+from ....core.graph.constants import NodeStatus
 
 
 class BaseNode(QGraphicsEllipseItem):
@@ -65,68 +64,4 @@ class BaseNode(QGraphicsEllipseItem):
         #  no menu on the wallet node
         if self.status_wallet:
             return None
-        # create node context menus
-        self.menu = QMenu()
-        # action show member
-        QT_TRANSLATE_NOOP('WoT.Node', 'Informations')
-        self.action_show_member = QAction(QCoreApplication.translate('WoT.Node', 'Informations'), self.scene())
-        self.menu.addAction(self.action_show_member)
-        self.action_show_member.triggered.connect(self.member_action)
-        # action add identity as contact
-        QT_TRANSLATE_NOOP('WoT.Node', 'Add as contact')
-        self.action_contact = QAction(QCoreApplication.translate('WoT.Node', 'Add as contact'), self.scene())
-        self.menu.addAction(self.action_contact)
-        self.action_contact.triggered.connect(self.contact_action)
-        # action transaction toward identity
-        QT_TRANSLATE_NOOP('WoT.Node', 'Send money')
-        self.action_transaction = QAction(QCoreApplication.translate('WoT.Node', 'Send money'), self.scene())
-        self.menu.addAction(self.action_transaction)
-        self.action_transaction.triggered.connect(self.transaction_action)
-        # action sign identity
-        QT_TRANSLATE_NOOP('WoT.Node', 'Certify identity')
-        self.action_sign = QAction(QCoreApplication.translate('WoT.Node', 'Certify identity'), self.scene())
-        self.menu.addAction(self.action_sign)
-        self.action_sign.triggered.connect(self.sign_action)
-        # action copy identity pubkey
-        QT_TRANSLATE_NOOP('WoT.Node', 'Copy pubkey')
-        self.action_copy = QAction(QCoreApplication.translate('WoT.Node', 'Copy pubkey'), self.scene())
-        self.menu.addAction(self.action_copy)
-        self.action_copy.triggered.connect(self.copy_action)
-
-        # run menu
-        self.menu.exec(event.screenPos())
-
-    def member_action(self):
-        """
-        Transaction action to identity node
-        """
-        # trigger scene signal
-        self.scene().node_member.emit(self.id, self.metadata)
-
-    def contact_action(self):
-        """
-        Transaction action to identity node
-        """
-        # trigger scene signal
-        self.scene().node_contact.emit(self.id, self.metadata)
-
-    def sign_action(self):
-        """
-        Sign identity node
-        """
-        # trigger scene signal
-        self.scene().node_signed.emit(self.id, self.metadata)
-
-    def copy_action(self):
-        """
-        Copy identity node pubkey
-        """
-        # trigger scene signal
-        self.scene().node_copy_pubkey.emit(self.id)
-
-    def transaction_action(self):
-        """
-        Transaction action to identity node
-        """
-        # trigger scene signal
-        self.scene().node_transaction.emit(self.id, self.metadata)
+        self.scene().node_context_menu_requested.emit(self.id)
diff --git a/src/sakia/gui/views/nodes/explorer_node.py b/src/sakia/gui/views/nodes/explorer_node.py
index bedc9b9df18957407021d3a5e1058122b7cfa3ac..7f985e91950a9d25c3a4195568cd908892c7d827 100644
--- a/src/sakia/gui/views/nodes/explorer_node.py
+++ b/src/sakia/gui/views/nodes/explorer_node.py
@@ -3,7 +3,6 @@ from PyQt5.QtCore import Qt, QPointF, QTimeLine, QTimer
 from PyQt5.QtGui import QTransform, QColor, QPen, QBrush, QRadialGradient
 from ....core.graph.constants import NodeStatus
 from .base_node import BaseNode
-import logging
 import math
 
 
diff --git a/src/sakia/gui/views/scenes/base_scene.py b/src/sakia/gui/views/scenes/base_scene.py
index 7a4762b0c4926d4d9fc473c06b840c789828c3c6..36cd72880a4def8abc332cd47f0b5c06e68aaede 100644
--- a/src/sakia/gui/views/scenes/base_scene.py
+++ b/src/sakia/gui/views/scenes/base_scene.py
@@ -1,16 +1,12 @@
 from PyQt5.QtCore import pyqtSignal
-from PyQt5.QtWidgets import QGraphicsScene
+from PyQt5.QtWidgets import QGraphicsScene, QGraphicsSceneContextMenuEvent
 
 
 class BaseScene(QGraphicsScene):
     # This defines signals taking string arguments
-    node_clicked = pyqtSignal(str, dict)
-    node_signed = pyqtSignal(str, dict)
-    node_transaction = pyqtSignal(str, dict)
-    node_contact = pyqtSignal(str, dict)
-    node_member = pyqtSignal(str, dict)
-    node_copy_pubkey = pyqtSignal(str)
+    node_context_menu_requested = pyqtSignal(str)
     node_hovered = pyqtSignal(str)
+    node_clicked = pyqtSignal(str, dict)
 
     def __init__(self, parent=None):
-        super().__init__(parent)
\ No newline at end of file
+        super().__init__(parent)
diff --git a/src/sakia/gui/views/wot.py b/src/sakia/gui/views/wot.py
index c4e874e971f68cad026eacfe17d819c1c3d657a5..056962d84469f4000daec002861fac40f9066ad9 100644
--- a/src/sakia/gui/views/wot.py
+++ b/src/sakia/gui/views/wot.py
@@ -1,10 +1,6 @@
-import networkx
-from PyQt5.QtCore import Qt, QPoint,  pyqtSignal
+from PyQt5.QtCore import Qt
 from PyQt5.QtGui import QPainter, QWheelEvent
-from PyQt5.QtWidgets import QGraphicsView, QGraphicsScene
-
-from .edges import WotEdge
-from .nodes import WotNode
+from PyQt5.QtWidgets import QGraphicsView
 from .scenes import WotScene
 
 
@@ -15,7 +11,7 @@ class WotView(QGraphicsView):
 
         :param parent:  [Optional, default=None] Parent widget
         """
-        super(WotView, self).__init__(parent)
+        super().__init__(parent)
 
         self.setScene(WotScene(self))
 
@@ -44,4 +40,4 @@ class WotView(QGraphicsView):
         #  act normally on scrollbar
         else:
             # transmit event to parent class wheelevent
-            super().wheelEvent(event)
+            super().wheelEvent(event)
\ No newline at end of file
diff --git a/src/sakia/gui/widgets/context_menu.py b/src/sakia/gui/widgets/context_menu.py
new file mode 100644
index 0000000000000000000000000000000000000000..e328bf39b15036e646bfb87fe28024e705bb148e
--- /dev/null
+++ b/src/sakia/gui/widgets/context_menu.py
@@ -0,0 +1,213 @@
+from PyQt5.QtWidgets import QMenu, QAction, QApplication, QMessageBox
+from PyQt5.QtCore import QObject, pyqtSignal
+from ucoinpy.documents import Block, Membership
+from ..member import MemberDialog
+from ..contact import ConfigureContactDialog
+from ..transfer import TransferMoneyDialog
+from ..certification import CertificationDialog
+from ...tools.decorators import asyncify
+from ...core.transfer import Transfer, TransferState
+from ...core.registry import Identity
+
+
+class ContextMenu(QObject):
+    view_identity_in_wot = pyqtSignal(object)
+
+    def __init__(self, qmenu, app, account, community, password_asker):
+        """
+        :param PyQt5.QtWidgets.QMenu: the qmenu widget
+        :param sakia.core.Application app: Application instance
+        :param sakia.core.Account account: The current account instance
+        :param sakia.core.Community community: The community instance
+        :param sakia.gui.PasswordAsker password_asker: The password dialog
+        """
+        super().__init__()
+        self.qmenu = qmenu
+        self._app = app
+        self._community = community
+        self._account = account
+        self._password_asker = password_asker
+
+    @staticmethod
+    def _add_identity_actions(menu, identity):
+        """
+        :param ContextMenu menu: the qmenu to add actions to
+        :param Identity identity: the identity
+        """
+        menu.qmenu.addSeparator().setText(identity.uid)
+
+        informations = QAction(menu.qmenu.tr("Informations"), menu.qmenu.parent())
+        informations.triggered.connect(lambda checked, i=identity: menu.informations(i))
+        menu.qmenu.addAction(informations)
+
+        add_as_contact = QAction(menu.qmenu.tr("Add as contact"), menu.qmenu.parent())
+        add_as_contact.triggered.connect(lambda checked,i=identity: menu.add_as_contact(i))
+        menu.qmenu.addAction(add_as_contact)
+
+        send_money = QAction(menu.qmenu.tr("Send money"), menu.qmenu.parent())
+        send_money.triggered.connect(lambda checked, i=identity: menu.send_money(i))
+        menu.qmenu.addAction(send_money)
+
+        certify = QAction(menu.tr("Certify identity"), menu.qmenu.parent())
+        certify.triggered.connect(lambda checked, i=identity: menu.certify_identity(i))
+        menu.qmenu.addAction(certify)
+
+        view_wot = QAction(menu.qmenu.tr("View in Web of Trust"), menu.qmenu.parent())
+        view_wot.triggered.connect(lambda checked, i=identity: menu.view_wot(i))
+        menu.qmenu.addAction(view_wot)
+
+        copy_pubkey = QAction(menu.qmenu.tr("Copy pubkey to clipboard"), menu.qmenu.parent())
+        copy_pubkey.triggered.connect(lambda checked, i=identity: ContextMenu.copy_pubkey_to_clipboard(i))
+        menu.qmenu.addAction(copy_pubkey)
+
+        if menu._app.preferences['expert_mode']:
+            copy_membership = QAction(menu.qmenu.tr("Copy membership document to clipboard"), menu.qmenu.parent())
+            copy_membership.triggered.connect(lambda checked, i=identity: menu.copy_membership_to_clipboard(i))
+            # TODO: Copy membership when written field is available
+            #menu.qmenu.addAction(copy_membership)
+
+            copy_selfcert = QAction(menu.qmenu.tr("Copy self-certification document to clipboard"), menu.qmenu.parent())
+            copy_selfcert.triggered.connect(lambda checked, i=identity: menu.copy_selfcert_to_clipboard(i))
+            menu.qmenu.addAction(copy_selfcert)
+
+    @staticmethod
+    def _add_transfers_actions(menu, transfer):
+        """
+        :param ContextMenu menu: the qmenu to add actions to
+        :param Transfer transfer: the transfer
+        """
+        menu.qmenu.addSeparator().setText(menu.qmenu.tr("Transfer"))
+        if transfer.state in (TransferState.REFUSED, TransferState.TO_SEND):
+            send_back = QAction(menu.qmenu.tr("Send again"), menu.qmenu.parent())
+            send_back.triggered.connect(lambda checked, tr=transfer: menu.send_again(tr))
+            menu.qmenu.addAction(send_back)
+
+            cancel = QAction(menu.qmenu.tr("Cancel"), menu.qmenu.parent())
+            cancel.triggered.connect(lambda checked, tr=transfer: menu.cancel_transfer(tr))
+            menu.qmenu.addAction(cancel)
+
+        if menu._app.preferences['expert_mode']:
+            copy_doc = QAction(menu.qmenu.tr("Copy raw transaction to clipboard"), menu.qmenu.parent())
+            copy_doc.triggered.connect(lambda checked, tx=transfer: menu.copy_transaction_to_clipboard(tx))
+            menu.qmenu.addAction(copy_doc)
+
+            copy_doc = QAction(menu.qmenu.tr("Copy transaction block to clipboard"), menu.qmenu.parent())
+            copy_doc.triggered.connect(lambda checked, number=transfer.blockid.number:
+                                       menu.copy_block_to_clipboard(number))
+            menu.qmenu.addAction(copy_doc)
+
+
+    @classmethod
+    def from_data(cls, parent, app, account, community, password_asker, data):
+        """
+        Builds a QMenu from data passed as parameters
+        Data can be Identity or Transfer
+
+        :param PyQt5.QtWidgets.QWidget parent: the parent widget
+        :param sakia.core.Application app: the application
+        :param sakia.core.Application app: Application instance
+        :param sakia.core.Account account: The current account instance
+        :param sakia.core.Community community: The community instance
+        :param sakia.gui.PasswordAsker password_asker: The password dialog
+        :param tuple data: a tuple of data to add to the menu
+        :rtype: ContextMenu
+        """
+        menu = cls(QMenu(parent), app, account, community, password_asker)
+        build_actions = {
+            Identity: ContextMenu._add_identity_actions,
+            Transfer: ContextMenu._add_transfers_actions,
+            dict: lambda m, d: None
+        }
+        for d in data:
+            build_actions[type(d)](menu, d)
+
+        return menu
+
+    @staticmethod
+    def copy_pubkey_to_clipboard(identity):
+        clipboard = QApplication.clipboard()
+        clipboard.setText(identity.pubkey)
+
+    def informations(self, identity):
+        MemberDialog.open_dialog(self._app, self._account, self._community, identity)
+
+    def add_as_contact(self, identity):
+        dialog = ConfigureContactDialog.from_identity( self.parent(), self._account, identity)
+        dialog.exec_()
+        #TODO: Send signal from account to refresh contacts
+        # if result == QDialog.Accepted:
+        #    self.parent().window().refresh_contacts()
+
+    @asyncify
+    async def send_money(self, identity):
+        await TransferMoneyDialog.send_money_to_identity(self._app, self._account, self._password_asker,
+                                                            self._community, identity)
+        #TODO: Send signal from account to refresh transfers
+        #self.ui.table_history.model().sourceModel().refresh_transfers()
+
+    def view_wot(self, identity):
+        self.view_identity_in_wot.emit(identity)
+
+    @asyncify
+    async def certify_identity(self, identity):
+        await CertificationDialog.certify_identity(self._app, self._account, self._password_asker,
+                                             self._community, identity)
+
+    @asyncify
+    async def send_again(self, transfer):
+        await TransferMoneyDialog.send_transfer_again(self._app, self._app.current_account,
+                                     self._password_asker, self._community, transfer)
+        #TODO: Send signal from account to refresh transfers
+        #self.ui.table_history.model().sourceModel().refresh_transfers()
+
+    def cancel_transfer(self, transfer):
+        reply = QMessageBox.warning(self, self.tr("Warning"),
+                             self.tr("""Are you sure ?
+This money transfer will be removed and not sent."""),
+QMessageBox.Ok | QMessageBox.Cancel)
+        if reply == QMessageBox.Ok:
+            transfer.cancel()
+        #TODO: Send signal from transfer to refresh transfers
+        #self.ui.table_history.model().sourceModel().refresh_transfers()
+
+    @asyncify
+    async def copy_transaction_to_clipboard(self, tx):
+        clipboard = QApplication.clipboard()
+        raw_doc = await tx.get_raw_document(self._community)
+        clipboard.setText(raw_doc.signed_raw())
+
+    @asyncify
+    async def copy_block_to_clipboard(self, number):
+        clipboard = QApplication.clipboard()
+        block = await self._community.get_block(number)
+        if block:
+            block_doc = Block.from_signed_raw("{0}{1}\n".format(block['raw'], block['signature']))
+            clipboard.setText(block_doc.signed_raw())
+
+    @asyncify
+    async def copy_membership_to_clipboard(self, identity):
+        """
+
+        :param sakia.core.registry.Identity identity:
+        :return:
+        """
+        clipboard = QApplication.clipboard()
+        membership = await identity.membership(self._community)
+        if membership:
+            block_number = membership['blockNumber']
+            block = await self._community.get_block(block_number)
+            block_doc = Block.from_signed_raw("{0}{1}\n".format(block['raw'], block['signature']))
+            for ms_doc in block_doc.joiners:
+                if ms_doc.issuer == identity.pubkey:
+                    clipboard.setText(ms_doc.signed_raw())
+
+    @asyncify
+    async def copy_selfcert_to_clipboard(self, identity):
+        """
+
+        :param sakia.core.registry.Identity identity:
+        :return:
+        """
+        clipboard = QApplication.clipboard()
+        selfcert = await identity.selfcert(self._community)
+        clipboard.setText(selfcert.signed_raw())
diff --git a/src/sakia/gui/widgets/search_user.py b/src/sakia/gui/widgets/search_user.py
index 94114755631209cefe8ea8551beecb72cc4d0a59..e93b906e39abfcfd01d07b1a66651055ef9beaba 100644
--- a/src/sakia/gui/widgets/search_user.py
+++ b/src/sakia/gui/widgets/search_user.py
@@ -1,6 +1,6 @@
 import logging
 
-from PyQt5.QtCore import QEvent, pyqtSignal, QT_TRANSLATE_NOOP
+from PyQt5.QtCore import QEvent, pyqtSignal, QT_TRANSLATE_NOOP, Qt
 from PyQt5.QtWidgets import QComboBox, QWidget
 
 from ucoinpy.api import bma
@@ -37,6 +37,10 @@ class SearchUserWidget(QWidget, Ui_SearchUserWidget):
         self.community = None
         self.account = None
         self.app = None
+        self._current_identity = None
+
+    def current_identity(self):
+        return self._current_identity
 
     def init(self, app):
         """
@@ -77,6 +81,15 @@ class SearchUserWidget(QWidget, Ui_SearchUserWidget):
                     self.combobox_search.addItem(uid)
                 self.blockSignals(False)
                 self.combobox_search.showPopup()
+        except ValueError as e:
+            if '404' in str(e):
+                self.nodes = list()
+                self.blockSignals(True)
+                self.combobox_search.clear()
+                self.blockSignals(False)
+                self.combobox_search.showPopup()
+            else:
+                pass
         except NoPeerAvailable:
             pass
 
@@ -85,17 +98,19 @@ class SearchUserWidget(QWidget, Ui_SearchUserWidget):
         Select node in graph when item is selected in combobox
         """
         if index < 0 or index >= len(self.nodes):
+            self._current_identity = None
             return False
         node = self.nodes[index]
         metadata = {'id': node['pubkey'], 'text': node['uid']}
-        self.identity_selected.emit(
-            self.app.identities_registry.from_handled_data(
+        self._current_identity = self.app.identities_registry.from_handled_data(
                 metadata['text'],
                 metadata['id'],
                 None,
                 BlockchainState.VALIDATED,
                 self.community
             )
+        self.identity_selected.emit(
+            self._current_identity
         )
 
     def retranslateUi(self, widget):
@@ -104,3 +119,9 @@ class SearchUserWidget(QWidget, Ui_SearchUserWidget):
         """
         self.combobox_search.lineEdit().setPlaceholderText(self.tr(SearchUserWidget._search_placeholder))
         super().retranslateUi(self)
+
+    def keyPressEvent(self, event):
+        if event.key() == Qt.Key_Return:
+            return
+
+        super().keyPressEvent(event)
diff --git a/src/sakia/main.py b/src/sakia/main.py
index 65844f363335e26a36e549b38bc3f29c00c1f34a..8058c3324f3d79366edcf76c175031a18bd8ba19 100755
--- a/src/sakia/main.py
+++ b/src/sakia/main.py
@@ -16,7 +16,7 @@ import jsonschema
 # To force cx_freeze import
 import PyQt5.QtSvg
 
-from quamash import QEventLoop
+from quamash import QSelectorEventLoop
 from PyQt5.QtWidgets import QApplication
 from sakia.gui.mainwindow import MainWindow
 from sakia.core.app import Application
@@ -61,7 +61,7 @@ if __name__ == '__main__':
     # activate ctrl-c interrupt
     signal.signal(signal.SIGINT, signal.SIG_DFL)
     sakia = QApplication(sys.argv)
-    loop = QEventLoop(sakia)
+    loop = QSelectorEventLoop(sakia)
     loop.set_exception_handler(async_exception_handler)
     asyncio.set_event_loop(loop)
 
diff --git a/src/sakia/models/identities.py b/src/sakia/models/identities.py
index 9cdbab2b69e9a56ed9d278935f12cdfb0d186ab8..c49e44f8f0a545c90dfec0f890e9d6948ea761ba 100644
--- a/src/sakia/models/identities.py
+++ b/src/sakia/models/identities.py
@@ -7,7 +7,7 @@ Created on 5 févr. 2014
 from ..tools.exceptions import NoPeerAvailable, MembershipNotFoundError
 from PyQt5.QtCore import QAbstractTableModel, QSortFilterProxyModel, Qt, \
                         QDateTime, QModelIndex, QLocale, QEvent
-from PyQt5.QtGui import QColor
+from PyQt5.QtGui import QColor, QIcon
 import logging
 import asyncio
 
@@ -67,9 +67,19 @@ class IdentitiesFilterProxyModel(QSortFilterProxyModel):
             if role == Qt.ForegroundRole:
                 if expiration_data:
                     if will_expire_soon:
-                        return QColor(Qt.red)
+                        return QColor("darkorange").darker(120)
                 else:
                     return QColor(Qt.blue)
+
+            if role == Qt.DecorationRole and source_index.column() == self.sourceModel().columns_ids.index('uid'):
+                if expiration_data:
+                    if will_expire_soon:
+                        return QIcon(":/icons/member_warning")
+                    else:
+                        return QIcon(":/icons/member")
+                else:
+                    return QIcon(":/icons/not_member")
+
             return source_data
 
 
diff --git a/src/sakia/models/network.py b/src/sakia/models/network.py
index 3a5538eaf01a04726132b38307c7a231de58ca35..e8b1ee4f614dc3a6aabfacb89c993e9b04559757 100644
--- a/src/sakia/models/network.py
+++ b/src/sakia/models/network.py
@@ -8,7 +8,7 @@ import logging
 import asyncio
 
 from PyQt5.QtCore import QAbstractTableModel, Qt, QVariant, QSortFilterProxyModel
-from PyQt5.QtGui import QColor, QFont
+from PyQt5.QtGui import QColor, QFont, QIcon
 
 from ..tools.exceptions import NoPeerAvailable
 from ..tools.decorators import asyncify, once_at_a_time, cancel_once_task
@@ -131,6 +131,12 @@ class NetworkTableModel(QAbstractTableModel):
             Node.DESYNCED: QColor('#ffbd81'),
             Node.CORRUPTED: QColor(Qt.lightGray)
         }
+        self.node_icons = {
+            Node.ONLINE: ":/icons/synchronized",
+            Node.OFFLINE: ":/icons/offline",
+            Node.DESYNCED: ":/icons/forked",
+            Node.CORRUPTED: ":/icons/corrupted"
+        }
         self.node_states = {
             Node.ONLINE: lambda: self.tr('Online'),
             Node.OFFLINE: lambda: self.tr('Offline'),
@@ -214,6 +220,9 @@ class NetworkTableModel(QAbstractTableModel):
         if role == Qt.ToolTipRole:
             return self.node_states[node[self.columns_types.index('state')]]()
 
+        if role == Qt.DecorationRole and index.column() == 0:
+            return QIcon(self.node_icons[node[self.columns_types.index('state')]])
+
         return QVariant()
 
     def flags(self, index):
diff --git a/src/sakia/models/txhistory.py b/src/sakia/models/txhistory.py
index d138dada1f9d006d46f344bdc1ef6c6672f70a5e..5bea986af16723e039923a3fcc852c568e6a993a 100644
--- a/src/sakia/models/txhistory.py
+++ b/src/sakia/models/txhistory.py
@@ -13,7 +13,7 @@ from ..tools.decorators import asyncify, once_at_a_time, cancel_once_task
 from PyQt5.QtCore import QAbstractTableModel, Qt, QVariant, QSortFilterProxyModel, \
     QDateTime, QLocale, QModelIndex
 
-from PyQt5.QtGui import QFont, QColor
+from PyQt5.QtGui import QFont, QColor, QIcon
 
 
 class TxFilterProxyModel(QSortFilterProxyModel):
@@ -169,7 +169,6 @@ class TxFilterProxyModel(QSortFilterProxyModel):
                     return self.tr("Confirming... {0} %").format(QLocale().toString(float(confirmation), 'f', 0))
 
             return None
-
         return source_data
 
 
@@ -231,7 +230,8 @@ class HistoryTableModel(QAbstractTableModel):
 
     async def data_received(self, transfer):
         amount = transfer.metadata['amount']
-        deposit = await self.account.current_ref(transfer.metadata['amount'], self.community, self.app)\
+        deposit = await self.account.current_ref(transfer.metadata['amount'], self.community,
+                                                 self.app, transfer.blockid.number)\
             .diff_localized(international_system=self.app.preferences['international_system_of_units'])
         comment = ""
         if transfer.metadata['comment'] != "":
@@ -254,7 +254,8 @@ class HistoryTableModel(QAbstractTableModel):
 
     async def data_sent(self, transfer):
         amount = transfer.metadata['amount']
-        paiment = await self.account.current_ref(transfer.metadata['amount'], self.community, self.app)\
+        paiment = await self.account.current_ref(transfer.metadata['amount'], self.community,
+                                                 self.app, transfer.blockid.number)\
             .diff_localized(international_system=self.app.preferences['international_system_of_units'])
         comment = ""
         if transfer.metadata['comment'] != "":
@@ -277,7 +278,7 @@ class HistoryTableModel(QAbstractTableModel):
 
     async def data_dividend(self, dividend):
         amount = dividend['amount']
-        deposit = await self.account.current_ref(dividend['amount'], self.community, self.app)\
+        deposit = await self.account.current_ref(dividend['amount'], self.community, self.app, dividend['block_number'])\
             .diff_localized(international_system=self.app.preferences['international_system_of_units'])
         comment = ""
         receiver = self.account.name
@@ -334,7 +335,7 @@ class HistoryTableModel(QAbstractTableModel):
                 if self.columns_types[section] == 'payment' or self.columns_types[section] == 'deposit':
                     return '{:}\n({:})'.format(
                         self.column_headers[section](),
-                        self.account.current_ref.diff_units(self.community.short_currency)
+                        self.account.current_ref(0, self.community, self.app, None).diff_units
                     )
 
                 return self.column_headers[section]()
@@ -352,6 +353,15 @@ class HistoryTableModel(QAbstractTableModel):
         if role == Qt.ToolTipRole:
             return self.transfers_data[row][col]
 
+        if role == Qt.DecorationRole and index.column() == 0:
+            transfer = self.transfers_data[row]
+            if transfer[self.columns_types.index('payment')] != "":
+                return QIcon(":/icons/sent")
+            elif transfer[self.columns_types.index('uid')] == self.account.name:
+                return QIcon(":/icons/dividend")
+            else:
+                return QIcon(":/icons/received")
+
     def flags(self, index):
         return Qt.ItemIsSelectable | Qt.ItemIsEnabled
 
diff --git a/src/sakia/models/wallets.py b/src/sakia/models/wallets.py
index a656f182d05107b72ba6dc777cbf32967a83c61d..4428dcbb9cc070488c58c4ac009857f0ff74541b 100644
--- a/src/sakia/models/wallets.py
+++ b/src/sakia/models/wallets.py
@@ -112,7 +112,7 @@ class WalletsTableModel(QAbstractTableModel):
             if self.columns_types[section] == 'amount':
                 return '{:}\n({:})'.format(
                     self.columns_headers[section],
-                    self.account.current_ref.units(self.community.short_currency)
+                    self.account.current_ref(0, self.community, self.app, None).units
                 )
             return self.columns_headers[section]
 
diff --git a/src/sakia/tests/functional/certification/test_certification.py b/src/sakia/tests/functional/certification/test_certification.py
index 322cb71c2a78d131391c70e765f9f7df9fc0d510..571766802261f27d67488786f7c2fc6fef7e2c73 100644
--- a/src/sakia/tests/functional/certification/test_certification.py
+++ b/src/sakia/tests/functional/certification/test_certification.py
@@ -1,24 +1,21 @@
 import sys
 import unittest
 import asyncio
-import quamash
 import time
 import logging
 from ucoinpy.documents.peer import BMAEndpoint
 from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QMessageBox, QApplication
 from PyQt5.QtCore import QLocale, Qt
 from PyQt5.QtTest import QTest
-from ucoinpy.api.bma import API
 from sakia.tests.mocks.bma import init_new_community
 from sakia.core.registry.identities import IdentitiesRegistry
-from sakia.gui.certification import CertificationDialog
+from sakia.gui.certification import CertificationDialog, Ui_CertificationDialog
 from sakia.gui.password_asker import PasswordAskerDialog
 from sakia.core.app import Application
 from sakia.core import Account, Community, Wallet
 from sakia.core.net import Network, Node
 from sakia.core.net.api.bma.access import BmaAccess
 from sakia.tests import QuamashTest
-from ucoinpy.api import bma
 
 
 class TestCertificationDialog(unittest.TestCase, QuamashTest):
@@ -30,8 +27,10 @@ class TestCertificationDialog(unittest.TestCase, QuamashTest):
         self.application = Application(self.qapplication, self.lp, self.identities_registry)
         self.application.preferences['notifications'] = False
 
+        self.mock_new_community = init_new_community.get_mock(self.lp)
+
         self.endpoint = BMAEndpoint("", "127.0.0.1", "", 50010)
-        self.node = Node("test_currency", [self.endpoint],
+        self.node = Node(self.mock_new_community.peer(),
                          "", "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk",
                          None, Node.ONLINE,
                          time.time(), {}, "ucoin", "0.14.0", 0)
@@ -46,39 +45,35 @@ class TestCertificationDialog(unittest.TestCase, QuamashTest):
         # Pubkey : 7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ
         self.account = Account("testsakia", "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ",
                                "john", [self.community], [self.wallet], [], self.identities_registry)
-
+        self.account.notifications['warning_certifying_first_time'] = False
         self.password_asker = PasswordAskerDialog(self.account)
         self.password_asker.password = "testsakia"
         self.password_asker.remember = True
 
-    def tearDown(self):
-        self.tearDownQuamash()
-
     def test_certification_init_community(self):
-        mock = init_new_community.get_mock(self.lp)
         time.sleep(2)
         certification_dialog = CertificationDialog(self.application,
                                                    self.account,
-                                                   self.password_asker)
+                                                   self.password_asker,
+                                                   QDialog(),
+                                                    Ui_CertificationDialog())
 
         async def open_dialog(certification_dialog):
-            srv, port, url = await mock.create_server()
+            srv, port, url = await self.mock_new_community.create_server()
             self.addCleanup(srv.close)
-            self.endpoint.port = port
-
             result = await certification_dialog.async_exec()
             self.assertEqual(result, QDialog.Accepted)
 
         def close_dialog():
-            if certification_dialog.isVisible():
-                certification_dialog.close()
+            if certification_dialog.widget.isVisible():
+                certification_dialog.widget.close()
 
         async def exec_test():
             await asyncio.sleep(1)
-            QTest.mouseClick(certification_dialog.radio_pubkey, Qt.LeftButton)
-            QTest.keyClicks(certification_dialog.edit_pubkey, "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn")
-            QTest.mouseClick(certification_dialog.button_box.button(QDialogButtonBox.Ok), Qt.LeftButton)
-            await asyncio.sleep(1)
+            QTest.mouseClick(certification_dialog.ui.radio_pubkey, Qt.LeftButton)
+            QTest.keyClicks(certification_dialog.ui.edit_pubkey, "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn")
+            QTest.mouseClick(certification_dialog.ui.button_box.button(QDialogButtonBox.Ok), Qt.LeftButton)
+            await asyncio.sleep(2)
             topWidgets = QApplication.topLevelWidgets()
             for w in topWidgets:
                 if type(w) is QMessageBox:
diff --git a/src/sakia/tests/functional/identities_tab/test_identities_table.py b/src/sakia/tests/functional/identities_tab/test_identities_table.py
index 72be5f0dfb13e0b9c8166b063d4ba2c57fdd293c..bb7aeb65882868e74b4ed9d1e124cd440ef4e1d4 100644
--- a/src/sakia/tests/functional/identities_tab/test_identities_table.py
+++ b/src/sakia/tests/functional/identities_tab/test_identities_table.py
@@ -31,8 +31,8 @@ class TestIdentitiesTable(unittest.TestCase, QuamashTest):
         self.application = Application(self.qapplication, self.lp, self.identities_registry)
         self.application.preferences['notifications'] = False
 
-        self.endpoint = BMAEndpoint("", "127.0.0.1", "", 50002)
-        self.node = Node("test_currency", [self.endpoint],
+        self.mock_nice_blockchain = nice_blockchain.get_mock(self.lp)
+        self.node = Node(self.mock_nice_blockchain.peer(),
                          "", "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk",
                          None, Node.ONLINE,
                          time.time(), {}, "ucoin", "0.14.0", 0)
@@ -56,29 +56,27 @@ class TestIdentitiesTable(unittest.TestCase, QuamashTest):
         self.tearDownQuamash()
 
     def test_search_identity_found(self):
-        mock = nice_blockchain.get_mock(self.lp)
         time.sleep(2)
         identities_tab = IdentitiesTabWidget(self.application)
         future = asyncio.Future()
 
         def open_widget():
-            identities_tab.show()
+            identities_tab.widget.show()
             return future
 
         def close_dialog():
-            if identities_tab.isVisible():
-                identities_tab.close()
+            if identities_tab.widget.isVisible():
+                identities_tab.widget.close()
             future.set_result(True)
 
         async def exec_test():
-            srv, port, url = await mock.create_server()
+            srv, port, url = await self.mock_nice_blockchain.create_server()
             self.addCleanup(srv.close)
-            self.endpoint.port = port
 
             identities_tab.change_account(self.account, self.password_asker)
             identities_tab.change_community(self.community)
             await asyncio.sleep(1)
-            urls = [mock.get_request(i).url for i in range(0, 7)]
+            urls = [self.mock_nice_blockchain.get_request(i).url for i in range(0, 7)]
             self.assertTrue('/wot/certifiers-of/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ' in urls,
                             msg="Not found in {0}".format(urls))
             self.assertTrue('/wot/lookup/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ' in urls,
@@ -90,17 +88,17 @@ class TestIdentitiesTable(unittest.TestCase, QuamashTest):
             # requests 1 to 3 are for getting certifiers-of and certified-by
             # on john, + a lookup
 
-            QTest.keyClicks(identities_tab.edit_textsearch, "doe")
-            QTest.mouseClick(identities_tab.button_search, Qt.LeftButton)
+            QTest.keyClicks(identities_tab.ui.edit_textsearch, "doe")
+            QTest.mouseClick(identities_tab.ui.button_search, Qt.LeftButton)
             await asyncio.sleep(2)
             req = 8
 
-            self.assertEqual(mock.get_request(req).method, 'GET')
-            self.assertEqual(mock.get_request(req).url,
+            self.assertEqual(self.mock_nice_blockchain.get_request(req).method, 'GET')
+            self.assertEqual(self.mock_nice_blockchain.get_request(req).url,
                              '/blockchain/memberships/FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn')
             req += 1
 
-            self.assertEqual(identities_tab.table_identities.model().rowCount(), 1)
+            self.assertEqual(identities_tab.ui.table_identities.model().rowCount(), 1)
             await asyncio.sleep(2)
             self.lp.call_soon(close_dialog)
 
diff --git a/src/sakia/tests/functional/main_window/test_main_window_dialogs.py b/src/sakia/tests/functional/main_window/test_main_window_dialogs.py
index 97d0a5f88887c751ea286230f6992c21a21bc2ae..2c054c338787e757bb59fd8cfa7f48b42a255144 100644
--- a/src/sakia/tests/functional/main_window/test_main_window_dialogs.py
+++ b/src/sakia/tests/functional/main_window/test_main_window_dialogs.py
@@ -1,9 +1,6 @@
 import unittest
-import asyncio
-import quamash
 from PyQt5.QtWidgets import QDialog, QFileDialog
 from PyQt5.QtCore import QLocale, QTimer
-from PyQt5.QtNetwork import QNetworkAccessManager
 from sakia.gui.mainwindow import MainWindow
 from sakia.core.app import Application
 from sakia.tests import QuamashTest
diff --git a/src/sakia/tests/functional/process_cfg_community/test_add_community.py b/src/sakia/tests/functional/process_cfg_community/test_add_community.py
index 7f97a3dee9b3712bbb078818bf49b5db67ad7ebd..20fe49931097a2e6c0617c4c3a47e3f92efbd84d 100644
--- a/src/sakia/tests/functional/process_cfg_community/test_add_community.py
+++ b/src/sakia/tests/functional/process_cfg_community/test_add_community.py
@@ -35,7 +35,6 @@ class ProcessAddCommunity(unittest.TestCase, QuamashTest):
     def tearDown(self):
         self.tearDownQuamash()
 
-    @unittest.skipIf(sys.platform== "darwin", "Test not working on OSX, but feature is OK")
     def test_register_community_empty_blockchain(self):
         mock = new_blockchain.get_mock(self.lp)
         time.sleep(2)
@@ -64,7 +63,7 @@ class ProcessAddCommunity(unittest.TestCase, QuamashTest):
             await asyncio.sleep(1)
             self.assertEqual(mock.get_request(0).method, 'GET')
             self.assertEqual(mock.get_request(0).url, '/network/peering')
-            self.assertEqual(process_community._step_init.node._endpoints[0].port, port)
+            self.assertEqual(process_community._step_init.node.endpoint.port, port)
             self.assertEqual(mock.get_request(1).method, 'GET')
             self.assertEqual(mock.get_request(1).url,
                              '/wot/certifiers-of/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ')
@@ -96,7 +95,6 @@ class ProcessAddCommunity(unittest.TestCase, QuamashTest):
         self.lp.run_until_complete(process_community.async_exec())
         self.assertEqual(process_community.result(), QDialog.Accepted)
 
-    @unittest.skipIf(sys.platform== "darwin", "Test not working on OSX, but feature is OK")
     def test_connect_community_empty_blockchain(self):
         mock = new_blockchain.get_mock(self.lp)
         time.sleep(2)
@@ -143,7 +141,6 @@ class ProcessAddCommunity(unittest.TestCase, QuamashTest):
         asyncio.ensure_future(exec_test())
         self.lp.run_until_complete(process_community.async_exec())
 
-    @unittest.skipIf(sys.platform== "darwin", "Test not working on OSX, but feature is OK")
     def test_connect_community_wrong_pubkey(self):
         mock = nice_blockchain.get_mock(self.lp)
         time.sleep(2)
@@ -185,7 +182,6 @@ Yours : wrong_pubkey, the network : 7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ
         self.lp.run_until_complete(process_community.async_exec())
         self.assertEqual(process_community.result(), QDialog.Rejected)
 
-    @unittest.skipIf(sys.platform== "darwin", "Test not working on OSX, but feature is OK")
     def test_connect_community_wrong_uid(self):
         mock = nice_blockchain.get_mock(self.lp)
         time.sleep(2)
@@ -227,7 +223,6 @@ Yours : wrong_uid, the network : john""")
         self.lp.run_until_complete(process_community.async_exec())
         self.assertEqual(process_community.result(), QDialog.Rejected)
 
-    @unittest.skipIf(sys.platform== "darwin", "Test not working on OSX, but feature is OK")
     def test_connect_community_success(self):
         mock = nice_blockchain.get_mock(self.lp)
         time.sleep(2)
diff --git a/src/sakia/tests/functional/transfer/test_transfer.py b/src/sakia/tests/functional/transfer/test_transfer.py
index ee348926d27d7f35be38cbb16a4b5d264372c9a8..6ba1ca1ef1f8f7e78ef3c89efb800c57353d1714 100644
--- a/src/sakia/tests/functional/transfer/test_transfer.py
+++ b/src/sakia/tests/functional/transfer/test_transfer.py
@@ -31,8 +31,8 @@ class TestTransferDialog(unittest.TestCase, QuamashTest):
         self.application = Application(self.qapplication, self.lp, self.identities_registry)
         self.application.preferences['notifications'] = False
 
-        self.endpoint = BMAEndpoint("", "127.0.0.1", "", 50002)
-        self.node = Node("test_currency", [self.endpoint],
+        self.mock_nice_blockchain = nice_blockchain.get_mock(self.lp)
+        self.node = Node(self.mock_nice_blockchain.peer(),
                          "", "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk",
                          None, Node.ONLINE,
                          time.time(), {}, "ucoin", "0.14.0", 0)
@@ -56,8 +56,6 @@ class TestTransferDialog(unittest.TestCase, QuamashTest):
         self.tearDownQuamash()
 
     def test_transfer_nice_community(self):
-        mock = nice_blockchain.get_mock(self.lp)
-        time.sleep(2)
         transfer_dialog = TransferMoneyDialog(self.application,
                                               self.account,
                                               self.password_asker,
@@ -66,9 +64,8 @@ class TestTransferDialog(unittest.TestCase, QuamashTest):
         self.account.wallets[0].init_cache(self.application, self.community)
 
         async def open_dialog(transfer_dialog):
-            srv, port, url = await mock.create_server()
+            srv, port, url = await self.mock_nice_blockchain.create_server()
             self.addCleanup(srv.close)
-            self.endpoint.port = port
 
             result = await transfer_dialog.async_exec()
             self.assertEqual(result, QDialog.Accepted)
@@ -80,10 +77,10 @@ class TestTransferDialog(unittest.TestCase, QuamashTest):
         async def exec_test():
             await asyncio.sleep(1)
             self.account.wallets[0].caches[self.community.currency].available_sources = await self.wallet.sources(self.community)
-            QTest.mouseClick(transfer_dialog.radio_pubkey, Qt.LeftButton)
-            QTest.keyClicks(transfer_dialog.edit_pubkey, "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn")
-            transfer_dialog.spinbox_amount.setValue(10)
-            QTest.mouseClick(transfer_dialog.button_box.button(QDialogButtonBox.Ok), Qt.LeftButton)
+            QTest.mouseClick(transfer_dialog.ui.radio_pubkey, Qt.LeftButton)
+            QTest.keyClicks(transfer_dialog.ui.edit_pubkey, "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn")
+            transfer_dialog.ui.spinbox_amount.setValue(10)
+            QTest.mouseClick(transfer_dialog.ui.button_box.button(QDialogButtonBox.Ok), Qt.LeftButton)
             await asyncio.sleep(1)
             topWidgets = QApplication.topLevelWidgets()
             for w in topWidgets:
diff --git a/src/sakia/tests/functional/wot_tab/test_wot_tab.py b/src/sakia/tests/functional/wot_tab/test_wot_tab.py
index 0bac059cb2e89515ed55bf521c5d3247026eeb85..fc3def5b612e047e706303fb2b5515bc3f74f56d 100644
--- a/src/sakia/tests/functional/wot_tab/test_wot_tab.py
+++ b/src/sakia/tests/functional/wot_tab/test_wot_tab.py
@@ -27,8 +27,8 @@ class TestWotTab(unittest.TestCase, QuamashTest):
         self.application = Application(self.qapplication, self.lp, self.identities_registry)
         self.application.preferences['notifications'] = False
 
-        self.endpoint = BMAEndpoint("", "127.0.0.1", "", 50003)
-        self.node = Node("test_currency", [self.endpoint],
+        self.mock_nice_blockchain = nice_blockchain.get_mock(self.lp)
+        self.node = Node(self.mock_nice_blockchain.peer(),
                          "", "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk",
                          None, Node.ONLINE,
                          time.time(), {}, "ucoin", "0.14.0", 0)
@@ -52,29 +52,26 @@ class TestWotTab(unittest.TestCase, QuamashTest):
         self.tearDownQuamash()
 
     def test_empty_wot_tab(self):
-        mock = nice_blockchain.get_mock(self.lp)
-        time.sleep(2)
         wot_tab = WotTabWidget(self.application)
         future = asyncio.Future()
 
         def open_widget():
-            wot_tab.show()
+            wot_tab.widget.show()
             return future
 
         async def async_open_widget():
-            srv, port, url = await mock.create_server()
+            srv, port, url = await self.mock_nice_blockchain.create_server()
             self.addCleanup(srv.close)
-            self.endpoint.port = port
             await open_widget()
 
         def close_dialog():
-            if wot_tab.isVisible():
-                wot_tab.close()
+            if wot_tab.widget.isVisible():
+                wot_tab.widget.close()
             future.set_result(True)
 
         async def exec_test():
             await asyncio.sleep(1)
-            self.assertTrue(wot_tab.isVisible())
+            self.assertTrue(wot_tab.widget.isVisible())
             self.lp.call_soon(close_dialog)
 
         asyncio.ensure_future(exec_test())
diff --git a/src/sakia/tests/mocks/server.py b/src/sakia/tests/mocks/server.py
index 9e25711c363f9b50497bae949bfe3de438c84efa..d614a72ec6a04fa06cbb87a18ac3adac0180389e 100644
--- a/src/sakia/tests/mocks/server.py
+++ b/src/sakia/tests/mocks/server.py
@@ -1,6 +1,7 @@
 from aiohttp import web, log
 import json
 import socket
+from ucoinpy.documents import Peer
 
 
 def bma_peering_generator(port):
@@ -8,16 +9,28 @@ def bma_peering_generator(port):
           "version": 1,
           "currency": "test_currency",
           "endpoints": [
-            "BASIC_MERKLED_API localhost 127.0.0.1 {port}".format(port=port)
+            "BASIC_MERKLED_API 127.0.0.1 {port}".format(port=port)
           ],
           "status": "UP",
           "block": "30152-00003E7F9234E7542FCF669B69B0F84FF79CCCD3",
           "signature": "cXuqZuDfyHvxYAEUkPH1TQ1M+8YNDpj8kiHGYi3LIaMqEdVqwVc4yQYGivjxFMYyngRfxXkyvqBKZA6rKOulCA==",
-          "raw": "Version: 1\nType: Peer\nCurrency: meta_brouzouf\nPublicKey: HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk\nBlock: 30152-00003E7F9234E7542FCF669B69B0F84FF79CCCD3\nEndpoints:\nBASIC_MERKLED_API localhost 127.0.0.1 {port}\n".format(port=port),
+          "raw": "Version: 1\nType: Peer\nCurrency: meta_brouzouf\nPublicKey: HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk\nBlock: 30152-00003E7F9234E7542FCF669B69B0F84FF79CCCD3\nEndpoints:\nBASIC_MERKLED_API 127.0.0.1 {port}\n".format(port=port),
           "pubkey": "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk"
         }
 
 
+def peer_document_generator(port):
+    return Peer.from_signed_raw("""Version: 1
+Type: Peer
+Currency: meta_brouzouf
+PublicKey: HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk
+Block: 30152-00003E7F9234E7542FCF669B69B0F84FF79CCCD3
+Endpoints:
+BASIC_MERKLED_API 127.0.0.1 {port}
+cXuqZuDfyHvxYAEUkPH1TQ1M+8YNDpj8kiHGYi3LIaMqEdVqwVc4yQYGivjxFMYyngRfxXkyvqBKZA6rKOulCA==
+""".format(port=port))
+
+
 class Request():
     def __init__(self, method, url, content):
         self.url = url
@@ -35,6 +48,8 @@ class MockServer():
             keep_alive_on=False,
             access_log=log.access_logger)
 
+        self.port = self.find_unused_port()
+
     def get_request(self, i):
         return self.requests[i]
 
@@ -56,12 +71,14 @@ class MockServer():
         s.close()
         return port
 
+    def peer(self):
+        return peer_document_generator(self.port)
+
     async def create_server(self, ssl_ctx=None):
-        port = self.find_unused_port()
-        srv = await self.lp.create_server(self.handler, '127.0.0.1', port)
+        srv = await self.lp.create_server(self.handler, '127.0.0.1', self.port)
         protocol = "https" if ssl_ctx else "http"
-        url = "{}://127.0.0.1:{}".format(protocol, port)
+        url = "{}://127.0.0.1:{}".format(protocol, self.port)
 
-        self.add_route('GET', '/network/peering', bma_peering_generator(port))
+        self.add_route('GET', '/network/peering', bma_peering_generator(self.port))
 
-        return srv, port, url
\ No newline at end of file
+        return srv, self.port, url
\ No newline at end of file
diff --git a/src/sakia/tests/quamash_utils.py b/src/sakia/tests/quamash_utils.py
index ae7610528fbec45516a6238d4dca54d9fdd28a99..7c11293ca4cbacbda7815318d3923c4b91eca84f 100644
--- a/src/sakia/tests/quamash_utils.py
+++ b/src/sakia/tests/quamash_utils.py
@@ -9,7 +9,7 @@ _application_ = []
 class QuamashTest:
     def setUpQuamash(self):
         self.qapplication = get_application()
-        self.lp = quamash.QEventLoop(self.qapplication)
+        self.lp = quamash.QSelectorEventLoop(self.qapplication)
         asyncio.set_event_loop(self.lp)
         self.lp.set_exception_handler(lambda l, c: unitttest_exception_handler(self, l, c))
         self.exceptions = []
diff --git a/src/sakia/tests/unit/core/money/__init__.py b/src/sakia/tests/unit/core/money/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/sakia/tests/unit/core/money/test_quantitative.py b/src/sakia/tests/unit/core/money/test_quantitative.py
new file mode 100644
index 0000000000000000000000000000000000000000..dd32a301ff91a7280f982bb66e68ade163d32be4
--- /dev/null
+++ b/src/sakia/tests/unit/core/money/test_quantitative.py
@@ -0,0 +1,144 @@
+import unittest
+from asynctest.mock import Mock, CoroutineMock, patch, PropertyMock
+from PyQt5.QtCore import QLocale
+from sakia.tests import QuamashTest
+from sakia.core.money import Quantitative
+
+
+class TestQuantitative(unittest.TestCase, QuamashTest):
+    def setUp(self):
+        self.setUpQuamash()
+        QLocale.setDefault(QLocale("en_GB"))
+
+    def tearDown(self):
+        self.tearDownQuamash()
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_units(self, app, community):
+        type(community).short_currency = PropertyMock(return_value="TC")
+        referential = Quantitative(0, community, app, None)
+        self.assertEqual(referential.units, "TC")
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_diff_units(self, app, community):
+        type(community).short_currency = PropertyMock(return_value="TC")
+        referential = Quantitative(0, community, app, None)
+        self.assertEqual(referential.units, "TC")
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_value(self, app, community):
+        referential = Quantitative(101010110, community, app, None)
+        async def exec_test():
+            value = await referential.value()
+            self.assertEqual(value, 101010110)
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_differential(self, app, community):
+        referential = Quantitative(110, community, app, None)
+        async def exec_test():
+            value = await referential.value()
+            self.assertEqual(value, 110)
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_localized_no_si(self, app, community):
+        type(community).short_currency = PropertyMock(return_value="TC")
+        referential = Quantitative(101010110, community, app, None)
+        async def exec_test():
+            value = await referential.localized(units=True)
+            self.assertEqual(value, "101,010,110 TC")
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_localized_with_si(self, app, community):
+        type(community).short_currency = PropertyMock(return_value="TC")
+        app.preferences = {
+            'digits_after_comma': 6
+        }
+        referential = Quantitative(101010110, community, app, None)
+        async def exec_test():
+            value = await referential.localized(units=True, international_system=True)
+            self.assertEqual(value, "101.010110 MTC")
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_localized_no_units_no_si(self, app, community):
+        type(community).short_currency = PropertyMock(return_value="TC")
+        app.preferences = {
+            'digits_after_comma': 6
+        }
+        referential = Quantitative(101010110, community, app, None)
+        async def exec_test():
+            value = await referential.localized(units=False, international_system=False)
+            self.assertEqual(value, "101,010,110")
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_localized_no_units_with_si(self, app, community):
+        type(community).short_currency = PropertyMock(return_value="TC")
+        app.preferences = {
+            'digits_after_comma': 6
+        }
+        referential = Quantitative(101010110, community, app, None)
+        async def exec_test():
+            value = await referential.localized(units=False, international_system=True)
+            self.assertEqual(value, "101.010110 M")
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_diff_localized_no_si(self, app, community):
+        type(community).short_currency = PropertyMock(return_value="TC")
+        referential = Quantitative(101010110, community, app, None)
+        async def exec_test():
+            value = await referential.diff_localized(units=True)
+            self.assertEqual(value, "101,010,110 TC")
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_diff_localized_with_si(self, app, community):
+        type(community).short_currency = PropertyMock(return_value="TC")
+        app.preferences = {
+            'digits_after_comma': 6
+        }
+        referential = Quantitative(101010110, community, app, None)
+        async def exec_test():
+            value = await referential.diff_localized(units=True, international_system=True)
+            self.assertEqual(value, "101.010110 MTC")
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_diff_localized_no_units_no_si(self, app, community):
+        type(community).short_currency = PropertyMock(return_value="TC")
+        app.preferences = {
+            'digits_after_comma': 6
+        }
+        referential = Quantitative(101010110, community, app, None)
+        async def exec_test():
+            value = await referential.diff_localized(units=False, international_system=False)
+            self.assertEqual(value, "101,010,110")
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_diff_localized_no_units_with_si(self, app, community):
+        type(community).short_currency = PropertyMock(return_value="TC")
+        app.preferences = {
+            'digits_after_comma': 6
+        }
+        referential = Quantitative(101010110, community, app, None)
+        async def exec_test():
+            value = await referential.diff_localized(units=False, international_system=True)
+            self.assertEqual(value, "101.010110 M")
+        self.lp.run_until_complete(exec_test())
diff --git a/src/sakia/tests/unit/core/money/test_quantitative_zsum.py b/src/sakia/tests/unit/core/money/test_quantitative_zsum.py
new file mode 100644
index 0000000000000000000000000000000000000000..68ecaad7c751ba4b8f6fa014c93875e0bc85ebe7
--- /dev/null
+++ b/src/sakia/tests/unit/core/money/test_quantitative_zsum.py
@@ -0,0 +1,164 @@
+import unittest
+from asynctest.mock import Mock, CoroutineMock, patch, PropertyMock
+from PyQt5.QtCore import QLocale
+from sakia.tests import QuamashTest
+from sakia.core.money import QuantitativeZSum
+
+
+class TestQuantitativeZSum(unittest.TestCase, QuamashTest):
+    def setUp(self):
+        self.setUpQuamash()
+        QLocale.setDefault(QLocale("en_GB"))
+
+    def tearDown(self):
+        self.tearDownQuamash()
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_units(self, app, community):
+        type(community).short_currency = PropertyMock(return_value="TC")
+        referential = QuantitativeZSum(0, community, app, None)
+        self.assertEqual(referential.units, "Q0 TC")
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_diff_units(self, app, community):
+        type(community).short_currency = PropertyMock(return_value="TC")
+        referential = QuantitativeZSum(0, community, app, None)
+        self.assertEqual(referential.units, "Q0 TC")
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_value(self, app, community):
+        referential = QuantitativeZSum(110, community, app, None)
+        community.get_ud_block = CoroutineMock(return_value={'membersCount': 5})
+        community.monetary_mass = CoroutineMock(return_value=500)
+        async def exec_test():
+            value = await referential.value()
+            self.assertEqual(value, 10)
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_differential(self, app, community):
+        community.get_ud_block = CoroutineMock(return_value={'membersCount': 5})
+        community.monetary_mass = CoroutineMock(return_value=500)
+        referential = QuantitativeZSum(110, community, app, None)
+        async def exec_test():
+            value = await referential.value()
+            self.assertEqual(value, 10)
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_localized_no_si(self, app, community):
+        type(community).short_currency = PropertyMock(return_value="TC")
+        community.get_ud_block = CoroutineMock(return_value={'membersCount': 5})
+        community.monetary_mass = CoroutineMock(return_value=500)
+        referential = QuantitativeZSum(110, community, app, None)
+        async def exec_test():
+            value = await referential.localized(units=True)
+            self.assertEqual(value, "10 Q0 TC")
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_localized_with_si(self, app, community):
+        type(community).short_currency = PropertyMock(return_value="TC")
+        community.get_ud_block = CoroutineMock(return_value={'membersCount': 1000})
+        community.monetary_mass = CoroutineMock(return_value=500 * 1000)
+        app.preferences = {
+            'digits_after_comma': 6
+        }
+        referential = QuantitativeZSum(110 * 1000, community, app, None)
+        async def exec_test():
+            value = await referential.localized(units=True, international_system=True)
+            self.assertEqual(value, "109.500000 kQ0 TC")
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_localized_no_units_no_si(self, app, community):
+        type(community).short_currency = PropertyMock(return_value="TC")
+        community.get_ud_block = CoroutineMock(return_value={'membersCount': 5})
+        community.monetary_mass = CoroutineMock(return_value=500)
+        app.preferences = {
+            'digits_after_comma': 6
+        }
+        referential = QuantitativeZSum(110, community, app, None)
+        async def exec_test():
+            value = await referential.localized(units=False, international_system=False)
+            self.assertEqual(value, "10")
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_localized_no_units_with_si(self, app, community):
+        type(community).short_currency = PropertyMock(return_value="TC")
+        community.get_ud_block = CoroutineMock(return_value={'membersCount': 1000})
+        community.monetary_mass = CoroutineMock(return_value=500 * 1000)
+        app.preferences = {
+            'digits_after_comma': 6
+        }
+        referential = QuantitativeZSum(110 * 1000, community, app, None)
+        async def exec_test():
+            value = await referential.localized(units=False, international_system=True)
+            self.assertEqual(value, "109.500000 kQ0 ")
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_diff_localized_no_si(self, app, community):
+        type(community).short_currency = PropertyMock(return_value="TC")
+        community.get_ud_block = CoroutineMock(return_value={'membersCount': 1000})
+        community.monetary_mass = CoroutineMock(return_value=500 * 1000 * 1000)
+        referential = QuantitativeZSum(110 * 1000, community, app, None)
+        async def exec_test():
+            value = await referential.diff_localized(units=True)
+            self.assertEqual(value, "110,000 TC")
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_diff_localized_with_si(self, app, community):
+        type(community).short_currency = PropertyMock(return_value="TC")
+        community.get_ud_block = CoroutineMock(return_value={'membersCount': 10})
+        community.monetary_mass = CoroutineMock(return_value=500 * 1000 * 1000)
+        app.preferences = {
+            'digits_after_comma': 6
+        }
+        referential = QuantitativeZSum(101010110, community, app, None)
+        async def exec_test():
+            value = await referential.diff_localized(units=True, international_system=True)
+            self.assertEqual(value, "101.010110 MTC")
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_diff_localized_no_units_no_si(self, app, community):
+        type(community).short_currency = PropertyMock(return_value="TC")
+        community.get_ud_block = CoroutineMock(return_value={'membersCount': 10})
+        community.monetary_mass = CoroutineMock(return_value=500 * 1000 * 1000)
+        app.preferences = {
+            'digits_after_comma': 6
+        }
+        referential = QuantitativeZSum(101010110, community, app, None)
+        async def exec_test():
+            value = await referential.diff_localized(units=False, international_system=False)
+            self.assertEqual(value, "101,010,110")
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_diff_localized_no_units_with_si(self, app, community):
+        type(community).short_currency = PropertyMock(return_value="TC")
+        community.get_ud_block = CoroutineMock(return_value={'membersCount': 10})
+        community.monetary_mass = CoroutineMock(return_value=500 * 1000 * 1000)
+        app.preferences = {
+            'digits_after_comma': 6
+        }
+        referential = QuantitativeZSum(101010110, community, app, None)
+        async def exec_test():
+            value = await referential.diff_localized(units=False, international_system=True)
+            self.assertEqual(value, "101.010110 M")
+        self.lp.run_until_complete(exec_test())
diff --git a/src/sakia/tests/unit/core/money/test_relative.py b/src/sakia/tests/unit/core/money/test_relative.py
new file mode 100644
index 0000000000000000000000000000000000000000..ae542b05ae8f5f4110dfebd8370ed67297342b46
--- /dev/null
+++ b/src/sakia/tests/unit/core/money/test_relative.py
@@ -0,0 +1,160 @@
+import unittest
+from asynctest.mock import Mock, CoroutineMock, patch, PropertyMock
+from PyQt5.QtCore import QLocale
+from sakia.tests import QuamashTest
+from sakia.core.money import Relative
+
+
+class TestRelative(unittest.TestCase, QuamashTest):
+    def setUp(self):
+        self.setUpQuamash()
+        QLocale.setDefault(QLocale("en_GB"))
+
+    def tearDown(self):
+        self.tearDownQuamash()
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_units(self, app, community):
+        type(community).short_currency = PropertyMock(return_value="TC")
+        referential = Relative(0, community, app, None)
+        self.assertEqual(referential.units, "UD TC")
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_diff_units(self, app, community):
+        type(community).short_currency = PropertyMock(return_value="TC")
+        referential = Relative(0, community, app, None)
+        self.assertEqual(referential.units, "UD TC")
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_value(self, app, community):
+        community.dividend = CoroutineMock(return_value=10000)
+        referential = Relative(10101011, community, app, None)
+        async def exec_test():
+            value = await referential.value()
+            self.assertAlmostEqual(value, 1010.10110)
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_differential(self, app, community):
+        community.dividend = CoroutineMock(return_value=1000)
+        referential = Relative(110, community, app, None)
+        async def exec_test():
+            value = await referential.value()
+            self.assertAlmostEqual(value, 0.11)
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_localized_no_si(self, app, community):
+        community.dividend = CoroutineMock(return_value=1000)
+        type(community).short_currency = PropertyMock(return_value="TC")
+        app.preferences = {
+            'digits_after_comma': 6
+        }
+        referential = Relative(101, community, app, None)
+        async def exec_test():
+            value = await referential.localized(units=True)
+            self.assertEqual(value, "0.101000 UD TC")
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_localized_with_si(self, app, community):
+        community.dividend = CoroutineMock(return_value=1000000)
+        type(community).short_currency = PropertyMock(return_value="TC")
+        app.preferences = {
+            'digits_after_comma': 6
+        }
+        referential = Relative(1011, community, app, None)
+        async def exec_test():
+            value = await referential.localized(units=True, international_system=True)
+            self.assertEqual(value, "1.011000 mUD TC")
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_localized_no_units_no_si(self, app, community):
+        community.dividend = CoroutineMock(return_value=10000)
+        type(community).short_currency = PropertyMock(return_value="TC")
+        app.preferences = {
+            'digits_after_comma': 6
+        }
+        referential = Relative(1011, community, app, None)
+        async def exec_test():
+            value = await referential.localized(units=False, international_system=False)
+            self.assertEqual(value, "0.101100")
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_localized_no_units_with_si(self, app, community):
+        community.dividend = CoroutineMock(return_value=1000000)
+        type(community).short_currency = PropertyMock(return_value="TC")
+        app.preferences = {
+            'digits_after_comma': 6
+        }
+        referential = Relative(1011, community, app, None)
+        async def exec_test():
+            value = await referential.localized(units=False, international_system=True)
+            self.assertEqual(value, "1.011000 mUD ")
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_diff_localized_no_si(self, app, community):
+        community.dividend = CoroutineMock(return_value=10000)
+        type(community).short_currency = PropertyMock(return_value="TC")
+        app.preferences = {
+            'digits_after_comma': 6
+        }
+        referential = Relative(1011, community, app, None)
+        async def exec_test():
+            value = await referential.diff_localized(units=True)
+            self.assertEqual(value, "0.101100 UD TC")
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_diff_localized_with_si(self, app, community):
+        community.dividend = CoroutineMock(return_value=1000000)
+        type(community).short_currency = PropertyMock(return_value="TC")
+        app.preferences = {
+            'digits_after_comma': 6
+        }
+        referential = Relative(1011, community, app, None)
+        async def exec_test():
+            value = await referential.diff_localized(units=True, international_system=True)
+            self.assertEqual(value, "1.011000 mUD TC")
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_diff_localized_no_units_no_si(self, app, community):
+        community.dividend = CoroutineMock(return_value=1000000)
+        type(community).short_currency = PropertyMock(return_value="TC")
+        app.preferences = {
+            'digits_after_comma': 6
+        }
+        referential = Relative(1011, community, app, None)
+        async def exec_test():
+            value = await referential.diff_localized(units=False, international_system=False)
+            self.assertEqual(value, "0.001011")
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_diff_localized_no_units_with_si(self, app, community):
+        community.dividend = CoroutineMock(return_value=1000000)
+        type(community).short_currency = PropertyMock(return_value="TC")
+        app.preferences = {
+            'digits_after_comma': 6
+        }
+        referential = Relative(1011, community, app, None)
+        async def exec_test():
+            value = await referential.diff_localized(units=False, international_system=True)
+            self.assertEqual(value, "1.011000 mUD ")
+        self.lp.run_until_complete(exec_test())
\ No newline at end of file
diff --git a/src/sakia/tests/unit/core/money/test_relative_to_past.py b/src/sakia/tests/unit/core/money/test_relative_to_past.py
new file mode 100644
index 0000000000000000000000000000000000000000..0a0f5e2d83b6512d01d745b1e66bdfb66d9342f5
--- /dev/null
+++ b/src/sakia/tests/unit/core/money/test_relative_to_past.py
@@ -0,0 +1,192 @@
+import unittest
+from asynctest.mock import Mock, CoroutineMock, patch, PropertyMock
+from PyQt5.QtCore import QLocale, QDateTime
+from sakia.tests import QuamashTest
+from sakia.core.money import RelativeToPast
+
+
+class TestRelativeToPast(unittest.TestCase, QuamashTest):
+    def setUp(self):
+        self.setUpQuamash()
+        QLocale.setDefault(QLocale("en_GB"))
+
+    def tearDown(self):
+        self.tearDownQuamash()
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_units(self, app, community):
+        type(community).short_currency = PropertyMock(return_value="TC")
+        referential = RelativeToPast(0, community, app, 100)
+        self.assertEqual(referential.units, "UD(t) TC")
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_diff_units(self, app, community):
+        type(community).short_currency = PropertyMock(return_value="TC")
+        referential = RelativeToPast(0, community, app, 100)
+        self.assertEqual(referential.units, "UD(t) TC")
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_value(self, app, community):
+        community.dividend = CoroutineMock(return_value=10000)
+        referential = RelativeToPast(10101011, community, app, 100)
+        async def exec_test():
+            value = await referential.value()
+            self.assertAlmostEqual(value, 1010.10110)
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_differential(self, app, community):
+        community.dividend = CoroutineMock(return_value=1000)
+        referential = RelativeToPast(110, community, app, 100)
+        async def exec_test():
+            value = await referential.value()
+            self.assertAlmostEqual(value, 0.11)
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_localized_no_si(self, app, community):
+        community.dividend = CoroutineMock(return_value=1000)
+        community.get_block = CoroutineMock(return_value={'medianTime': 1452663088792})
+        type(community).short_currency = PropertyMock(return_value="TC")
+        app.preferences = {
+            'digits_after_comma': 6
+        }
+        referential = RelativeToPast(101, community, app, 100)
+        async def exec_test():
+            value = await referential.localized(units=True)
+            self.assertEqual(value, "0.101000 UD({0}) TC".format(QLocale.toString(
+                            QLocale(),
+                            QDateTime.fromTime_t(1452663088792).date(),
+                            QLocale.dateFormat(QLocale(), QLocale.ShortFormat)
+                        )))
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_localized_with_si(self, app, community):
+        community.dividend = CoroutineMock(return_value=1000000)
+        community.get_block = CoroutineMock(return_value={'medianTime': 1452663088792})
+        type(community).short_currency = PropertyMock(return_value="TC")
+        app.preferences = {
+            'digits_after_comma': 6
+        }
+        referential = RelativeToPast(1011, community, app, 100)
+        async def exec_test():
+            value = await referential.localized(units=True, international_system=True)
+            self.assertEqual(value, "1.011000 mUD({0}) TC".format(QLocale.toString(
+                            QLocale(),
+                            QDateTime.fromTime_t(1452663088792).date(),
+                            QLocale.dateFormat(QLocale(), QLocale.ShortFormat)
+                        )))
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_localized_no_units_no_si(self, app, community):
+        community.dividend = CoroutineMock(return_value=10000)
+        community.get_block = CoroutineMock(return_value={'medianTime': 1452663088792})
+        type(community).short_currency = PropertyMock(return_value="TC")
+        app.preferences = {
+            'digits_after_comma': 6
+        }
+        referential = RelativeToPast(1011, community, app, 100)
+        async def exec_test():
+            value = await referential.localized(units=False, international_system=False)
+            self.assertEqual(value, "0.101100")
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_localized_no_units_with_si(self, app, community):
+        community.dividend = CoroutineMock(return_value=1000000)
+        community.get_block = CoroutineMock(return_value={'medianTime': 1452663088792})
+        type(community).short_currency = PropertyMock(return_value="TC")
+        app.preferences = {
+            'digits_after_comma': 6
+        }
+        referential = RelativeToPast(1011, community, app, 100)
+        async def exec_test():
+            value = await referential.localized(units=False, international_system=True)
+            self.assertEqual(value, "1.011000 mUD({0}) ".format(QLocale.toString(
+                            QLocale(),
+                            QDateTime.fromTime_t(1452663088792).date(),
+                            QLocale.dateFormat(QLocale(), QLocale.ShortFormat)
+                        )))
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_diff_localized_no_si(self, app, community):
+        community.dividend = CoroutineMock(return_value=10000)
+        community.get_block = CoroutineMock(return_value={'medianTime': 1452663088792})
+        type(community).short_currency = PropertyMock(return_value="TC")
+        app.preferences = {
+            'digits_after_comma': 6
+        }
+        referential = RelativeToPast(1011, community, app, 100)
+        async def exec_test():
+            value = await referential.diff_localized(units=True)
+            self.assertEqual(value, "0.101100 UD({0}) TC".format(QLocale.toString(
+                            QLocale(),
+                            QDateTime.fromTime_t(1452663088792).date(),
+                            QLocale.dateFormat(QLocale(), QLocale.ShortFormat)
+                        )))
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_diff_localized_with_si(self, app, community):
+        community.dividend = CoroutineMock(return_value=1000000)
+        community.get_block = CoroutineMock(return_value={'medianTime': 1452663088792})
+        type(community).short_currency = PropertyMock(return_value="TC")
+        app.preferences = {
+            'digits_after_comma': 6
+        }
+        referential = RelativeToPast(1011, community, app, 100)
+        async def exec_test():
+            value = await referential.diff_localized(units=True, international_system=True)
+            self.assertEqual(value, "1.011000 mUD({0}) TC".format(QLocale.toString(
+                            QLocale(),
+                            QDateTime.fromTime_t(1452663088792).date(),
+                            QLocale.dateFormat(QLocale(), QLocale.ShortFormat)
+                        )))
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_diff_localized_no_units_no_si(self, app, community):
+        community.dividend = CoroutineMock(return_value=10000)
+        community.get_block = CoroutineMock(return_value={'medianTime': 1452663088792})
+        type(community).short_currency = PropertyMock(return_value="TC")
+        app.preferences = {
+            'digits_after_comma': 6
+        }
+        referential = RelativeToPast(1011, community, app, 100)
+        async def exec_test():
+            value = await referential.diff_localized(units=False, international_system=False)
+            self.assertEqual(value, "0.101100")
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_diff_localized_no_units_with_si(self, app, community):
+        community.dividend = CoroutineMock(return_value=1000000)
+        community.get_block = CoroutineMock(return_value={'medianTime': 1452663088792})
+        type(community).short_currency = PropertyMock(return_value="TC")
+        app.preferences = {
+            'digits_after_comma': 6
+        }
+        referential = RelativeToPast(1011, community, app, 100)
+        async def exec_test():
+            value = await referential.diff_localized(units=False, international_system=True)
+            self.assertEqual(value, "1.011000 mUD({0}) ".format(QLocale.toString(
+                            QLocale(),
+                            QDateTime.fromTime_t(1452663088792).date(),
+                            QLocale.dateFormat(QLocale(), QLocale.ShortFormat)
+                        )))
+        self.lp.run_until_complete(exec_test())
diff --git a/src/sakia/tests/unit/core/money/test_relative_zsum.py b/src/sakia/tests/unit/core/money/test_relative_zsum.py
new file mode 100644
index 0000000000000000000000000000000000000000..2a8208997fc6f2a7a34c7fece2fdd5cfe46f0eda
--- /dev/null
+++ b/src/sakia/tests/unit/core/money/test_relative_zsum.py
@@ -0,0 +1,184 @@
+import unittest
+from asynctest.mock import Mock, CoroutineMock, patch, PropertyMock
+from PyQt5.QtCore import QLocale
+from sakia.tests import QuamashTest
+from sakia.core.money import RelativeZSum
+
+
+class TestRelativeZSum(unittest.TestCase, QuamashTest):
+    def setUp(self):
+        self.setUpQuamash()
+        QLocale.setDefault(QLocale("en_GB"))
+
+    def tearDown(self):
+        self.tearDownQuamash()
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_units(self, app, community):
+        type(community).short_currency = PropertyMock(return_value="TC")
+        referential = RelativeZSum(0, community, app, None)
+        self.assertEqual(referential.units, "R0 TC")
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_diff_units(self, app, community):
+        type(community).short_currency = PropertyMock(return_value="TC")
+        referential = RelativeZSum(0, community, app, None)
+        self.assertEqual(referential.units, "R0 TC")
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_value(self, app, community):
+        referential = RelativeZSum(110, community, app, None)
+        community.dividend = CoroutineMock(return_value=100)
+        community.get_ud_block = CoroutineMock(side_effect=lambda *args, **kwargs: \
+                                                            {'membersCount': 5, "monetaryMass": 500, "dividend": 100} if 'x' in kwargs \
+                                                            else {'membersCount': 5, "monetaryMass": 1050, "dividend": 100} )
+        async def exec_test():
+            value = await referential.value()
+            self.assertAlmostEqual(value, 0.10)
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_differential(self, app, community):
+        community.dividend = CoroutineMock(return_value=100)
+        community.get_ud_block = CoroutineMock(side_effect=lambda *args, **kwargs: \
+                                                            {'membersCount': 5, "monetaryMass": 500, "dividend": 100} if 'x' in kwargs \
+                                                            else {'membersCount': 5, "monetaryMass": 1050, "dividend": 100} )
+        referential = RelativeZSum(110, community, app, None)
+        async def exec_test():
+            value = await referential.value()
+            self.assertAlmostEqual(value, 0.10)
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_localized_no_si(self, app, community):
+        type(community).short_currency = PropertyMock(return_value="TC")
+        community.dividend = CoroutineMock(return_value=100)
+        community.get_ud_block = CoroutineMock(side_effect=lambda *args, **kwargs: \
+                                                            {'membersCount': 5, "monetaryMass": 500, "dividend": 100} if 'x' in kwargs \
+                                                            else {'membersCount': 5, "monetaryMass": 1050, "dividend": 100} )
+        referential = RelativeZSum(110, community, app, None)
+        async def exec_test():
+            value = await referential.localized(units=True)
+            self.assertEqual(value, "0.1 R0 TC")
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_localized_with_si(self, app, community):
+        type(community).short_currency = PropertyMock(return_value="TC")
+        community.dividend = CoroutineMock(return_value=100)
+        community.get_ud_block = CoroutineMock(side_effect=lambda *args, **kwargs: \
+                                                            {'membersCount': 5, "monetaryMass": 500, "dividend": 100} if 'x' in kwargs \
+                                                            else {'membersCount': 5, "monetaryMass": 1050, "dividend": 100} )
+        app.preferences = {
+            'digits_after_comma': 6
+        }
+        referential = RelativeZSum(110, community, app, None)
+        async def exec_test():
+            value = await referential.localized(units=True, international_system=True)
+            self.assertEqual(value, "100.000000 mR0 TC")
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_localized_no_units_no_si(self, app, community):
+        type(community).short_currency = PropertyMock(return_value="TC")
+        community.dividend = CoroutineMock(return_value=100)
+        community.get_ud_block = CoroutineMock(side_effect=lambda *args, **kwargs: \
+                                                            {'membersCount': 5, "monetaryMass": 500, "dividend": 100} if 'x' in kwargs \
+                                                            else {'membersCount': 5, "monetaryMass": 1050, "dividend": 100} )
+        app.preferences = {
+            'digits_after_comma': 6
+        }
+        referential = RelativeZSum(110, community, app, None)
+        async def exec_test():
+            value = await referential.localized(units=False, international_system=False)
+            self.assertEqual(value, "0.100000")
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_localized_no_units_with_si(self, app, community):
+        type(community).short_currency = PropertyMock(return_value="TC")
+        community.dividend = CoroutineMock(return_value=100)
+        community.get_ud_block = CoroutineMock(side_effect=lambda *args, **kwargs: \
+                                                            {'membersCount': 5, "monetaryMass": 500, "dividend": 100} if 'x' in kwargs \
+                                                            else {'membersCount': 5, "monetaryMass": 1050, "dividend": 100} )
+        app.preferences = {
+            'digits_after_comma': 6
+        }
+        referential = RelativeZSum(110, community, app, None)
+        async def exec_test():
+            value = await referential.localized(units=False, international_system=True)
+            self.assertEqual(value, "100.000000 mR0 ")
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_diff_localized_no_si(self, app, community):
+        type(community).short_currency = PropertyMock(return_value="TC")
+        community.dividend = CoroutineMock(return_value=100)
+        community.get_ud_block = CoroutineMock(side_effect=lambda *args, **kwargs: \
+                                                            {'membersCount': 5, "monetaryMass": 500, "dividend": 100} if 'x' in kwargs \
+                                                            else {'membersCount': 5, "monetaryMass": 1050, "dividend": 100} )
+        referential = RelativeZSum(90, community, app, None)
+        async def exec_test():
+            value = await referential.diff_localized(units=True)
+            self.assertEqual(value, "0.9 R0 TC")
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_diff_localized_with_si(self, app, community):
+        type(community).short_currency = PropertyMock(return_value="TC")
+        community.dividend = CoroutineMock(return_value=100)
+        community.get_ud_block = CoroutineMock(side_effect=lambda *args, **kwargs: \
+                                                            {'membersCount': 5, "monetaryMass": 500, "dividend": 100} if 'x' in kwargs \
+                                                            else {'membersCount': 5, "monetaryMass": 1050, "dividend": 100} )
+        app.preferences = {
+            'digits_after_comma': 6
+        }
+        referential = RelativeZSum(90, community, app, None)
+        async def exec_test():
+            value = await referential.diff_localized(units=True, international_system=True)
+            self.assertEqual(value, "900.000000 mR0 TC")
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_diff_localized_no_units_no_si(self, app, community):
+        type(community).short_currency = PropertyMock(return_value="TC")
+        community.dividend = CoroutineMock(return_value=100)
+        community.get_ud_block = CoroutineMock(side_effect=lambda *args, **kwargs: \
+                                                            {'membersCount': 5, "monetaryMass": 500, "dividend": 100} if 'x' in kwargs \
+                                                            else {'membersCount': 5, "monetaryMass": 1050, "dividend": 100} )
+        app.preferences = {
+            'digits_after_comma': 6
+        }
+        referential = RelativeZSum(90, community, app, None)
+        async def exec_test():
+            value = await referential.diff_localized(units=False, international_system=False)
+            self.assertEqual(value, "0.900000")
+        self.lp.run_until_complete(exec_test())
+
+    @patch('sakia.core.Community')
+    @patch('sakia.core.Application')
+    def test_diff_localized_no_units_with_si(self, app, community):
+        type(community).short_currency = PropertyMock(return_value="TC")
+        community.dividend = CoroutineMock(return_value=100)
+        community.get_ud_block = CoroutineMock(side_effect=lambda *args, **kwargs: \
+                                                            {'membersCount': 5, "monetaryMass": 500, "dividend": 100} if 'x' in kwargs \
+                                                            else {'membersCount': 5, "monetaryMass": 1050, "dividend": 100} )
+        app.preferences = {
+            'digits_after_comma': 6
+        }
+        referential = RelativeZSum(90, community, app, None)
+        async def exec_test():
+            value = await referential.diff_localized(units=False, international_system=True)
+            self.assertEqual(value, "900.000000 mR0 ")
+        self.lp.run_until_complete(exec_test())
diff --git a/src/sakia/tests/unit/core/test_bma_access.py b/src/sakia/tests/unit/core/test_bma_access.py
index 293eb3ddf51a74dbc177c8b33a9825314c7e5380..d382a5bac015fa36ddb10f474d8defd2fecebc65 100644
--- a/src/sakia/tests/unit/core/test_bma_access.py
+++ b/src/sakia/tests/unit/core/test_bma_access.py
@@ -1,8 +1,4 @@
-import sys
 import unittest
-import asyncio
-import quamash
-import logging
 import time
 from PyQt5.QtCore import QLocale
 from sakia.core.registry.identities import Identity, IdentitiesRegistry, LocalState, BlockchainState
@@ -11,10 +7,8 @@ from sakia.tests.mocks.bma import nice_blockchain, corrupted
 from sakia.tests import QuamashTest
 from sakia.core import Application, Community
 from sakia.core.net import Network, Node
-from ucoinpy.documents.peer import BMAEndpoint
+from ucoinpy.documents.peer import Peer
 from sakia.core.net.api.bma.access import BmaAccess
-from sakia.tools.exceptions import MembershipNotFoundError
-from ucoinpy.api.bma import API
 
 
 class TestBmaAccess(unittest.TestCase, QuamashTest):
@@ -26,8 +20,16 @@ class TestBmaAccess(unittest.TestCase, QuamashTest):
         self.application = Application(self.qapplication, self.lp, self.identities_registry)
         self.application.preferences['notifications'] = False
 
-        self.endpoint = BMAEndpoint("", "127.0.0.1", "", 50004)
-        self.node = Node("test_currency", [self.endpoint],
+        self.peer = Peer.from_signed_raw("""Version: 1
+Type: Peer
+Currency: meta_brouzouf
+PublicKey: 8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU
+Block: 48698-000005E0F228038E4DDD4F6CA4ACB01EC88FBAF8
+Endpoints:
+BASIC_MERKLED_API ucoin.inso.ovh 80
+82o1sNCh1bLpUXU6nacbK48HBcA9Eu2sPkL1/3c2GtDPxBUZd2U2sb7DxwJ54n6ce9G0Oy7nd1hCxN3fS0oADw==
+""")
+        self.node = Node(self.peer,
                          "", "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk",
                          None, Node.ONLINE,
                          time.time(), {}, "ucoin", "0.12.0", 0)
diff --git a/src/sakia/tests/unit/core/test_community.py b/src/sakia/tests/unit/core/test_community.py
index acf5c176be84783ec2fabde14674f3cd9e50e9bd..80e0f2f34de13303b2bf00ab29802b5ccd34bde5 100644
--- a/src/sakia/tests/unit/core/test_community.py
+++ b/src/sakia/tests/unit/core/test_community.py
@@ -1,6 +1,6 @@
 import sys
 import unittest
-import logging
+from distutils.version import StrictVersion
 from PyQt5.QtCore import QLocale
 from sakia.core.net.api.bma.access import BmaAccess
 from sakia.core.net.network import Network
@@ -22,6 +22,6 @@ class TestCommunity(unittest.TestCase, QuamashTest):
         community = Community("test_currency", network, bma_access)
 
         json_data = community.jsonify()
-        community_from_json = Community.load(json_data)
+        community_from_json = Community.load(json_data, StrictVersion('0.12.0'))
         self.assertEqual(community.name, community_from_json.name)
         self.assertEqual(len(community.network._nodes), len(community_from_json.network._nodes))
diff --git a/src/sakia/tests/unit/core/test_identity.py b/src/sakia/tests/unit/core/test_identity.py
index ec7044f771f6e5e28bfffb9bc5eb4c48a5960d2e..26186f7a190b651fc46b6afb32fc6e3333a82019 100644
--- a/src/sakia/tests/unit/core/test_identity.py
+++ b/src/sakia/tests/unit/core/test_identity.py
@@ -27,8 +27,8 @@ class TestIdentity(unittest.TestCase, QuamashTest):
         self.application = Application(self.qapplication, self.lp, self.identities_registry)
         self.application.preferences['notifications'] = False
 
-        self.endpoint = BMAEndpoint("", "127.0.0.1", "", 50009)
-        self.node = Node("test_currency", [self.endpoint],
+        self.mock_nice_blockchain = nice_blockchain.get_mock(self.lp)
+        self.node = Node(self.mock_nice_blockchain.peer(),
                          "", "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk",
                          None, Node.ONLINE,
                          time.time(), {}, "ucoin", "0.12.0", 0)
@@ -40,14 +40,13 @@ class TestIdentity(unittest.TestCase, QuamashTest):
         self.tearDownQuamash()
 
     def test_identity_certifiers_of(self):
-        mock = nice_blockchain.get_mock(self.lp)
-
+        time.sleep(1)
         identity = Identity("john", "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ", 1441130831,
                             LocalState.COMPLETED, BlockchainState.VALIDATED)
 
         async def exec_test():
-            srv, port, url = await mock.create_server()
-            self.endpoint.port = port
+            srv, port, url = await self.mock_nice_blockchain.create_server()
+            self.addCleanup(srv.close)
             certifiers = await identity.certifiers_of(self.identities_registry, self.community)
 
             self.assertEqual(len(certifiers), 1)
@@ -58,14 +57,13 @@ class TestIdentity(unittest.TestCase, QuamashTest):
         self.lp.run_until_complete(exec_test())
 
     def test_identity_membership(self):
-        mock = nice_blockchain.get_mock(self.lp)
-        time.sleep(2)
+        time.sleep(1)
         identity = Identity("john", "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ", 1441130831,
                             LocalState.COMPLETED, BlockchainState.VALIDATED)
 
         async def exec_test():
-            srv, port, url = await mock.create_server()
-            self.endpoint.port = port
+            srv, port, url = await self.mock_nice_blockchain.create_server()
+            self.addCleanup(srv.close)
             ms = await identity.membership(self.community)
             self.assertEqual(ms["blockNumber"], 0)
             self.assertEqual(ms["blockHash"], "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709")
@@ -76,15 +74,23 @@ class TestIdentity(unittest.TestCase, QuamashTest):
 
     def test_identity_corrupted_membership(self):
         mock = corrupted.get_mock(self.lp)
-        time.sleep(2)
+        time.sleep(1)
+        node = Node(mock.peer(),
+                         "", "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk",
+                         None, Node.ONLINE,
+                         time.time(), {}, "ucoin", "0.12.0", 0)
+        network = Network.create(node)
+        bma_access = BmaAccess.create(network)
+        community = Community("test_currency", network, bma_access)
+
         identity = Identity("john", "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ", 1441130831,
                             LocalState.COMPLETED, BlockchainState.VALIDATED)
 
         async def exec_test():
             srv, port, url = await mock.create_server()
-            self.endpoint.port = port
+            self.addCleanup(srv.close)
             with self.assertRaises(MembershipNotFoundError):
-                await identity.membership(self.community)
+                await identity.membership(community)
 
         self.lp.run_until_complete(exec_test())
 
diff --git a/src/sakia/tests/unit/core/test_node.py b/src/sakia/tests/unit/core/test_node.py
new file mode 100644
index 0000000000000000000000000000000000000000..cf184e411e198291997e7ebb87460c96acbd85fc
--- /dev/null
+++ b/src/sakia/tests/unit/core/test_node.py
@@ -0,0 +1,122 @@
+import unittest
+from asynctest import CoroutineMock, patch
+from ucoinpy.documents import Peer, BlockId
+from PyQt5.QtCore import QLocale
+from sakia.core.net import Node
+from sakia.tests import QuamashTest
+from sakia.tests.mocks.bma import nice_blockchain
+from distutils.version import StrictVersion
+
+
+class TestNode(unittest.TestCase, QuamashTest):
+    def setUp(self):
+        self.setUpQuamash()
+        QLocale.setDefault(QLocale("en_GB"))
+
+    def tearDown(self):
+        self.tearDownQuamash()
+
+    def test_from_peer(self):
+        peer = Peer.from_signed_raw("""Version: 1
+Type: Peer
+Currency: meta_brouzouf
+PublicKey: 8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU
+Block: 48698-000005E0F228038E4DDD4F6CA4ACB01EC88FBAF8
+Endpoints:
+BASIC_MERKLED_API ucoin.inso.ovh 80
+82o1sNCh1bLpUXU6nacbK48HBcA9Eu2sPkL1/3c2GtDPxBUZd2U2sb7DxwJ54n6ce9G0Oy7nd1hCxN3fS0oADw==
+""")
+        node = Node.from_peer('meta_brouzouf', peer, "8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU")
+        self.assertEqual(node.pubkey, "8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU")
+        self.assertEqual(node.endpoint.inline(), "BASIC_MERKLED_API ucoin.inso.ovh 80")
+        self.assertEqual(node.currency, "meta_brouzouf")
+
+    @patch('ucoinpy.api.bma.network.Peering')
+    def test_from_address(self, peering):
+        peering.return_value.get = CoroutineMock(return_value={
+            "version": 1,
+            "currency": "meta_brouzouf",
+            "endpoints": [
+                "BASIC_MERKLED_API ucoin.inso.ovh 80"
+            ],
+            "block": "48698-000005E0F228038E4DDD4F6CA4ACB01EC88FBAF8",
+            "signature": "82o1sNCh1bLpUXU6nacbK48HBcA9Eu2sPkL1/3c2GtDPxBUZd2U2sb7DxwJ54n6ce9G0Oy7nd1hCxN3fS0oADw==",
+            "raw": "Version: 1\nType: Peer\nCurrency: meta_brouzouf\nPublicKey: 8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU\nBlock: 48698-000005E0F228038E4DDD4F6CA4ACB01EC88FBAF8\nEndpoints:\nBASIC_MERKLED_API ucoin.inso.ovh 80\n",
+            "pubkey": "8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU"
+        })
+
+        async def exec_test():
+            node = await Node.from_address("meta_brouzouf", "127.0.0.1", 9000)
+            self.assertEqual(node.pubkey, "8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU")
+            self.assertEqual(node.endpoint.inline(), "BASIC_MERKLED_API ucoin.inso.ovh 80")
+            self.assertEqual(node.currency, "meta_brouzouf")
+
+        self.lp.run_until_complete(exec_test())
+
+    def test_from_json_011(self):
+        json_data = {"version": "0.12.0", "state": 1, "fork_window": 0, "uid": "cgeek",
+                      "block": nice_blockchain.bma_blockchain_current,
+                      "endpoints": ["BASIC_MERKLED_API metab.ucoin.io 88.174.120.187 9201"],
+                      "pubkey": "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk",
+                      "last_change": 1448199706.6561477, "currency": "meta_brouzouf", "sofware": "ucoin"}
+        node = Node.from_json("meta_brouzouf", json_data, StrictVersion('0.11.5'))
+        self.assertEqual(node.version, "0.12.0")
+        self.assertEqual(node.state, 1)
+        self.assertEqual(node.fork_window, 0)
+        self.assertEqual(node.uid, "cgeek")
+        self.assertEqual(node.block, nice_blockchain.bma_blockchain_current)
+        self.assertEqual(node.endpoint.inline(), "BASIC_MERKLED_API metab.ucoin.io 88.174.120.187 9201")
+        self.assertEqual(node.pubkey, "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk")
+        self.assertEqual(node.last_change, 1448199706.6561477)
+        self.assertEqual(node.currency, "meta_brouzouf")
+        self.assertEqual(node.peer.pubkey, "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk")
+        self.assertEqual(BlockId.from_str(node.peer.blockid).number, 0)
+
+    def test_from_json_to_json(self):
+        json_data = {"version": "0.12.0", "state": 1, "fork_window": 0, "uid": "inso",
+                      "block": nice_blockchain.bma_blockchain_current,
+                      "peer": """Version: 1
+Type: Peer
+Currency: meta_brouzouf
+PublicKey: 8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU
+Block: 48698-000005E0F228038E4DDD4F6CA4ACB01EC88FBAF8
+Endpoints:
+BASIC_MERKLED_API ucoin.inso.ovh 80
+82o1sNCh1bLpUXU6nacbK48HBcA9Eu2sPkL1/3c2GtDPxBUZd2U2sb7DxwJ54n6ce9G0Oy7nd1hCxN3fS0oADw==
+""",
+                      "pubkey": "8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU",
+                      "last_change": 1448199706.6561477, "software": "ucoin"}
+        node = Node.from_json("meta_brouzouf", json_data, StrictVersion('0.12.0'))
+        self.assertEqual(node.version, "0.12.0")
+        self.assertEqual(node.state, 1)
+        self.assertEqual(node.fork_window, 0)
+        self.assertEqual(node.uid, "inso")
+        self.assertEqual(node.block, nice_blockchain.bma_blockchain_current)
+        self.assertEqual(node.endpoint.inline(), "BASIC_MERKLED_API ucoin.inso.ovh 80")
+        self.assertEqual(node.pubkey, "8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU")
+        self.assertEqual(node.last_change, 1448199706.6561477)
+        self.assertEqual(node.currency, "meta_brouzouf")
+        self.assertEqual(node.peer.pubkey, "8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU")
+        self.assertEqual(BlockId.from_str(node.peer.blockid).number, 48698)
+        self.assertEqual(BlockId.from_str(node.peer.blockid).sha_hash, "000005E0F228038E4DDD4F6CA4ACB01EC88FBAF8")
+
+        result = node.jsonify()
+        for key in result:
+            self.assertEqual(result[key], json_data[key], "Error with key {0}".format(key))
+
+    def test_jsonify_root_node(self):
+        peer = Peer.from_signed_raw("""Version: 1
+Type: Peer
+Currency: meta_brouzouf
+PublicKey: 8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU
+Block: 48698-000005E0F228038E4DDD4F6CA4ACB01EC88FBAF8
+Endpoints:
+BASIC_MERKLED_API ucoin.inso.ovh 80
+82o1sNCh1bLpUXU6nacbK48HBcA9Eu2sPkL1/3c2GtDPxBUZd2U2sb7DxwJ54n6ce9G0Oy7nd1hCxN3fS0oADw==
+""")
+        node = Node(peer, "inso", "8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU", nice_blockchain.bma_blockchain_current,
+                 Node.ONLINE, 1111111111, {}, "ucoin", "0.12", 0)
+        result = node.jsonify_root_node()
+        self.assertEqual(result['pubkey'], "8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU")
+        self.assertEqual(result['uid'], "inso")
+        self.assertEqual(result['peer'], peer.signed_raw())
\ No newline at end of file
diff --git a/src/sakia/tests/unit/gui/test_context_menu.py b/src/sakia/tests/unit/gui/test_context_menu.py
new file mode 100644
index 0000000000000000000000000000000000000000..299918431949ab12364406a421775b5fde4de434
--- /dev/null
+++ b/src/sakia/tests/unit/gui/test_context_menu.py
@@ -0,0 +1,66 @@
+import unittest
+from unittest.mock import patch, MagicMock, Mock
+from asynctest.mock import CoroutineMock
+from PyQt5.QtCore import QLocale
+from sakia.tests import QuamashTest
+from sakia.tests.mocks.bma import nice_blockchain
+from sakia.gui.widgets.context_menu import ContextMenu
+
+
+class TestContextMenu(unittest.TestCase, QuamashTest):
+    def setUp(self):
+        self.setUpQuamash()
+        QLocale.setDefault(QLocale("en_GB"))
+
+        self.identity = Mock(specs='sakia.core.registry.Identity')
+        self.identity.pubkey = "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk"
+        self.identity.uid = "A"
+
+        self.app = MagicMock(specs='sakia.core.Application')
+        self.account = MagicMock(specs='sakia.core.Account')
+        self.community = MagicMock(specs='sakia.core.Community')
+        self.password_asker = MagicMock(specs='sakia.gui.password_asker.PasswordAsker')
+
+    def tearDown(self):
+        self.tearDownQuamash()
+
+    @patch('PyQt5.QtWidgets.QMenu', create=True)
+    def test_view_in_wot(self, qmenu):
+        wot_refreshed = False
+
+        def refresh_wot(identity):
+            nonlocal wot_refreshed
+            self.assertEqual(identity, self.identity)
+            wot_refreshed = True
+
+        async def exec_test():
+            context_menu = ContextMenu(qmenu, self.app, self.account, self.community, self.password_asker)
+            context_menu.view_identity_in_wot.connect(refresh_wot)
+            context_menu.view_wot(self.identity)
+
+        self.lp.run_until_complete(exec_test())
+        self.assertTrue(wot_refreshed)
+
+    @patch('PyQt5.QtWidgets.QMenu', create=True)
+    def test_copy_pubkey_to_clipboard(self, qmenu):
+        app = Mock('sakia.core.Application')
+        async def exec_test():
+            context_menu = ContextMenu(qmenu, self.app, self.account, self.community, self.password_asker)
+            context_menu.copy_pubkey_to_clipboard(self.identity)
+        self.lp.run_until_complete(exec_test())
+        self.assertEqual(self.qapplication.clipboard().text(), "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk")
+
+    @patch('PyQt5.QtWidgets.QMenu', create=True)
+    def test_copy_block_to_clipboard(self, qmenu):
+        self.community.get_block = CoroutineMock(side_effect=lambda n: nice_blockchain.bma_blockchain_current if n == 15 \
+                                                    else nice_blockchain.bma_blockchain_0)
+        self.qapplication.clipboard().clear()
+        async def exec_test():
+            context_menu = ContextMenu(qmenu, self.app, self.account, self.community, self.password_asker)
+            context_menu.community = self.community
+            context_menu.copy_block_to_clipboard(15)
+
+        self.lp.run_until_complete(exec_test())
+        raw_block = "{0}{1}\n".format(nice_blockchain.bma_blockchain_current["raw"],
+                                      nice_blockchain.bma_blockchain_current["signature"])
+        self.assertEqual(self.qapplication.clipboard().text(), raw_block)
diff --git a/src/sakia/tests/unit/gui/views/test_explorer_node.py b/src/sakia/tests/unit/gui/views/test_explorer_node.py
index cd54b19f534f54e2931d1f092d872f1d1f3bc993..e684d5ab56d23107426561f4ed721e5126d30f84 100644
--- a/src/sakia/tests/unit/gui/views/test_explorer_node.py
+++ b/src/sakia/tests/unit/gui/views/test_explorer_node.py
@@ -72,9 +72,9 @@ class TestExplorerNode(unittest.TestCase, QuamashTest):
         async def exec_test():
             node = ExplorerNode(("A", metadata), QPointF(0, 0), nx_pos, 0, 1)
             bounding_rect = node.boundingRect()
-            self.assertAlmostEqual(bounding_rect.x(), -0.5, delta=5)
-            self.assertAlmostEqual(bounding_rect.y(), -0.5, delta=5)
-            self.assertAlmostEqual(bounding_rect.width(), 19.59375, delta=5)
-            self.assertAlmostEqual(bounding_rect.height(), 37.0, delta=5)
+            self.assertAlmostEqual(bounding_rect.x(), -0.5, delta=15)
+            self.assertAlmostEqual(bounding_rect.y(), -0.5, delta=15)
+            self.assertAlmostEqual(bounding_rect.width(), 19.59375, delta=15)
+            self.assertAlmostEqual(bounding_rect.height(), 37.0, delta=15)
 
         self.lp.run_until_complete(exec_test())
diff --git a/src/sakia/tests/unit/gui/views/test_wot_node.py b/src/sakia/tests/unit/gui/views/test_wot_node.py
index a92ba2daa72a6309c08b885178f3a16274b989db..6bf361fa23537deb98c11b0a71fbc03dcd91c5c1 100644
--- a/src/sakia/tests/unit/gui/views/test_wot_node.py
+++ b/src/sakia/tests/unit/gui/views/test_wot_node.py
@@ -74,7 +74,7 @@ class TestWotNode(unittest.TestCase, QuamashTest):
             bounding_rect = node.boundingRect()
             self.assertAlmostEqual(bounding_rect.x(), -0.5, delta=1)
             self.assertAlmostEqual(bounding_rect.y(), -0.5, delta=1)
-            self.assertAlmostEqual(bounding_rect.width(), 19.59375, delta=5)
-            self.assertAlmostEqual(bounding_rect.height(), 37.0, delta=5)
+            self.assertAlmostEqual(bounding_rect.width(), 19.59375, delta=15)
+            self.assertAlmostEqual(bounding_rect.height(), 37.0, delta=15)
 
         self.lp.run_until_complete(exec_test())