diff --git a/android/assets/text/application/application_cs.properties b/android/assets/text/application/application_cs.properties
index e7079a602c09d0c21e4677d14e6318a4ceba39c1..39c4b78361afe96da79425f399416b2dec14981d 100644
--- a/android/assets/text/application/application_cs.properties
+++ b/android/assets/text/application/application_cs.properties
@@ -26,6 +26,7 @@ mainmenu_statistics=Statistiky
 mainmenu_encyclopedia=Encyklopedie
 mainmenu_preferences=NastavenĂ­
 mainmenu_about=O aplikaci
+mainmenu_profile=Profil
 mainmenu_logout=Odhlásit
 mainmenu_screendebug=Debug Screen
 mainmenu_panorama=Panorama
@@ -168,5 +169,18 @@ user_consecutivelyallgames2stars_description=Za všechny hry po sobě na středn
 user_consecutivelyallgames3stars=Detektivní šelma
 user_consecutivelyallgames3stars_description=Za všechny hry po sobě na těžkou obtížnost a tři poháry
 
+#	<!-- Ranky -->
+user_rank_1=Podržtaška
+user_rank_2=Zelenáč
+user_rank_3=Prošlapchodník
+user_rank_4=ÄŚmuchal
+user_rank_5=Pátral
+user_rank_6=Pořádkumistr
+user_rank_7=DĹŻkazĹŻlapaÄŤ
+user_rank_8=OÄŤko
+user_rank_9=Komisárek
+user_rank_10=Rozumbrada
+user_rank_11=VrchnĂ­ rada
+
 sync_request_dialog_text=Zadej ÄŤĂ­slo prĹŻkazu:
 sync_request_button=Synchronizovat uĹľivatele
diff --git a/android/assets/text/application/application_de.properties b/android/assets/text/application/application_de.properties
index b97fc711f3210f5d5ed6396212eeb48aad649b78..0310d2a57af7b8bc7933a39e3bc61e98531eff3e 100644
--- a/android/assets/text/application/application_de.properties
+++ b/android/assets/text/application/application_de.properties
@@ -27,6 +27,7 @@ mainmenu_statistics=Statistiken
 mainmenu_encyclopedia=Enzyklopädie
 mainmenu_preferences=Einstellung
 mainmenu_about=Ăśber die App
+mainmenu_profile=Profil
 mainmenu_logout=Abmelden
 mainmenu_screendebug=Debug Screen
 mainmenu_panorama=Panorama
@@ -168,5 +169,18 @@ user_consecutivelyallgames2stars_description=FĂĽr alle Spiele nacheinander auf d
 user_consecutivelyallgames3stars=Als DetektivIn ein Raubtier
 user_consecutivelyallgames3stars_description=FĂĽr alle Spiele nacheinander auf der schwierigen Stufe mit drei Pokalen
 
+#	<!-- Ranky -->
+user_rank_1=Diener
+user_rank_2=GrĂĽnschnabel
+user_rank_3=Wachtmeister
+user_rank_4=SchnĂĽffler
+user_rank_5=Ermittler
+user_rank_6=Ordnungsmeister
+user_rank_7=BeweisaufspĂĽrer
+user_rank_8=Spitzel
+user_rank_9=Kleiner Kommissar
+user_rank_10=Besserwisser
+user_rank_11=Oberrat
+
 sync_request_dialog_text=Trage deine Ausweisnummer ein:
 sync_request_button=Account synchronisieren
diff --git a/android/assets/text/application/application_sk.properties b/android/assets/text/application/application_sk.properties
index 93aa14149ceacffb8fb8f355a4a13256f0592c2d..5cdebd3c3db0f8d0015952ad76ee46350e69248b 100644
--- a/android/assets/text/application/application_sk.properties
+++ b/android/assets/text/application/application_sk.properties
@@ -26,6 +26,7 @@ mainmenu_statistics=Ĺ tatistiky
 mainmenu_encyclopedia=Encyklopédia
 mainmenu_preferences=Nastavenie
 mainmenu_about=O aplikácií
+mainmenu_profile=Profil
 mainmenu_logout=Odhlásiť
 mainmenu_screendebug=Debug Screen
 mainmenu_panorama=Panorama
@@ -48,7 +49,7 @@ gamedifficulty_easy=Ľahká
 gamedifficulty_medium=Stredná
 gamedifficulty_hard=Ťažká
 
-victoryscreen_button_replay=Hráť znovu
+victoryscreen_button_replay=HraĹĄ znovu
 victoryscreen_button_changegame=InĂş hru
 victoryscreen_text_tutorial=Gratulujem! A teraz to skús sám…
 victoryscreen_new_trophy=Získavaš trofej!
@@ -67,11 +68,11 @@ game_robbery_preloader=Prečítaj a zapamätaj si pravidlo, podľa ktorého spoz
 game_kidnapping_title=Ăšnos
 game_kidnapping_description=Precvičovanie sluchovej pamäti
 game_kidnapping_preloader1=Vypočuj a\u00A0zapamätaj si zvuk, ktorý si počul na križovatke.
-game_kidnapping_preloader2=Potom si vypočuj zvuky okolitých ulic a\u00A0urči, ktorú ste prešli.
-game_kidnapping_preloader3=So slúchatkami budeš zvuky počuť lepšie.
+game_kidnapping_preloader2=Potom si vypočuj zvuky okolitých ulíc a\u00A0urči, ktorú ste prešli.
+game_kidnapping_preloader3=So slúchadlami budeš zvuky počuť lepšie.
 game_pursuit_title=Prenasledovanie
 game_pursuit_description=Precvičovanie priestorovej orientácie
-game_pursuit_preloader=Zostav mapu premiestňovania a\u00A0otáčania jednotlivých dielcov.
+game_pursuit_preloader=Zostav mapu priemiestňovaniam a\u00A0otáčaniam jednotlivých dielcov.
 game_night_watch_title=Hliadka
 game_night_watch_description=Precvičovanie zrakovej pamäti
 game_night_watch_preloader=Dávaj pozor, ktoré okná sa po zotmení rozsvietia a\u00A0o\u00A0ktorej.\nPo svitaní nastav na hodinách čas a\u00A0označ okná, ktoré boli rozsvietené.
@@ -113,7 +114,7 @@ kidnapping_1_finished=Nastražené ucho
 kidnapping_1_finished_description=Za dohranie prvej hry
 kidnapping_5_finished=RysĂ­ sluch
 kidnapping_5_finished_description=Za odohranie piatich hier
-kidnapping_10_finished=SousedÄŤino ucho
+kidnapping_10_finished=Susedkyno ucho
 kidnapping_10_finished_description=Za 10 dohraných her
 kidnapping_1_limit=Spiaci netopier
 kidnapping_1_limit_description=Za tri poháre na strednú úroveň
@@ -170,5 +171,18 @@ user_consecutivelyallgames2stars_description=Za všetky hry po sebe na strednú
 user_consecutivelyallgames3stars=Detektívna šelma
 user_consecutivelyallgames3stars_description=Za všetky hry po sebe na ťažkú obtiažnosť a tri poháre.
 
+#	<!-- Ranky -->
+user_rank_1=Podržtaška
+user_rank_2=Zelenáč
+user_rank_3=Prešľapchodník
+user_rank_4=Sliedil
+user_rank_5=Pátrač
+user_rank_6=Poriadkomajster
+user_rank_7=DĂ´kazolapaÄŤ
+user_rank_8=OÄŤko
+user_rank_9=Komisárik
+user_rank_10=Rozumbrada
+user_rank_11=Ĺ efmajster
+
 sync_request_dialog_text=Zadaj ÄŤĂ­slo preukazu:
-sync_request_button=Synchronizovať užívateľa
\ No newline at end of file
+sync_request_button=Synchronizovať užívateľa
diff --git a/android/assets/text/game/robbery/robbery_sk.properties b/android/assets/text/game/robbery/robbery_sk.properties
index 283f18ce62fc44d08e627ef6803034b607003217..4f6f6472927313e0c8e740b1d53bad094c9e5ac4 100644
--- a/android/assets/text/game/robbery/robbery_sk.properties
+++ b/android/assets/text/game/robbery/robbery_sk.properties
@@ -46,14 +46,14 @@ game_robbery_attribute_mhairattribute=é krátke vlasy
 game_robbery_attribute_fbeadsattribute=é korále
 game_robbery_attribute_fscarfattribute=ú dámskú šatku
 game_robbery_attribute_mscarfattribute=ý pánský šál
-game_robbery_attribute_mtieattribute=ou kravatu
+game_robbery_attribute_mtieattribute=Ăş kravatu
     
     
 game_robbery_rule_ca0cc0t=Ak príde človek, ktorý bude mať na sebe [BLACK]nejaké {0}é[] oblečenie a\u00A0po ňom človek, ktorý bude mať [BLACK]{1}{2}[], tak [BLACK]ďalší v poradí je zlodej[].
 game_robbery_rule_cc0cc0t=Ak príde človek, ktorý bude mať [BLACK]{0}{1}[] a [BLACK]po ňom[] človek, ktorý bude mať [BLACK]{2}{3}[], tak [BLACK]ďalší v poradí[] je zlodej.
 game_robbery_rule_cccc=Zlodej bude maĹĄ [BLACK]{0}{1}[] a [BLACK]{2}{3}[].
-game_robbery_rule_cacc=Zlodej bude maĹĄ na sebe nieÄŤo [BLACK]{0}Ă©ho[] a\u00A0bude maĹĄ [BLACK]{1}{2}[].
-game_robbery_rule_caca=Zlodej bude maĹĄ na sebe nieÄŤo [BLACK]{0}Ă©ho[] a\u00A0nieÄŤo [BLACK]{1}Ă©ho[].
+game_robbery_rule_cacc=Zlodej bude maĹĄ na sebe nieÄŤo [BLACK]{0}Ă©[] a\u00A0bude maĹĄ [BLACK]{1}{2}[].
+game_robbery_rule_caca=Zlodej bude maĹĄ na sebe nieÄŤo [BLACK]{0}Ă©[] a\u00A0nieÄŤo [BLACK]{1}Ă©[].
 game_robbery_rule_bx0bx=Zlodej bude maĹĄ [BLACK]rovnakĂ˝ {0}[] ako ÄŤlovek, ktorĂ˝ prĂ­de [BLACK]pred nĂ­m[].
 game_robbery_rule_bc1bc=Zlodej bude mať [BLACK]rovnak{0}[] ako človek, ktorý príde [BLACK]ob\u00A0jedného človeka pred ním[].
 game_robbery_rule_cc0notcc=Zlodej nebude maĹĄ [BLACK]{0}{1}[] a\u00A0ÄŤlovek, ktorĂ˝ prĂ­de [BLACK]pred nĂ­m[], bude maĹĄ na sebe [BLACK]{2}{3}[].
@@ -67,7 +67,7 @@ game_robbery_rule_cccccc=Zlodej bude maĹĄ [BLACK]{0}{1}[], [BLACK]{2}{3}[] a [BL
 
 game_robbery_rule_cc2cc=Zlodej bude maĹĄ [BLACK]{0}{1}[] a\u00A0prĂ­de [BLACK]ob dva lidi[] po ÄŤloveku, kterĂ˝ bude maĹĄ [BLACK]{2}{3}[].
 game_robbery_rule_cc0notcc0t=Ak príde človek, který bude mať [BLACK]{0}{1}[] a [BLACK]po ňom[] človek, který [BLACK]nebude[] mať [BLACK]{2}{3}[], tak [BLACK]ďalší v poradí[] je zlodej.
-game_robbery_rule_cc0notca0t=Ak príde človek, ktorý bude mať [BLACK]{0}{1}[] a [BLACK]po ňom[] človek, ktorý [BLACK]nebude[] mať nič [BLACK]{2}ého[], tak [BLACK]ďalší v poradí[] je zlodej.
+game_robbery_rule_cc0notca0t=Ak príde človek, ktorý bude mať [BLACK]{0}{1}[] a [BLACK]po ňom[] človek, ktorý [BLACK]nebude[] mať nič [BLACK]{2}é[], tak [BLACK]ďalší v poradí[] je zlodej.
 game_robbery_rule_cc0cc0cc=Ak príde človek, ktorý bude mať [BLACK]{0}{1}[] a [BLACK]po ňom[] človek, který bude mať [BLACK]{2}{3}[], tak [BLACK]ďalší v poradí[] je zlodej, ak má na sebe [BLACK]{4}{5}[].
 game_robbery_rule_ccccnotcc=Zlodej bude maĹĄ [BLACK]{0}{1}[] a [BLACK]{2}{3}[] a [BLACK]nebude[] maĹĄ [BLACK]{4}{5}[].
 game_robbery_rule_bx1bx=Zlodej bude mať [BLACK]rovnaký {0}[] ako človek, ktorý príde [BLACK]ob jedného človeka pred ním[].
diff --git a/android/assets/text/screen/halloffame/halloffame_cs.properties b/android/assets/text/screen/halloffame/halloffame_cs.properties
index 83ceb3318431f4523d04e0506653161feb33bf72..ab1c7ba53c1666f4c326028ae2d7004af929137f 100644
--- a/android/assets/text/screen/halloffame/halloffame_cs.properties
+++ b/android/assets/text/screen/halloffame/halloffame_cs.properties
@@ -32,3 +32,9 @@ mouse_20_1=Tak to tu ještě nebylo!
 mouse_20_2=Všechna čest, tohle jsem ještě neviděla.\r\nA to tu bydlím už docela dlouho.
 mouse_20_3=Gratuluju, gratuluju, gratuluju!\r\nÚctyhodný výkon!
 mouse_20_4=O tom si budou vyprávět\r\nještě moje vnoučata.
+
+mouse_rankup=Gratuluju k povýšení. Jen tak dál!
+
+#	<!-- Skrin s hodnostmi -->
+badge_cabinet_list=Seznam hodnostĂ­
+badge_cabinet_locked=???
diff --git a/android/assets/text/screen/halloffame/halloffame_de.properties b/android/assets/text/screen/halloffame/halloffame_de.properties
index c886fb7c3df854987d9d4b3a363770ce92dff115..f300b5b7f418d665b377250885405e7be7781a7f 100644
--- a/android/assets/text/screen/halloffame/halloffame_de.properties
+++ b/android/assets/text/screen/halloffame/halloffame_de.properties
@@ -32,3 +32,9 @@ mouse_20_1=Na das hat es hier noch nicht gegeben!
 mouse_20_2=Alle Ehre, das habe ich noch nicht gesehen.\r\nUnd ich wohne hier schon ganz schön lange.
 mouse_20_3=Gratulation, Gratulation, Gratulation!\r\nRespektable Leistung!
 mouse_20_4=Davon werden sich noch meine Enkel erzählen.
+
+mouse_rankup=Herzlichen Glückwunsch zur Beförderung! Mach weiter so!
+
+#	<!-- Skrin s hodnostmi -->
+badge_cabinet_list=Dienstgradliste
+badge_cabinet_locked=???
diff --git a/android/assets/text/screen/halloffame/halloffame_sk.properties b/android/assets/text/screen/halloffame/halloffame_sk.properties
index 52c43451cd5601a035aad679bdcc1229c7029636..756bb6fae40e5c882bbd81682e1d6d9578fc28aa 100644
--- a/android/assets/text/screen/halloffame/halloffame_sk.properties
+++ b/android/assets/text/screen/halloffame/halloffame_sk.properties
@@ -32,3 +32,9 @@ mouse_20_1=Tak to tu ešte nebolo!
 mouse_20_2=Všetka česť, toto som ešte nevidela.\r\nA to tu bývam už celkom dlho.
 mouse_20_3=Gratulujem, gratulujem, gratulujem!\r\nÚctyhodný výkon!
 mouse_20_4=O tom si budú rozprávať\r\nešte moje vnúčatá.
+
+mouse_rankup=Gratulujem k povýšenie. Len tak ďalej!
+
+#	<!-- Skrin s hodnostmi -->
+badge_cabinet_list=Zoznam hodnostĂ­
+badge_cabinet_locked=???
diff --git a/android/src/main/java/cz/nic/tablexia/android/AndroidLauncher.java b/android/src/main/java/cz/nic/tablexia/android/AndroidLauncher.java
index 55f52a14c15a9f97fdf7efbb13bb2f65fb400cbc..138f5b6c7b317f93de3a796894506503fe77637d 100644
--- a/android/src/main/java/cz/nic/tablexia/android/AndroidLauncher.java
+++ b/android/src/main/java/cz/nic/tablexia/android/AndroidLauncher.java
@@ -25,7 +25,8 @@ public class AndroidLauncher extends AndroidApplication {
 
     public static final Tablexia.SQLConnectionType SQL_CONNECTION_TYPE = new Tablexia.SQLConnectionType("org.sqldroid.SQLDroidDriver", "jdbc:sqldroid:");
 
-	private static final int MULTI_SAMPLING_2X	= 2;
+    private static final int        MULTI_SAMPLING_2X	    = 2;
+    private static final boolean    HAS_SOFT_BACK_BUTTON    = false;
 
     private Tablexia tablexia;
 
@@ -41,6 +42,7 @@ public class AndroidLauncher extends AndroidApplication {
 					getResources().getConfiguration().locale,
 					SQL_CONNECTION_TYPE,
 					new AndroidConnectionManager(getContext()),
+                    HAS_SOFT_BACK_BUTTON,
 					savedInstanceState == null), config);
 		}
 
diff --git a/build.gradle b/build.gradle
index f356c059691e32b154f2e71c833fb72f63bb7f90..e7ed8bb50e3fcef2a735687bca0345f07c313b15 100644
--- a/build.gradle
+++ b/build.gradle
@@ -3,7 +3,7 @@ import com.badlogic.gdx.tools.texturepacker.TexturePacker
 
 buildscript {
     repositories {
-        //mavenCentral()
+//        mavenCentral()
         maven { url 'https://jitpack.io' }
         jcenter{ url "http://jcenter.bintray.com/" }
     }
diff --git a/core/assets/common/_global/application/badge/badge1.png b/core/assets/common/_global/application/badge/badge1.png
new file mode 100644
index 0000000000000000000000000000000000000000..7437ba5332eab3d4d3c104843c76e1b8d01adf63
Binary files /dev/null and b/core/assets/common/_global/application/badge/badge1.png differ
diff --git a/core/assets/common/_global/application/badge/badge10.png b/core/assets/common/_global/application/badge/badge10.png
new file mode 100644
index 0000000000000000000000000000000000000000..91a3057cd665801d38b5a6cc2a403fa3bb8bfc15
Binary files /dev/null and b/core/assets/common/_global/application/badge/badge10.png differ
diff --git a/core/assets/common/_global/application/badge/badge10_icon.png b/core/assets/common/_global/application/badge/badge10_icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..4218a169b16e4f54d9abdc68e7115a57cd22db64
Binary files /dev/null and b/core/assets/common/_global/application/badge/badge10_icon.png differ
diff --git a/core/assets/common/_global/application/badge/badge11.png b/core/assets/common/_global/application/badge/badge11.png
new file mode 100644
index 0000000000000000000000000000000000000000..4f9094da0286d36b05b35aa13751953e2667ec2f
Binary files /dev/null and b/core/assets/common/_global/application/badge/badge11.png differ
diff --git a/core/assets/common/_global/application/badge/badge11_icon.png b/core/assets/common/_global/application/badge/badge11_icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..38496b16a178b52249bd7780b709507e663b3451
Binary files /dev/null and b/core/assets/common/_global/application/badge/badge11_icon.png differ
diff --git a/core/assets/common/_global/application/badge/badge1_icon.png b/core/assets/common/_global/application/badge/badge1_icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..5221d58204389405af077c70ebfddb9714af8a89
Binary files /dev/null and b/core/assets/common/_global/application/badge/badge1_icon.png differ
diff --git a/core/assets/common/_global/application/badge/badge2.png b/core/assets/common/_global/application/badge/badge2.png
new file mode 100644
index 0000000000000000000000000000000000000000..97f50c9858ecab7f647471cb08d417d5b7ae9e06
Binary files /dev/null and b/core/assets/common/_global/application/badge/badge2.png differ
diff --git a/core/assets/common/_global/application/badge/badge2_icon.png b/core/assets/common/_global/application/badge/badge2_icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..cd454763d69b9d236b6647d21e1c152049ffaba1
Binary files /dev/null and b/core/assets/common/_global/application/badge/badge2_icon.png differ
diff --git a/core/assets/common/_global/application/badge/badge3.png b/core/assets/common/_global/application/badge/badge3.png
new file mode 100644
index 0000000000000000000000000000000000000000..c97bea8fbdf68a25ec2261c35250dc4615fcade0
Binary files /dev/null and b/core/assets/common/_global/application/badge/badge3.png differ
diff --git a/core/assets/common/_global/application/badge/badge3_icon.png b/core/assets/common/_global/application/badge/badge3_icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..1e8ed9940e0725950958e6c2a411dc3cc5a2e175
Binary files /dev/null and b/core/assets/common/_global/application/badge/badge3_icon.png differ
diff --git a/core/assets/common/_global/application/badge/badge4.png b/core/assets/common/_global/application/badge/badge4.png
new file mode 100644
index 0000000000000000000000000000000000000000..61d4a942b5df208a20d48cacc512c2d6cd94db1d
Binary files /dev/null and b/core/assets/common/_global/application/badge/badge4.png differ
diff --git a/core/assets/common/_global/application/badge/badge4_icon.png b/core/assets/common/_global/application/badge/badge4_icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..30063ebbffc2968176a7a83caa29244149bdc2c3
Binary files /dev/null and b/core/assets/common/_global/application/badge/badge4_icon.png differ
diff --git a/core/assets/common/_global/application/badge/badge5.png b/core/assets/common/_global/application/badge/badge5.png
new file mode 100644
index 0000000000000000000000000000000000000000..994694d40c8871564fe2715db76fcded66108ddd
Binary files /dev/null and b/core/assets/common/_global/application/badge/badge5.png differ
diff --git a/core/assets/common/_global/application/badge/badge5_icon.png b/core/assets/common/_global/application/badge/badge5_icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..d8604d37b7314cb27c43118cd952f1bc724d2e99
Binary files /dev/null and b/core/assets/common/_global/application/badge/badge5_icon.png differ
diff --git a/core/assets/common/_global/application/badge/badge6.png b/core/assets/common/_global/application/badge/badge6.png
new file mode 100644
index 0000000000000000000000000000000000000000..212a80ab6b6c9093aab9fd6e69fde32ba1a2ad09
Binary files /dev/null and b/core/assets/common/_global/application/badge/badge6.png differ
diff --git a/core/assets/common/_global/application/badge/badge6_icon.png b/core/assets/common/_global/application/badge/badge6_icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..9ad343a58782efe465f2386a6d40f60b008cdda4
Binary files /dev/null and b/core/assets/common/_global/application/badge/badge6_icon.png differ
diff --git a/core/assets/common/_global/application/badge/badge7.png b/core/assets/common/_global/application/badge/badge7.png
new file mode 100644
index 0000000000000000000000000000000000000000..51344972c0a8c686b9f08ada9427a672440d972a
Binary files /dev/null and b/core/assets/common/_global/application/badge/badge7.png differ
diff --git a/core/assets/common/_global/application/badge/badge7_icon.png b/core/assets/common/_global/application/badge/badge7_icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..2e510f9118fb783aaaa08de8225cfaae4a865f08
Binary files /dev/null and b/core/assets/common/_global/application/badge/badge7_icon.png differ
diff --git a/core/assets/common/_global/application/badge/badge8.png b/core/assets/common/_global/application/badge/badge8.png
new file mode 100644
index 0000000000000000000000000000000000000000..782c5c0701688bfe4ea91c71040573fce5a79d71
Binary files /dev/null and b/core/assets/common/_global/application/badge/badge8.png differ
diff --git a/core/assets/common/_global/application/badge/badge8_icon.png b/core/assets/common/_global/application/badge/badge8_icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..d35ef356132c871b16e5c54f6a15236e781f20bc
Binary files /dev/null and b/core/assets/common/_global/application/badge/badge8_icon.png differ
diff --git a/core/assets/common/_global/application/badge/badge9.png b/core/assets/common/_global/application/badge/badge9.png
new file mode 100644
index 0000000000000000000000000000000000000000..e459e19b9b9ff452140d016e0a9235072e77806b
Binary files /dev/null and b/core/assets/common/_global/application/badge/badge9.png differ
diff --git a/core/assets/common/_global/application/badge/badge9_icon.png b/core/assets/common/_global/application/badge/badge9_icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..2782c97d8cc5e6a2c34fbeb9e19776755146368b
Binary files /dev/null and b/core/assets/common/_global/application/badge/badge9_icon.png differ
diff --git a/core/assets/common/screen/form/gfx/badge.png b/core/assets/common/_global/application/badge/badge_none.png
similarity index 100%
rename from core/assets/common/screen/form/gfx/badge.png
rename to core/assets/common/_global/application/badge/badge_none.png
diff --git a/core/assets/common/_global/application/badge/badge_none_icon.png b/core/assets/common/_global/application/badge/badge_none_icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..79e19203dc9ed9103d51df9764aca6f0f4ce3f37
Binary files /dev/null and b/core/assets/common/_global/application/badge/badge_none_icon.png differ
diff --git a/core/assets/common/_global/application/badge/rankup_sound.mp3 b/core/assets/common/_global/application/badge/rankup_sound.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..7abe63d1876e8cf7bf265d2614326d47f749b1cf
Binary files /dev/null and b/core/assets/common/_global/application/badge/rankup_sound.mp3 differ
diff --git a/core/assets/common/_global/application/dialog/dialog_badgeboard.9.png b/core/assets/common/_global/application/dialog/dialog_badgeboard.9.png
new file mode 100644
index 0000000000000000000000000000000000000000..e808fe10a08d9e1fc552f04ef6227248e5c40e2d
Binary files /dev/null and b/core/assets/common/_global/application/dialog/dialog_badgeboard.9.png differ
diff --git a/core/assets/common/_global/application/mainmenu/icon_profile_pressed.png b/core/assets/common/_global/application/mainmenu/icon_profile_pressed.png
new file mode 100644
index 0000000000000000000000000000000000000000..5ef49075fbce7bb89abe37ffe4abdae55d72233e
Binary files /dev/null and b/core/assets/common/_global/application/mainmenu/icon_profile_pressed.png differ
diff --git a/core/assets/common/_global/application/mainmenu/icon_profile_unpressed.png b/core/assets/common/_global/application/mainmenu/icon_profile_unpressed.png
new file mode 100644
index 0000000000000000000000000000000000000000..29d33bd792d0b2edccf171ed32427601bccd7213
Binary files /dev/null and b/core/assets/common/_global/application/mainmenu/icon_profile_unpressed.png differ
diff --git a/core/assets/common/_global/application/ui/back_button.png b/core/assets/common/_global/application/ui/back_button.png
new file mode 100644
index 0000000000000000000000000000000000000000..8e5833244e0915ef9aebe22d0376c7520f2f3928
Binary files /dev/null and b/core/assets/common/_global/application/ui/back_button.png differ
diff --git a/core/assets/common/_global/application/ui/back_button_pressed.png b/core/assets/common/_global/application/ui/back_button_pressed.png
new file mode 100644
index 0000000000000000000000000000000000000000..c16fde8c47412339e7766e0dade17ecf07a7e7a0
Binary files /dev/null and b/core/assets/common/_global/application/ui/back_button_pressed.png differ
diff --git a/core/assets/common/_global/application/ui/debug_cup_pressed.png b/core/assets/common/_global/application/ui/debug_cup_pressed.png
new file mode 100644
index 0000000000000000000000000000000000000000..1661e95e07c3fedae03a639c4150d62a8e936083
Binary files /dev/null and b/core/assets/common/_global/application/ui/debug_cup_pressed.png differ
diff --git a/core/assets/common/_global/application/ui/debug_cup_released.png b/core/assets/common/_global/application/ui/debug_cup_released.png
new file mode 100644
index 0000000000000000000000000000000000000000..84a06fa2d92a630ca0ed62813f479d319cf7f55c
Binary files /dev/null and b/core/assets/common/_global/application/ui/debug_cup_released.png differ
diff --git a/core/assets/common/_global/application/ui/progressbar.png b/core/assets/common/_global/application/ui/progressbar.png
new file mode 100644
index 0000000000000000000000000000000000000000..43c73642a2b648dbe4337151b1de1927475a53a9
Binary files /dev/null and b/core/assets/common/_global/application/ui/progressbar.png differ
diff --git a/core/assets/common/_global/application/ui/progressbar_fill.png b/core/assets/common/_global/application/ui/progressbar_fill.png
new file mode 100644
index 0000000000000000000000000000000000000000..18e62d78b670e36c61f98b1a493b4898dc221a5f
Binary files /dev/null and b/core/assets/common/_global/application/ui/progressbar_fill.png differ
diff --git a/core/assets/common/_global/application/ui/rankup_bg.png b/core/assets/common/_global/application/ui/rankup_bg.png
new file mode 100644
index 0000000000000000000000000000000000000000..409863c49c36be0a38ffaac396582df676d22758
Binary files /dev/null and b/core/assets/common/_global/application/ui/rankup_bg.png differ
diff --git a/core/assets/common/_global/application/ui/rankup_star.png b/core/assets/common/_global/application/ui/rankup_star.png
new file mode 100644
index 0000000000000000000000000000000000000000..59a0837f27c64f13357853b1dd931b591fc1314e
Binary files /dev/null and b/core/assets/common/_global/application/ui/rankup_star.png differ
diff --git a/core/assets/common/screen/form/gfx/progress_arrow.png b/core/assets/common/screen/form/gfx/progress_arrow.png
new file mode 100644
index 0000000000000000000000000000000000000000..8ec7091e94cfea38b3f7a503e7a5778bbd328267
Binary files /dev/null and b/core/assets/common/screen/form/gfx/progress_arrow.png differ
diff --git a/core/assets/common/screen/form/gfx/progressbar_fill.png b/core/assets/common/screen/form/gfx/progressbar_fill.png
new file mode 100644
index 0000000000000000000000000000000000000000..1a4d529f94e528863f2615f5c71e11b663aa0e4a
Binary files /dev/null and b/core/assets/common/screen/form/gfx/progressbar_fill.png differ
diff --git a/core/assets/common/screen/gamemenu/gfx/bankovniloupez_progressbar.png b/core/assets/common/screen/gamemenu/gfx/bankovniloupez_progressbar.png
new file mode 100644
index 0000000000000000000000000000000000000000..a8662bf8a5aad83205e01479d4cab599797bdc53
Binary files /dev/null and b/core/assets/common/screen/gamemenu/gfx/bankovniloupez_progressbar.png differ
diff --git a/core/assets/common/screen/gamemenu/gfx/nocnisledovani_progressbar.png b/core/assets/common/screen/gamemenu/gfx/nocnisledovani_progressbar.png
new file mode 100644
index 0000000000000000000000000000000000000000..f558c00452be94c48f6c6b8838b2bdcfbfbe684c
Binary files /dev/null and b/core/assets/common/screen/gamemenu/gfx/nocnisledovani_progressbar.png differ
diff --git a/core/assets/common/screen/gamemenu/gfx/potme_progressbar.png b/core/assets/common/screen/gamemenu/gfx/potme_progressbar.png
new file mode 100644
index 0000000000000000000000000000000000000000..7270ad68245be0caba785e061aa3b9da4ef16559
Binary files /dev/null and b/core/assets/common/screen/gamemenu/gfx/potme_progressbar.png differ
diff --git a/core/assets/common/screen/gamemenu/gfx/progress_bg.9.png b/core/assets/common/screen/gamemenu/gfx/progress_bg.9.png
new file mode 100644
index 0000000000000000000000000000000000000000..728922b7e7f3151a282422bd0b404beff8ad87ee
Binary files /dev/null and b/core/assets/common/screen/gamemenu/gfx/progress_bg.9.png differ
diff --git a/core/assets/common/screen/gamemenu/gfx/progressbar_fill.png b/core/assets/common/screen/gamemenu/gfx/progressbar_fill.png
new file mode 100644
index 0000000000000000000000000000000000000000..33d32ed4ab656bc2694d3cca35f52cce95048f9f
Binary files /dev/null and b/core/assets/common/screen/gamemenu/gfx/progressbar_fill.png differ
diff --git a/core/assets/common/screen/gamemenu/gfx/pronasledovani_progressbar.png b/core/assets/common/screen/gamemenu/gfx/pronasledovani_progressbar.png
new file mode 100644
index 0000000000000000000000000000000000000000..1c45c14682c9a6ca386c691819c354ab224cfd82
Binary files /dev/null and b/core/assets/common/screen/gamemenu/gfx/pronasledovani_progressbar.png differ
diff --git a/core/assets/common/screen/gamemenu/gfx/strelnice_progressbar.png b/core/assets/common/screen/gamemenu/gfx/strelnice_progressbar.png
new file mode 100644
index 0000000000000000000000000000000000000000..8aaacc7ab7982a7e17073c728865b906eb43dfda
Binary files /dev/null and b/core/assets/common/screen/gamemenu/gfx/strelnice_progressbar.png differ
diff --git a/core/assets/common/screen/gamemenu/gfx/unos_progressbar.png b/core/assets/common/screen/gamemenu/gfx/unos_progressbar.png
new file mode 100644
index 0000000000000000000000000000000000000000..968f1d542f3e704cc7b0c94f0b9c2d66d23b801a
Binary files /dev/null and b/core/assets/common/screen/gamemenu/gfx/unos_progressbar.png differ
diff --git a/core/assets/common/screen/halloffame/screen_halloffame_badgeboard.png b/core/assets/common/screen/halloffame/screen_halloffame_badgeboard.png
new file mode 100644
index 0000000000000000000000000000000000000000..07644715c2b524235020b5ac86ba989f650910f5
Binary files /dev/null and b/core/assets/common/screen/halloffame/screen_halloffame_badgeboard.png differ
diff --git a/core/assets/common/screen/halloffame/screen_halloffame_mouse_cheese_pressed.png b/core/assets/common/screen/halloffame/screen_halloffame_mouse_cheese_pressed.png
new file mode 100644
index 0000000000000000000000000000000000000000..bd4d84ec9f7dcaad25839a901cd15f69a3f68a3b
Binary files /dev/null and b/core/assets/common/screen/halloffame/screen_halloffame_mouse_cheese_pressed.png differ
diff --git a/core/assets/common/screen/profile/background.png b/core/assets/common/screen/profile/background.png
deleted file mode 100644
index 739d3949bf7550fa62fad0619a5eec42dd55e930..0000000000000000000000000000000000000000
Binary files a/core/assets/common/screen/profile/background.png and /dev/null differ
diff --git a/core/assets/common/screen/profile/ink.png b/core/assets/common/screen/profile/ink.png
deleted file mode 100644
index 13ce5d7757043e0e53be948d94a2123ecccc1dec..0000000000000000000000000000000000000000
Binary files a/core/assets/common/screen/profile/ink.png and /dev/null differ
diff --git a/core/assets/common/screen/profile/inkpad.png b/core/assets/common/screen/profile/inkpad.png
deleted file mode 100644
index eed2a9a6bcb632ada3c70a7a6cead0a4b0f33963..0000000000000000000000000000000000000000
Binary files a/core/assets/common/screen/profile/inkpad.png and /dev/null differ
diff --git a/core/assets/common/screen/profile/mugshotframe.png b/core/assets/common/screen/profile/mugshotframe.png
deleted file mode 100644
index 525b4cac6a429886d170ab197bdd2f18515f4c22..0000000000000000000000000000000000000000
Binary files a/core/assets/common/screen/profile/mugshotframe.png and /dev/null differ
diff --git a/core/assets/common/screen/profile/pencil.png b/core/assets/common/screen/profile/pencil.png
deleted file mode 100644
index 5460327ad85d9900e87cedb4e658964106d5e1ee..0000000000000000000000000000000000000000
Binary files a/core/assets/common/screen/profile/pencil.png and /dev/null differ
diff --git a/core/assets/common/screen/profile/pencil_dropped.png b/core/assets/common/screen/profile/pencil_dropped.png
deleted file mode 100644
index cab6f998fe0687c7f04f48cf6a42a42356ac7eee..0000000000000000000000000000000000000000
Binary files a/core/assets/common/screen/profile/pencil_dropped.png and /dev/null differ
diff --git a/core/assets/common/screen/profile/pencil_dropped_selected.png b/core/assets/common/screen/profile/pencil_dropped_selected.png
deleted file mode 100644
index 88b505ad15afada3ad5f464bf1b2f993c952d25c..0000000000000000000000000000000000000000
Binary files a/core/assets/common/screen/profile/pencil_dropped_selected.png and /dev/null differ
diff --git a/core/assets/common/screen/profile/pencil_grabbed.png b/core/assets/common/screen/profile/pencil_grabbed.png
deleted file mode 100644
index 67167e89250334ac98f4fc4baa679a56ae84d220..0000000000000000000000000000000000000000
Binary files a/core/assets/common/screen/profile/pencil_grabbed.png and /dev/null differ
diff --git a/core/assets/common/screen/profile/sex_female.png b/core/assets/common/screen/profile/sex_female.png
deleted file mode 100644
index 40ed86d45c1ccdeb53068afffc147b10d4fefb14..0000000000000000000000000000000000000000
Binary files a/core/assets/common/screen/profile/sex_female.png and /dev/null differ
diff --git a/core/assets/common/screen/profile/sex_male.png b/core/assets/common/screen/profile/sex_male.png
deleted file mode 100644
index 2640eb2ac943b163fef8e8f70fe1a2f221d5f9a7..0000000000000000000000000000000000000000
Binary files a/core/assets/common/screen/profile/sex_male.png and /dev/null differ
diff --git a/core/assets/common/screen/profile/signature_background.9.png b/core/assets/common/screen/profile/signature_background.9.png
deleted file mode 100644
index 34a8684782808b80af8fd556e3b6dd0b8eb73a19..0000000000000000000000000000000000000000
Binary files a/core/assets/common/screen/profile/signature_background.9.png and /dev/null differ
diff --git a/core/assets/common/screen/profile/stamp.png b/core/assets/common/screen/profile/stamp.png
deleted file mode 100644
index 8e80db058bac023e45e67c2a7f06663bb1c0509c..0000000000000000000000000000000000000000
Binary files a/core/assets/common/screen/profile/stamp.png and /dev/null differ
diff --git a/core/assets/common/screen/profile/stamp_left_dropped.png b/core/assets/common/screen/profile/stamp_left_dropped.png
deleted file mode 100644
index 4a9f24702ed6332c89da92348496173dec561bc0..0000000000000000000000000000000000000000
Binary files a/core/assets/common/screen/profile/stamp_left_dropped.png and /dev/null differ
diff --git a/core/assets/common/screen/profile/stamp_left_grabbed.png b/core/assets/common/screen/profile/stamp_left_grabbed.png
deleted file mode 100644
index 6dc7f8c326d1341c5c9e811c3d1a68fa70616c95..0000000000000000000000000000000000000000
Binary files a/core/assets/common/screen/profile/stamp_left_grabbed.png and /dev/null differ
diff --git a/core/assets/common/screen/profile/stamp_left_selected.png b/core/assets/common/screen/profile/stamp_left_selected.png
deleted file mode 100644
index 7e285f93da545c703e1d12011c0970726d07af6a..0000000000000000000000000000000000000000
Binary files a/core/assets/common/screen/profile/stamp_left_selected.png and /dev/null differ
diff --git a/core/assets/common/screen/profile/stamp_middle_dropped.png b/core/assets/common/screen/profile/stamp_middle_dropped.png
deleted file mode 100644
index 39a6962e70210e5228dfe9d518467695af0f3a4c..0000000000000000000000000000000000000000
Binary files a/core/assets/common/screen/profile/stamp_middle_dropped.png and /dev/null differ
diff --git a/core/assets/common/screen/profile/stamp_middle_grabbed.png b/core/assets/common/screen/profile/stamp_middle_grabbed.png
deleted file mode 100644
index 765902e61bd12e4af761d0094ce80c49596f0533..0000000000000000000000000000000000000000
Binary files a/core/assets/common/screen/profile/stamp_middle_grabbed.png and /dev/null differ
diff --git a/core/assets/common/screen/profile/stamp_right_dropped.png b/core/assets/common/screen/profile/stamp_right_dropped.png
deleted file mode 100644
index 8f28651c6f40775a56b7af8e7f5cd2aa8b883896..0000000000000000000000000000000000000000
Binary files a/core/assets/common/screen/profile/stamp_right_dropped.png and /dev/null differ
diff --git a/core/assets/common/screen/profile/stamp_right_grabbed.png b/core/assets/common/screen/profile/stamp_right_grabbed.png
deleted file mode 100644
index 1c90a45d977d7e251bc528af91e635da0e180706..0000000000000000000000000000000000000000
Binary files a/core/assets/common/screen/profile/stamp_right_grabbed.png and /dev/null differ
diff --git a/core/assets/common/screen/profile/stampplaceholder.png b/core/assets/common/screen/profile/stampplaceholder.png
deleted file mode 100644
index 1412e8205cf2bb95a4d4d75a8045848a74f22925..0000000000000000000000000000000000000000
Binary files a/core/assets/common/screen/profile/stampplaceholder.png and /dev/null differ
diff --git a/core/assets/common/screen/profile/table.png b/core/assets/common/screen/profile/table.png
deleted file mode 100644
index 8d78875b04550764241d5b03625a08e0e08cd186..0000000000000000000000000000000000000000
Binary files a/core/assets/common/screen/profile/table.png and /dev/null differ
diff --git a/core/assets/cs/_global/application/ui/promotion_label.png b/core/assets/cs/_global/application/ui/promotion_label.png
new file mode 100644
index 0000000000000000000000000000000000000000..59cd2b473eec419d93495552223d0ee02507ca24
Binary files /dev/null and b/core/assets/cs/_global/application/ui/promotion_label.png differ
diff --git a/core/assets/de/_global/application/ui/promotion_label.png b/core/assets/de/_global/application/ui/promotion_label.png
new file mode 100644
index 0000000000000000000000000000000000000000..2adc2e4529debc62ac54dc6e89fc3a24c9295bbd
Binary files /dev/null and b/core/assets/de/_global/application/ui/promotion_label.png differ
diff --git a/core/assets/sk/_global/application/ui/promotion_label.png b/core/assets/sk/_global/application/ui/promotion_label.png
new file mode 100644
index 0000000000000000000000000000000000000000..27f65c970f704363d9e74679937a62f13f893632
Binary files /dev/null and b/core/assets/sk/_global/application/ui/promotion_label.png differ
diff --git a/core/src/cz/nic/tablexia/Tablexia.java b/core/src/cz/nic/tablexia/Tablexia.java
index 6f759ea9b5e9115f9250bdb983cb4a10b5177201..8b809e02e0f74b8e32716c2bfc85b28fd223db94 100644
--- a/core/src/cz/nic/tablexia/Tablexia.java
+++ b/core/src/cz/nic/tablexia/Tablexia.java
@@ -3,6 +3,7 @@ package cz.nic.tablexia;
 import com.badlogic.gdx.Gdx;
 import com.badlogic.gdx.graphics.GL30;
 import com.badlogic.gdx.scenes.scene2d.InputEvent;
+import com.badlogic.gdx.scenes.scene2d.actions.Actions;
 import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
 
 import net.engio.mbassy.bus.error.IPublicationErrorHandler;
@@ -29,6 +30,7 @@ import cz.nic.tablexia.screen.AbstractTablexiaScreen;
 import cz.nic.tablexia.screen.loader.IConnectionManager;
 import cz.nic.tablexia.util.Log;
 import cz.nic.tablexia.util.Utility;
+import cz.nic.tablexia.util.ui.button.TablexiaButton;
 import cz.nic.tablexia.util.ui.dialog.TablexiaComponentDialog;
 import cz.nic.tablexia.util.ui.dialog.TablexiaComponentDialogFactory;
 import cz.nic.tablexia.util.ui.dialog.components.AdaptiveSizeDialogComponent;
@@ -53,12 +55,22 @@ public class Tablexia extends TablexiaApplication {
     public static final int     ERROR_DIALOG_HEIGHT                     = 300;
     public static final float   ERROR_DIALOG_DIMMER                     = 0.7f;
 
+    public static final int     BACK_BUTTON_SIZE                        = 50;
+    public static final float   BACK_BUTTON_LEFT_OFFSET_RATIO           = 0.045f;
+    public static final float   BACK_BUTTON_ADAPTIVE_SIZE_RATIO         = 1.7f;
+    public static final float   BACK_BUTTON_BOTTOM_OFFSET               = 0.04f;
+    public static final boolean BACK_BUTTON_ADAPTIVE_SIZE_POSITION_FIX  = true;
+    public static final float   SHOW_BACK_BUTTON_DURATION               = 1f;
+    public static final float   HIDE_BACK_BUTTON_DURATION               = 1f;
+
     private static final boolean LOADER_ERROR_DIALOG_HIDE_ANIMATION     = false;
 
     private static IConnectionManager connectionManager;
 
     private final SQLConnectionType     sqlConnectionType;
     private MenuController              menuController;
+    private TablexiaButton              backButton;
+    private boolean                     backButtonVisibility;
     private ZipAssetLoader              zipAssetLoader;
     private ScreenshotListener          screenshotListener;
     private boolean                     reset;
@@ -85,12 +97,12 @@ public class Tablexia extends TablexiaApplication {
         }
     }
 
-    public Tablexia(String buildType, Locale systemLocale, SQLConnectionType sqlConnectionType, IConnectionManager connManager, boolean reset) {
+    public Tablexia(String buildType, Locale systemLocale, SQLConnectionType sqlConnectionType, IConnectionManager connManager, boolean hasSoftBackButton, boolean reset) {
         this.reset = reset;
 		connectionManager = validateConnectionManager(connManager);
         this.sqlConnectionType = sqlConnectionType;
 
-        TablexiaSettings.init(buildType, systemLocale);
+        TablexiaSettings.init(buildType, systemLocale, hasSoftBackButton);
 
 		// register error handler for exceptions in event bus handler methods
 		ApplicationBus.getInstance().addErrorHandler(new IPublicationErrorHandler() {
@@ -136,6 +148,62 @@ public class Tablexia extends TablexiaApplication {
         }
     }
 
+    private void prepareBackButton() {
+        backButton = new TablexiaButton(
+                "",
+                false,
+                ApplicationAtlasManager.getInstance().getTextureRegion(ApplicationAtlasManager.BACK_BUTTON),
+                ApplicationAtlasManager.getInstance().getTextureRegion(ApplicationAtlasManager.BACK_BUTTON_PRESSED),
+                null,
+                null)
+        .setButtonBounds(
+                TablexiaSettings.getViewportLeftX(getStage()) + TablexiaSettings.getViewportWidth(getStage()) * BACK_BUTTON_LEFT_OFFSET_RATIO,
+                TablexiaSettings.getViewportBottomY(getStage()) + TablexiaSettings.getViewportHeight(getStage()) * BACK_BUTTON_BOTTOM_OFFSET,
+                BACK_BUTTON_SIZE,
+                BACK_BUTTON_SIZE)
+        .adaptiveSizeRatio(BACK_BUTTON_ADAPTIVE_SIZE_RATIO)
+        .adaptiveSizePositionFix(BACK_BUTTON_ADAPTIVE_SIZE_POSITION_FIX);
+
+        backButton.setVisible(false);
+        backButton.setInputListener(new ClickListener() {
+            @Override
+            public void clicked(InputEvent event, float x, float y) {
+                ApplicationBus.getInstance().post(new BackButtonPressed()).asynchronously();
+            }
+        });
+
+        setBackButtonVisibility(backButtonVisibility);
+        setBackButton(backButton);
+    }
+
+    private void setBackButtonVisibility(boolean hasBackButton) {
+        backButtonVisibility = hasBackButton;
+        if (backButton != null) {
+            if (hasBackButton) {
+                if (!backButton.isVisible()) {
+                    backButton.addAction(Actions.alpha(0f));
+                    backButton.setVisible(true);
+                    backButton.addAction(Actions.sequence(Actions.fadeIn(SHOW_BACK_BUTTON_DURATION)));
+                }
+            } else{
+                if (backButton.isVisible()) {
+                    backButton.addAction(Actions.sequence(Actions.fadeOut(HIDE_BACK_BUTTON_DURATION), Actions.run(new Runnable() {
+                        @Override
+                        public void run() {
+                            backButton.setVisible(false);
+                        }
+                    })));
+                }
+            }
+        }
+    }
+
+    @Override
+    protected void processNewScreen(AbstractTablexiaScreen<?> newScreen) {
+        super.processNewScreen(newScreen);
+        setBackButtonVisibility(newScreen.hasSoftBackButton());
+    }
+
 	@Override
     public void resize(int width, int height) {
         super.resize(width, height);
@@ -275,6 +343,7 @@ public class Tablexia extends TablexiaApplication {
 			if (!ApplicationExternalSoundManager.getInstance().update()) return;
 			if (!ApplicationAtlasManager.getInstance().update()) return;
 
+            prepareBackButton();
             prepareMenu();
             loadingComplete();
         }
diff --git a/core/src/cz/nic/tablexia/TablexiaApplication.java b/core/src/cz/nic/tablexia/TablexiaApplication.java
index 241e08e6c883526340020df23128c9ab79ea8d2a..ece993f36959a97c5f6966184024628fd3314cda 100644
--- a/core/src/cz/nic/tablexia/TablexiaApplication.java
+++ b/core/src/cz/nic/tablexia/TablexiaApplication.java
@@ -55,6 +55,7 @@ import cz.nic.tablexia.util.Log;
 import cz.nic.tablexia.util.ui.AnimatedImage;
 import cz.nic.tablexia.util.ui.ComponentScaleUtil;
 import cz.nic.tablexia.util.ui.XFillViewport;
+import cz.nic.tablexia.util.ui.button.TablexiaButton;
 import cz.nic.tablexia.util.ui.dialog.TablexiaComponentDialog;
 import cz.nic.tablexia.util.ui.dialog.TablexiaComponentDialogFactory;
 import cz.nic.tablexia.util.ui.dialog.components.AdaptiveSizeDialogComponent;
@@ -110,6 +111,7 @@ public abstract class TablexiaApplication implements ApplicationListener {
     private InputMultiplexer inputMultiplexer;
     private DebugInfo debugInfo;
     private Actor screenDimmer;
+    private Group backButtonLayer;
     private Group menuLayer;
     private Stage stage;
     private boolean screenSizeUnderThreshold = false;
@@ -178,6 +180,7 @@ public abstract class TablexiaApplication implements ApplicationListener {
         inputMultiplexer.addProcessor(backButtonInputProcessor);
         Gdx.input.setCatchBackKey(true);
         Gdx.input.setInputProcessor(inputMultiplexer);
+        prepareBackButtonLayer();
         prepareMenuLayer();
         prepareScreenDimmer();
         prepareDebugInfo();
@@ -293,6 +296,18 @@ public abstract class TablexiaApplication implements ApplicationListener {
     }
 
 
+//////////////////////////// BACK BUTTON LAYER
+
+    private void prepareBackButtonLayer() {
+        backButtonLayer = new Group();
+        stage.addActor(backButtonLayer);
+    }
+
+    protected void setBackButton(TablexiaButton backButton) {
+        backButtonLayer.addActor(backButton);
+    }
+
+
 //////////////////////////// MENU LAYER
 
     private void prepareMenuLayer() {
@@ -663,7 +678,7 @@ public abstract class TablexiaApplication implements ApplicationListener {
     }
 
     @SuppressWarnings("unchecked")
-    private void processNewScreen(AbstractTablexiaScreen<?> newScreen) {
+    protected void processNewScreen(AbstractTablexiaScreen<?> newScreen) {
         if (newScreen != null) {
             try {
                 inputMultiplexer.addProcessor(newScreen.getInputProcessor());
@@ -959,7 +974,7 @@ public abstract class TablexiaApplication implements ApplicationListener {
 
 		private int processWithPriority = 0;
 
-		private BackButtonPressed() {
+		protected BackButtonPressed() {
 
         }
 
diff --git a/core/src/cz/nic/tablexia/TablexiaSettings.java b/core/src/cz/nic/tablexia/TablexiaSettings.java
index 07308095fd67055f364d21ee9eaeb011c408c0ff..1a0a5ed5ddb549c79f03a0179b286ce5420e414a 100644
--- a/core/src/cz/nic/tablexia/TablexiaSettings.java
+++ b/core/src/cz/nic/tablexia/TablexiaSettings.java
@@ -27,6 +27,7 @@ import cz.nic.tablexia.util.Log;
 import cz.nic.tablexia.util.ui.dialog.TablexiaComponentDialogFactory;
 
 public class TablexiaSettings {
+
     private static final int    DEFAULT_SCREEN_WIDTH     = 1000;
     private static final double MAXIMUM_RATIO            = 9.0 / 16.0;
     private static final int    MIN_SCREEN_HEIGHT        = (int) (DEFAULT_SCREEN_WIDTH * MAXIMUM_RATIO);
@@ -40,23 +41,26 @@ public class TablexiaSettings {
 
     public static final int                                        PRELOADER_SPEECH_PLAY_COUNT = 2;
 
-    private static final String PREFERENCES_KEY         = "cz.nic.tablexia.";
-    private static final String LAST_LOCALE_KEY         = "last_locale";
-    public static final  String LOCALE_KEY              = "locale";
-    private static final String SELECTED_USER           = "selected_user";
-
-	//Interval <start month; end month>
-	private static final int WINTER_MODE_START_MONTH = 10;
-	private static final int WINTER_MODE_END_MONTH	 = 2;
-	private static boolean winterMode = false;
+    private static final String  PREFERENCES_KEY         = "cz.nic.tablexia.";
+    private static final String  LAST_LOCALE_KEY         = "last_locale";
+    public  static final String  LOCALE_KEY              = "locale";
+    private static final String  SELECTED_USER           = "selected_user";
 
+    public  static final int     EXPERIENCE_POINTS_TUTORIAL = 0;
+    public  static final int     EXPERIENCE_POINTS_EASY     = 1;
+    public  static final int     EXPERIENCE_POINTS_MEDIUM   = 2;
+    public  static final int     EXPERIENCE_POINTS_HARD     = 3;
 
-    public static final String  DEV_VERSION_TYPE        = "-SNAPSHOT-";
+	//Interval <start month; end month>
+	private static final int     WINTER_MODE_START_MONTH = 10;
+	private static final int     WINTER_MODE_END_MONTH	 = 2;
+	private static       boolean winterMode = false;
 
 
     private static final    String      APP_NAME        = TablexiaBuildConfig.APP_NAME;
     private final           String      VERSION_NAME    = TablexiaBuildConfig.VERSION_NAME;
     private final           BuildType   BUILD_TYPE;
+    private final           boolean     HAS_SOFT_BACK_BUTTON;
 
     private Preferences      preferences;
     private LocaleDefinition systemLocale;
@@ -67,10 +71,10 @@ public class TablexiaSettings {
 
     public enum BuildType {
 
-        //                  boxes   aInfo   sInfo   dMenu   btName  bReport
-        RELEASE ("release", false,  false,  false,  false,  false,  true,   Log.TablexiaLogLevel.ERROR),
-        DEBUG   ("debug",   false,  true,   true,   true,   true,   true,   Log.TablexiaLogLevel.DEBUG),
-        DEVEL   ("devel",   true,   true,   true,   true,   true,   false,  Log.TablexiaLogLevel.DEBUG);
+        //                  boxes   aInfo   sInfo   dMenu   btName  bReport  debugBtn
+        RELEASE ("release", false,  false,  false,  false,  false,  true,    false,   Log.TablexiaLogLevel.ERROR),
+        DEBUG   ("debug",   false,  true,   true,   true,   true,   true,    true,    Log.TablexiaLogLevel.DEBUG),
+        DEVEL   ("devel",   true,   true,   true,   true,   true,   false,   true,    Log.TablexiaLogLevel.DEBUG);
 
         private final static BuildType FALLBACK_VARIANT = BuildType.DEVEL;
 
@@ -81,9 +85,10 @@ public class TablexiaSettings {
         private       boolean              debugMenu;
         private       boolean              showBuildTypeInName;
         private       boolean              bugReport;
+        private       boolean              showDebugButtons;
         private final Log.TablexiaLogLevel logLevel;
 
-        BuildType(String key, boolean boundingBoxes, boolean applicationInfo, boolean screenInfo, boolean debugMenu, boolean showBuildTypeInName, boolean bugReport, Log.TablexiaLogLevel logLevel) {
+        BuildType(String key, boolean boundingBoxes, boolean applicationInfo, boolean screenInfo, boolean debugMenu, boolean showBuildTypeInName, boolean bugReport, boolean showDebugButtons, Log.TablexiaLogLevel logLevel) {
             this.key = key;
             this.boundingBoxes = boundingBoxes;
             this.applicationInfo = applicationInfo;
@@ -91,6 +96,7 @@ public class TablexiaSettings {
             this.debugMenu = debugMenu;
             this.showBuildTypeInName = showBuildTypeInName;
             this.bugReport = bugReport;
+            this.showDebugButtons = showDebugButtons;
             this.logLevel = logLevel;
         }
 
@@ -122,6 +128,10 @@ public class TablexiaSettings {
             return bugReport;
         }
 
+        public boolean isShowDebugButtons() {
+            return showDebugButtons;
+        }
+
         public Log.TablexiaLogLevel getLogLevel() {
             return logLevel;
         }
@@ -141,8 +151,9 @@ public class TablexiaSettings {
 
     private static TablexiaSettings instance;
 
-    private TablexiaSettings(BuildType buildType, Locale systemLocale) {
+    private TablexiaSettings(BuildType buildType, Locale systemLocale, boolean hasSoftBackButton) {
         BUILD_TYPE = buildType;
+        HAS_SOFT_BACK_BUTTON = hasSoftBackButton;
         this.systemLocale = LocaleDefinition.getLocaleDefinitionForLocale(systemLocale);
     }
 
@@ -155,18 +166,18 @@ public class TablexiaSettings {
         return instance;
     }
 
-    static void init(String buildTypeKey, Locale systemLocale) {
-        TablexiaSettings.init(BuildType.getBuildTypeForKey(buildTypeKey), systemLocale);
+    static void init(String buildTypeKey, Locale systemLocale, boolean hasSoftBackButton) {
+        TablexiaSettings.init(BuildType.getBuildTypeForKey(buildTypeKey), systemLocale, hasSoftBackButton);
     }
 
-    static void init(BuildType buildType, Locale systemLocale) {
+    static void init(BuildType buildType, Locale systemLocale, boolean hasSoftBackButton) {
         if (instance != null) {
             String exceptionMessage = "Tablexia settings already initialized!";
             Log.err(TablexiaSettings.class, exceptionMessage);
             throw new IllegalStateException(exceptionMessage);
         }
 
-        instance = new TablexiaSettings(buildType, systemLocale);
+        instance = new TablexiaSettings(buildType, systemLocale, hasSoftBackButton);
     }
 
     void dispose() {
@@ -201,7 +212,11 @@ public class TablexiaSettings {
         return VERSION_NAME;
     }
 
-	public boolean isWinterMode() { return winterMode; }
+    public boolean hasSoftBackButton() {
+        return HAS_SOFT_BACK_BUTTON;
+    }
+
+    public boolean isWinterMode() { return winterMode; }
 
     public boolean isShowBoundingBoxes() {
         return getBuildType().isBoundingBoxes();
@@ -236,6 +251,7 @@ public class TablexiaSettings {
         return DEFAULT_FONT_COLOR;
     }
 
+
 //////////////////////////// USER SETTINGS
 
     public static class SelectedUserEvent implements ApplicationBus.ApplicationEvent {
diff --git a/core/src/cz/nic/tablexia/game/AbstractTablexiaGame.java b/core/src/cz/nic/tablexia/game/AbstractTablexiaGame.java
index ebe8954075e7889436dd4d84d6f5f1693952e8b5..7eded19ddb9625781babfd1b88f79564f81f320e 100644
--- a/core/src/cz/nic/tablexia/game/AbstractTablexiaGame.java
+++ b/core/src/cz/nic/tablexia/game/AbstractTablexiaGame.java
@@ -4,12 +4,21 @@ import com.badlogic.gdx.Gdx;
 import com.badlogic.gdx.audio.Music;
 import com.badlogic.gdx.graphics.Color;
 import com.badlogic.gdx.graphics.g2d.TextureRegion;
+import com.badlogic.gdx.math.Bezier;
+import com.badlogic.gdx.math.Interpolation;
+import com.badlogic.gdx.math.Vector2;
 import com.badlogic.gdx.scenes.scene2d.Actor;
 import com.badlogic.gdx.scenes.scene2d.InputEvent;
+import com.badlogic.gdx.scenes.scene2d.Stage;
+import com.badlogic.gdx.scenes.scene2d.Touchable;
+import com.badlogic.gdx.scenes.scene2d.actions.Actions;
+import com.badlogic.gdx.scenes.scene2d.actions.ParallelAction;
+import com.badlogic.gdx.scenes.scene2d.actions.SequenceAction;
 import com.badlogic.gdx.scenes.scene2d.ui.Cell;
 import com.badlogic.gdx.scenes.scene2d.ui.Image;
 import com.badlogic.gdx.scenes.scene2d.ui.Table;
 import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
+import com.badlogic.gdx.utils.Align;
 import com.badlogic.gdx.utils.Scaling;
 
 import net.engio.mbassy.listener.Handler;
@@ -31,7 +40,11 @@ import cz.nic.tablexia.bus.event.MenuControlEvent;
 import cz.nic.tablexia.bus.event.StartIncrementalSynchronizationEvent;
 import cz.nic.tablexia.game.common.TablexiaRandom;
 import cz.nic.tablexia.game.difficulty.GameDifficulty;
+import cz.nic.tablexia.game.games.kidnapping.actions.WhileAction;
+import cz.nic.tablexia.game.ranksystem.RankAnimation;
+import cz.nic.tablexia.game.ranksystem.UserRankManager;
 import cz.nic.tablexia.game.trophy.ITrophyDefinition;
+import cz.nic.tablexia.loader.application.ApplicationAtlasManager;
 import cz.nic.tablexia.loader.application.ApplicationFontManager;
 import cz.nic.tablexia.loader.application.ApplicationInternalSoundManager;
 import cz.nic.tablexia.loader.application.ApplicationTextManager;
@@ -43,12 +56,17 @@ import cz.nic.tablexia.screen.AbstractTablexiaScreen;
 import cz.nic.tablexia.screen.gamemenu.GameMenuScreen;
 import cz.nic.tablexia.screen.halloffame.HallOfFameScreen;
 import cz.nic.tablexia.screen.halloffame.trophy.TrophyHelper;
+import cz.nic.tablexia.screen.profile.ProfileScreen;
 import cz.nic.tablexia.shared.model.Game;
 import cz.nic.tablexia.util.Log;
 import cz.nic.tablexia.util.MusicUtil;
+import cz.nic.tablexia.util.actions.MoveAlongAction;
+import cz.nic.tablexia.util.ui.ClickListenerWithSound;
 import cz.nic.tablexia.util.ui.ComponentScaleUtil;
 import cz.nic.tablexia.util.ui.TablexiaLabel;
+import cz.nic.tablexia.util.ui.TablexiaProgressBar;
 import cz.nic.tablexia.util.ui.button.StandardTablexiaButton;
+import cz.nic.tablexia.util.ui.button.TablexiaButton;
 import cz.nic.tablexia.util.ui.dialog.TablexiaComponentDialog;
 import cz.nic.tablexia.util.ui.dialog.TablexiaComponentDialogFactory;
 import cz.nic.tablexia.util.ui.dialog.components.AdaptiveSizeDialogComponent;
@@ -70,7 +88,7 @@ import static com.badlogic.gdx.scenes.scene2d.actions.Actions.sequence;
 
 public abstract class AbstractTablexiaGame<T> extends AbstractTablexiaScreen<T> {
 
-    private enum GamePhase {
+    protected enum GamePhase {
 
         PREPARED(false),
         STARTED(true),
@@ -134,10 +152,12 @@ public abstract class AbstractTablexiaGame<T> extends AbstractTablexiaScreen<T>
     public static final String VICTORY_DIALOG_SUMMARY_ICON_TIME     = "time";
     private static final String VICTORY_DIALOG_TUTORIAL_TEXT        = "victoryscreen_text_tutorial";
 
-    private static final int VICTORY_DIALOG_SHOW_SOUND_DELAY = 2;
-    public static final float VICTORY_SPEECH_FADE_OUT_TIME = 0.5f;
-    private static final float VICTORY_DIALOG_RATINGSTARS_DELAY = 0.5f;
-    private static final Color VICTORY_DIALOG_SUMMARY_FONT_COLOR = Color.GRAY;
+    private static final int   VICTORY_DIALOG_SHOW_SOUND_DELAY      = 2;
+    public  static final float VICTORY_SPEECH_FADE_OUT_TIME         = 0.5f;
+    private static final float VICTORY_DIALOG_RATINGSTARS_DELAY     = 0.5f;
+    private static final Color VICTORY_DIALOG_SUMMARY_FONT_COLOR    = Color.GRAY;
+
+    private static final float RANK_UP_ANIMATION_DELAY              = 3 / 2f;
 
     public static final String RANDOM_SEED_SCREEN_INFO_LABEL = "Random Seed";
     public static final String GAME_DIFFICULTY_SCREEN_INFO_LABEL = "Game Difficulty";
@@ -147,6 +167,40 @@ public abstract class AbstractTablexiaGame<T> extends AbstractTablexiaScreen<T>
 
     public static final String GAME_STATE_GAME_ID = "game_id";
 
+    //Lower equals faster (how many seconds does it take from 0% to 100%
+    private static final float   PROGRESS_BAR_SPEED  = 1f;
+
+    //Experience Stars
+    private static final Vector2[]      EXPERIENCE_STAR_PATH = new Vector2[] {
+            //Path (without final destination), which every star will follow (in stars coords system)
+            new Vector2(0, 0), //Starts at star
+            new Vector2(50, 80),
+            new Vector2(-10, -90),
+    };
+
+    //Position of a star on a cup
+    private static final float          EXPERIENCE_STAR_X_TO_CUP                = 0.5f;
+    private static final float          EXPERIENCE_STAR_Y_TO_CUP                = 0.68f;
+
+    //Star path variables
+    private static final float          EXPERIENCE_STAR_PATH_DURATION           = 2f;
+    private static final float          EXPERIENCE_STAR_PATH_SCALE              = 1.25f;
+    private static final float          EXPERIENCE_STAR_PATH_ROTATION           = 2f;
+
+    //Star variables
+    private static final float          EXPERIENCE_STAR_WIDTH_TO_CUP            = 3f / 10;
+    private static final float          EXPERIENCE_STAR_DELAY                   = 1f / 2;
+    private static final float          EXPERIENCE_STAR_FADE_IN                 = 1f / 2;
+    private static final Interpolation  EXPERIENCE_STAR_FADE_IN_INTERPOLATION   = Interpolation.pow3;
+
+    private static final float          EXPERIENCE_STAR_FADE_OUT_DELAY          = 1f / 4;
+    private static final float          EXPERIENCE_STAR_FADE_OUT                = 3f / 4;
+    private static final float          EXPERIENCE_STAR_FADE_OUT_SCALE          = 1.25f;
+    private static final float          EXPERIENCE_STAR_FADE_OUT_SCALE_TIME     = 1f;
+    private static final Interpolation  EXPERIENCE_STAR_FADE_OUT_INTERPOLATION  = Interpolation.pow3Out;
+
+    private static final float          DEBUG_END_GAME_BUTTON_SIZE      = 48f;
+
     private Game game;
     private TablexiaRandom random;
     private GamePhase gamePhase;
@@ -161,6 +215,8 @@ public abstract class AbstractTablexiaGame<T> extends AbstractTablexiaScreen<T>
     private ArrayList<TablexiaComponentDialog> receivedTrophyDialogs;
     private TablexiaComponentDialog victoryDialog;
 
+    private static TablexiaButton debugEndGameButton;
+
     public AbstractTablexiaGame() {
         inGameLoading = false;
         gamePhase = GamePhase.PREPARED;
@@ -216,6 +272,10 @@ public abstract class AbstractTablexiaGame<T> extends AbstractTablexiaScreen<T>
         return false;
     }
 
+    protected GamePhase getGamePhase() {
+        return gamePhase;
+    }
+
     @Handler
     public void handleMenuPauseEvent(AbstractMenu.MenuPauseEvent menuPauseEvent) {
         if (canBePaused()) {
@@ -246,6 +306,10 @@ public abstract class AbstractTablexiaGame<T> extends AbstractTablexiaScreen<T>
     @Override
     protected final void screenLoaded(final Map<String, String> screenState) {
         try {
+            if(debugEndGameButton == null && TablexiaSettings.getInstance().getBuildType().isShowDebugButtons()) {
+                createDebugEndGameButton();
+            }
+
             performGameLoaded(screenState);
         } catch (Throwable t) {
             Log.err(getClass(), "Cannot resume screen state!", t);
@@ -261,6 +325,23 @@ public abstract class AbstractTablexiaGame<T> extends AbstractTablexiaScreen<T>
         }
     }
 
+    private void createDebugEndGameButton() {
+        debugEndGameButton = new TablexiaButton(
+                null,
+                false,
+                ApplicationAtlasManager.getInstance().getTextureRegion(ApplicationAtlasManager.DEBUG_CUP_BUTTON_RELEASED),
+                ApplicationAtlasManager.getInstance().getTextureRegion(ApplicationAtlasManager.DEBUG_CUP_BUTTON_PRESSED),
+                null,
+                null
+        );
+
+        TablexiaComponentDialogFactory.getDialogStage().addActor(debugEndGameButton);
+
+        debugEndGameButton.setSize(DEBUG_END_GAME_BUTTON_SIZE, DEBUG_END_GAME_BUTTON_SIZE);
+        debugEndGameButton.setX(TablexiaComponentDialogFactory.getDialogStage().getWidth() - debugEndGameButton.getWidth());
+        debugEndGameButton.setVisible(false);
+    }
+
     @Override
     protected final void screenVisible(Map<String, String> screenState) {
         performGameVisible();
@@ -381,6 +462,9 @@ public abstract class AbstractTablexiaGame<T> extends AbstractTablexiaScreen<T>
     public void setScreenViewCount(long userId, String screenName, long time) {
     }
 
+    public boolean isGameFinished() {
+        return getGamePhase() == GamePhase.FINISHED;
+    }
 
 //////////////////////////// ABSTRACT TABLEXIA GAME LIFECYCLE
 
@@ -388,6 +472,22 @@ public abstract class AbstractTablexiaGame<T> extends AbstractTablexiaScreen<T>
         Log.info(getClass(), "[ ------- Game Loaded ------- ]");
         gameLoaded(gameState);
         prepareGameTrophies();
+
+        if(debugEndGameButton != null)
+            showDebugEndButton();
+    }
+
+    private void showDebugEndButton() {
+        debugEndGameButton.removeListener();
+        debugEndGameButton.setInputListener(new ClickListener() {
+            @Override
+            public void clicked(InputEvent event, float x, float y) {
+                forceGameEnd(GameResult.THREE_STAR);
+            }
+        });
+        debugEndGameButton.setEnabled();
+        debugEndGameButton.useOnce(true);
+        debugEndGameButton.setVisible(true);
     }
 
     public final void performGameVisible() {
@@ -403,6 +503,9 @@ public abstract class AbstractTablexiaGame<T> extends AbstractTablexiaScreen<T>
     private final void performGameEnd() {
         Log.info(getClass(), "[ ------- Game End ------- ]");
         gameEnd();
+
+        if(debugEndGameButton != null)
+            debugEndGameButton.setVisible(false);
     }
 
     private final void performGameDisposed() {
@@ -475,7 +578,7 @@ public abstract class AbstractTablexiaGame<T> extends AbstractTablexiaScreen<T>
 
 //////////////////////////// ABSTRACT TABLEXIA GAME
 
-    private final float             DIALOG_HEIGHT               = 400;
+    private final float             DIALOG_HEIGHT               = 460;
     private final float             DIALOG_WIDTH                = 500;
 
     private final float             TROPHY_DIALOG_WIDTH         = getSceneWidth() * 0.18f;
@@ -572,7 +675,6 @@ public abstract class AbstractTablexiaGame<T> extends AbstractTablexiaScreen<T>
         final Image[] cupsImages = new Image[gameResult.getStarCount()];
 
         TablexiaDialogComponentAdapter cups = new TablexiaDialogComponentAdapter() {
-
             private static final int    CUPS_TABLE_SPACING  = 4;
             private static final float  CUP_WIDTH_RATIO     = 1f / 8;
             private static final float  CUP_HEIGHT_RATIO    = 1f / 6;
@@ -717,6 +819,43 @@ public abstract class AbstractTablexiaGame<T> extends AbstractTablexiaScreen<T>
 
         playAgainButtonClicked = false;
 
+        adapters.add(new ResizableSpaceContentDialogComponent());
+
+        final UserRankManager.RankProgress rankProgress = UserRankManager.getInstance().getGameRankProgress(getSelectedUser(), GameDefinition.getGameDefinitionForGameNumber(game.getGameNumber()));
+        final TablexiaProgressBar progressBar = new TablexiaProgressBar(
+                ApplicationAtlasManager.getInstance().getTextureRegion(ApplicationAtlasManager.PROGRESS_BAR),
+                ApplicationAtlasManager.getInstance().getTextureRegion(ApplicationAtlasManager.PROGRESS_BAR_FILL)
+        );
+
+        progressBar.addListener(new ClickListenerWithSound() {
+            @Override
+            public void onClick(InputEvent event, float x, float y) {
+                hideDialogsAndChangeScreen(ProfileScreen.class, TablexiaApplication.ScreenTransaction.FADE);
+            }
+        });
+
+        adapters.add(new TablexiaDialogComponentAdapter() {
+            private static final float  PROGRESS_BAR_WIDTH  = 0.8f;
+
+            Cell<TablexiaProgressBar> progressCell;
+
+            @Override
+            public void sizeChanged() {
+                progressCell.expand();
+                progressCell.getActor().setWidth(getDialog().getInnerWidth() * PROGRESS_BAR_WIDTH);
+            }
+
+            @Override
+            public void prepareContent(Cell content) {
+                progressBar.setSmooth(false);
+                progressBar.setPercent(rankProgress.getPercentDone());
+
+                content.setActor(progressBar);
+
+                progressCell = content;
+            }
+        });
+
         //Buttons
         adapters.add(new ResizableSpaceContentDialogComponent());
         adapters.add(new TwoButtonContentDialogComponent(
@@ -792,6 +931,9 @@ public abstract class AbstractTablexiaGame<T> extends AbstractTablexiaScreen<T>
 			@Override
 			public void run() {
 				animateAndPlayVictoryDialogSounds(gameResult, cupsImages);
+                animateProgressBarAndExperienceStars(cupsImages, GameDifficulty.getByGame(game), rankProgress, progressBar);
+
+                UserRankManager.getInstance().forceRefreshUserRank(getSelectedUser());
 			}
 		});
     }
@@ -814,7 +956,7 @@ public abstract class AbstractTablexiaGame<T> extends AbstractTablexiaScreen<T>
             })));
         }
 
-        // rating stars
+        // rating cups
         for (int i = 0; i < cups.length; i++) {
             final Image cup = cups[i];
             final int index = i + 1;
@@ -826,6 +968,7 @@ public abstract class AbstractTablexiaGame<T> extends AbstractTablexiaScreen<T>
                 }
             })));
         }
+
     }
 
     private void handleTrophies() {
@@ -855,7 +998,6 @@ public abstract class AbstractTablexiaGame<T> extends AbstractTablexiaScreen<T>
 
     private void positionReceivedTrophyDialogs(float dialogX, float dialogY, float dialogWidth, float dialogHeight) {
         float dialogPad = isUnderThreshold ? TROPHY_DIALOG_HORIZONTAL_MOBILE_PAD : TROPHY_DIALOG_HORIZONTAL_DEFAULT_PAD;
-        System.out.println(dialogX + " " + dialogY + " " + dialogWidth + " " + dialogHeight);
 
         int trophyCount = receivedTrophyDialogs.size();
 
@@ -959,12 +1101,213 @@ public abstract class AbstractTablexiaGame<T> extends AbstractTablexiaScreen<T>
         showGameResultDialog();
     }
 
+    public interface ExperienceStarListener {
+        void onStarPathCompleted(ExperienceStar experienceStar);
+    }
+
+    public static class ExperienceStar extends Image {
+        private Vector2 relativeEndPosition;
+        private ExperienceStarListener listener;
+
+        public ExperienceStar(float starWidth, Vector2 relativeEndPosition) {
+            super(ApplicationAtlasManager.getInstance().getTextureRegion(ApplicationAtlasManager.RANK_UP_STAR));
+
+            this.setSize(starWidth, starWidth * (getWidth() / getHeight()));
+            this.setOrigin(Align.center);
+            this.relativeEndPosition = relativeEndPosition;
+
+            this.addAction(Actions.alpha(0));
+        }
+
+        private Vector2[] prepareActualPath() {
+            int arraySize = EXPERIENCE_STAR_PATH.length;
+            if(this.relativeEndPosition != null) arraySize++;
+
+            Vector2[] actualPath = new Vector2[arraySize];
+
+            for(int i = 0; i < EXPERIENCE_STAR_PATH.length; i++) {
+                actualPath[i] = EXPERIENCE_STAR_PATH[i];
+            }
+
+            if(this.relativeEndPosition != null)
+                actualPath[arraySize - 1] = this.relativeEndPosition;
+
+            return actualPath;
+        }
+
+        public void startAnimation(float delay, float fadeIn, float duration, Interpolation interpolation) {
+            Vector2[] path = prepareActualPath();
+
+            Bezier<Vector2> bezier = new Bezier<Vector2>(path);
+            MoveAlongAction moveAlongAction = new MoveAlongAction(bezier, duration);
+            moveAlongAction.setInterpolation(interpolation);
+
+            ParallelAction moveRotateScaleAction = new ParallelAction(
+                new WhileAction(
+                    moveAlongAction,
+                    Actions.rotateBy(360, EXPERIENCE_STAR_PATH_ROTATION)
+                ),
+                new SequenceAction(
+                    Actions.scaleBy( EXPERIENCE_STAR_PATH_SCALE,  EXPERIENCE_STAR_PATH_SCALE, duration / 2f),
+                    Actions.scaleBy(-EXPERIENCE_STAR_PATH_SCALE, -EXPERIENCE_STAR_PATH_SCALE, duration / 2f)
+                )
+            );
+
+            final ExperienceStar thisExperienceStar = this;
+            addAction(
+                new SequenceAction(
+                    Actions.delay(delay),
+                    Actions.fadeIn(fadeIn),
+                    moveRotateScaleAction,
+                    Actions.run(new Runnable() {
+                        @Override
+                        public void run() {
+                            if(listener != null)
+                                listener.onStarPathCompleted(thisExperienceStar);
+                        }
+                    })
+                )
+            );
+        }
+
+        public void setStarListener(ExperienceStarListener starListener) {
+            this.listener = starListener;
+        }
+    }
+    private void animateProgressBarAndExperienceStars(Image[] cupsImages, final GameDifficulty gameDifficulty, final UserRankManager.RankProgress rankProgress, final TablexiaProgressBar progressBar) {
+        Vector2 progressBarStagePosition = progressBar.localToStageCoordinates(new Vector2(0, progressBar.getHeight() / 2));
+        progressBar.setSmooth(true);
+        progressBar.setSpeed(PROGRESS_BAR_SPEED);
+
+        int starCountPerCup = gameDifficulty.getExperiencePointsMultiplier();
+
+        //Listener for all stars...
+        final ExperienceStarListener starListener = new ExperienceStarListener() {
+            @Override
+            public void onStarPathCompleted(ExperienceStar experienceStar) {
+                experienceStar.addAction(
+                    new SequenceAction(
+                        new ParallelAction(
+                                new SequenceAction(
+                                        Actions.delay(EXPERIENCE_STAR_FADE_OUT_DELAY),
+                                        Actions.fadeOut(EXPERIENCE_STAR_FADE_OUT, EXPERIENCE_STAR_FADE_OUT_INTERPOLATION)
+                                ),
+                                Actions.scaleBy(EXPERIENCE_STAR_FADE_OUT_SCALE, EXPERIENCE_STAR_FADE_OUT_SCALE, EXPERIENCE_STAR_FADE_OUT_SCALE_TIME, EXPERIENCE_STAR_FADE_OUT_INTERPOLATION)
+                        ),
+                        Actions.removeActor()
+                    )
+                );
+
+                //TODO - different sound...
+//                ApplicationInternalSoundManager.getInstance().getSound(ApplicationInternalSoundManager.ALERT).play();
+
+                //Updates progress bar
+                rankProgress.setCurrXP(rankProgress.getCurrXP() + 1);
+                progressBar.setPercent(rankProgress.getPercentDone());
+            }
+        };
+
+        //RankProgress to compute stars final destination on the progress bar
+        GameDefinition gd = GameDefinition.getGameDefinitionForClass(getClass());
+        if(gd == null) throw new RuntimeException("Couldn't find game definition for class: " + getClass());
+
+        UserRankManager.RankProgress gameRankProgress = new UserRankManager.RankProgress(rankProgress.getMinXP(), rankProgress.getCurrXP(), rankProgress.getNextXP());
+
+        //Iterate through all the achieved cups
+        for(int cupsAchievedIndex = 0; cupsAchievedIndex < cupsImages.length; cupsAchievedIndex++) {
+            float cupWidth = cupsImages[cupsAchievedIndex].getWidth();
+            float starWidth = cupWidth * EXPERIENCE_STAR_WIDTH_TO_CUP;
+
+            //Star position for particular cup
+            Vector2 starPosition = cupsImages[cupsAchievedIndex].localToStageCoordinates(
+                    new Vector2(
+                            EXPERIENCE_STAR_X_TO_CUP * cupsImages[cupsAchievedIndex].getWidth(),
+                            EXPERIENCE_STAR_Y_TO_CUP * cupsImages[cupsAchievedIndex].getHeight()
+                    )
+            );
+
+            for(int starIndex = 0; starIndex < starCountPerCup; starIndex++) {
+                float gamePercent = gameRankProgress.getPercentDone();
+                if(gamePercent >= 1) return;  //ProgressBar is already at (100%)
+
+                //Final destination point for stars in stars coordinate system
+                Vector2 lastPoint = new Vector2(
+                        progressBarStagePosition.x + progressBar.getFillOffsetX() + (progressBar.getWidth() - 2*progressBar.getFillOffsetX()) * gamePercent - starPosition.x,
+                        progressBarStagePosition.y - starPosition.y
+                );
+
+                //Actual star
+                ExperienceStar experienceStar = new ExperienceStar(starWidth, lastPoint);
+
+                experienceStar.setTouchable(Touchable.disabled);
+                experienceStar.setPosition(starPosition.x - experienceStar.getWidth() / 2f, starPosition.y - experienceStar.getHeight() / 2f);
+                experienceStar.setStarListener(starListener);
+
+                //Starting animation
+                float cupDelay = cupsAchievedIndex * starCountPerCup * EXPERIENCE_STAR_DELAY;
+                experienceStar.startAnimation(cupDelay + (EXPERIENCE_STAR_DELAY * starIndex), EXPERIENCE_STAR_FADE_IN, EXPERIENCE_STAR_PATH_DURATION, EXPERIENCE_STAR_FADE_IN_INTERPOLATION);
+
+                gameRankProgress.setCurrXP(gameRankProgress.getCurrXP() + 1);
+                TablexiaComponentDialogFactory.getDialogStage().addActor(experienceStar);
+            }
+        }
+    }
+
+    public void onRankUp(UserRankManager.UserRank previousRank, UserRankManager.UserRank newRank) {
+        final Stage dialogStage = TablexiaComponentDialogFactory.getDialogStage();
+        final RankAnimation rankAnimation = RankAnimation.createRankAnimation(
+                dialogStage,
+                previousRank,
+                newRank
+        );
+
+        //Clicked the Badge...
+        rankAnimation.setNewBadgeEventListener(new ClickListenerWithSound() {
+            @Override
+            public void onClick(InputEvent event, float x, float y) {
+                hideDialogsAndChangeScreen(HallOfFameScreen.class, TablexiaApplication.ScreenTransaction.FADE);
+            }
+        });
+
+        //Clicked the rank up animation
+        rankAnimation.addListener(new ClickListener() {
+            @Override
+            public void clicked(InputEvent event, float x, float y) {
+                rankAnimation.hide();
+            }
+        });
+
+        getStage().addAction( new SequenceAction(
+            Actions.delay(RANK_UP_ANIMATION_DELAY),
+            Actions.run(new Runnable() {
+                @Override
+                public void run() {
+                    dialogStage.addActor(rankAnimation);
+                    rankAnimation.show();
+                }})
+        ));
+    }
+
+    private void hideDialogsAndChangeScreen(Class<? extends AbstractTablexiaScreen<?>> screen, TablexiaApplication.ScreenTransaction screenTransaction) {
+        ApplicationBus.getInstance().post(new Tablexia.ChangeScreenEvent(screen, screenTransaction)).asynchronously();
+
+        victoryDialog.hide();
+        clearReceivedTrophyDialogs();
+    }
+
+    @Handler
+    public void onUserRankUpEvent(final UserRankManager.UserRankUpEvent userRankUpEvent) {
+        onRankUp(userRankUpEvent.getPreviousRank(), userRankUpEvent.getNewRank());
+    }
+
 	public void endGame() {
 		gamePhase = GamePhase.FINISHED;
         GameDAO.endGame(game);
 		Log.info(getClass(), "[DB] Ended game: " + game);
 		ApplicationBus.getInstance().publishAsync(new StartIncrementalSynchronizationEvent(getSelectedUser().getId()));
-	}
+    }
+
+    protected void forceGameEnd(GameResult gameResult) {}
 
     public void startNewGame() {
 		performHideTransaction(new Runnable() {
@@ -1046,6 +1389,20 @@ public abstract class AbstractTablexiaGame<T> extends AbstractTablexiaScreen<T>
         }
     }
 
+    /**
+     * Thread blocking method which waits for all GameScores to be set and ready.
+     */
+    public void waitForActualGameScore() {
+        while(!GameDAO.isGameScoreActual()) {
+            try {
+                Log.info(getClass(), "Waiting for 50ms for GameDAO to set all GameScores...");
+                Thread.sleep(50);
+            } catch (InterruptedException e) {
+                Thread.yield();
+            }
+        }
+    }
+
     public String getGameScoreString(String key, String nullValue) {
         if (game != null) {
             String gameScoreStr = game.getGameScoreValue(key);
diff --git a/core/src/cz/nic/tablexia/game/difficulty/GameDifficulty.java b/core/src/cz/nic/tablexia/game/difficulty/GameDifficulty.java
index 1a37ab0845eba446d552e3eab22f00a0bde331bf..e4da03b66be297a8a4becd6221cbb02582a11e6f 100644
--- a/core/src/cz/nic/tablexia/game/difficulty/GameDifficulty.java
+++ b/core/src/cz/nic/tablexia/game/difficulty/GameDifficulty.java
@@ -22,6 +22,7 @@ package cz.nic.tablexia.game.difficulty;
 import java.util.ArrayList;
 import java.util.List;
 
+import cz.nic.tablexia.TablexiaSettings;
 import cz.nic.tablexia.loader.application.ApplicationTextManager;
 import cz.nic.tablexia.shared.model.Game;
 
@@ -32,20 +33,22 @@ import cz.nic.tablexia.shared.model.Game;
  */
 public enum GameDifficulty {
 
-    TUTORIAL(0, "gamedifficulty_tutorial",  false, false),
-    EASY    (1, "gamedifficulty_easy",      true, true),
-    MEDIUM  (2, "gamedifficulty_medium",    true, true),
-    HARD    (3, "gamedifficulty_hard",      true, true);
+    TUTORIAL(0, TablexiaSettings.EXPERIENCE_POINTS_TUTORIAL, "gamedifficulty_tutorial",  false, false),
+    EASY    (1, TablexiaSettings.EXPERIENCE_POINTS_EASY,     "gamedifficulty_easy",      true, true),
+    MEDIUM  (2, TablexiaSettings.EXPERIENCE_POINTS_MEDIUM,   "gamedifficulty_medium",    true, true),
+    HARD    (3, TablexiaSettings.EXPERIENCE_POINTS_HARD,     "gamedifficulty_hard",      true, true);
 
     public static final GameDifficulty DEFAULT_DIFFICULTY = EASY;
 
     private int difficultyNumber;
+    private int experiencePointsMultiplier;
     private String descriptionResourceKey;
     private boolean visible;
     private boolean hasScore;
 
-    GameDifficulty(int difficultyNumber, String descriptionResourceKey, boolean visible, boolean hasScore) {
+    GameDifficulty(int difficultyNumber, int experiencePointsMultiplier, String descriptionResourceKey, boolean visible, boolean hasScore) {
         this.difficultyNumber = difficultyNumber;
+        this.experiencePointsMultiplier = experiencePointsMultiplier;
         this.descriptionResourceKey = descriptionResourceKey;
         this.visible = visible;
         this.hasScore = hasScore;
@@ -95,6 +98,10 @@ public enum GameDifficulty {
         return getGameDifficultyForDifficultyNumber(game.getGameDifficulty());
     }
 
+    public int getExperiencePointsMultiplier() {
+        return experiencePointsMultiplier;
+    }
+
     public boolean hasScore() {
         return hasScore;
     }
diff --git a/core/src/cz/nic/tablexia/game/games/in_the_darkness/InTheDarknessGame.java b/core/src/cz/nic/tablexia/game/games/in_the_darkness/InTheDarknessGame.java
index 8b79604d820cf263f7244b9943ddd702368ddaf7..ea45a8bf39a9a548cdeee2521a338986a213f35b 100644
--- a/core/src/cz/nic/tablexia/game/games/in_the_darkness/InTheDarknessGame.java
+++ b/core/src/cz/nic/tablexia/game/games/in_the_darkness/InTheDarknessGame.java
@@ -64,14 +64,18 @@ import static com.badlogic.gdx.scenes.scene2d.actions.Actions.sequence;
 public class InTheDarknessGame extends AbstractTablexiaGame<List<MapWidget>> implements MapWidget.TileMapClickListener {
 
     public static class GameResultResolver implements GameDefinition.GameResultResolver {
+        public static final int ERROR_COUNT_THREE_STARS = 2;
+        public static final int ERROR_COUNT_TWO_STARS   = 4;
+        public static final int ERROR_COUNT_ONE_STAR    = 8;
+
         @Override
         public AbstractTablexiaGame.GameResult getGameCupsResult(Game game) {
             Integer errorsCount = Integer.valueOf(game.getGameScoreValue(InTheDarknessGame.SCORE_KEY_ERRORS_COUNT));
-            if (errorsCount < 2) {
+            if (errorsCount < ERROR_COUNT_THREE_STARS) {
                 return AbstractTablexiaGame.GameResult.THREE_STAR;
-            } else if (errorsCount < 4) {
+            } else if (errorsCount < ERROR_COUNT_TWO_STARS) {
                 return AbstractTablexiaGame.GameResult.TWO_STAR;
-            } else if (errorsCount < 8) {
+            } else if (errorsCount < ERROR_COUNT_ONE_STAR) {
                 return AbstractTablexiaGame.GameResult.ONE_STAR;
             } else {
                 return AbstractTablexiaGame.GameResult.NO_STAR;
@@ -902,4 +906,21 @@ public class InTheDarknessGame extends AbstractTablexiaGame<List<MapWidget>> imp
                 PRELOADER_LEFT_COLUMN_WIDTH_RATIO,
                 PRELOADER_ROW_HEIGHT));
     }
+
+    //////////////////////////////////////////// DEBUG - FORCE GAME END
+
+    @Override
+    protected void forceGameEnd(GameResult result) {
+        int errors;
+
+        switch (result) {
+            case NO_STAR:  errors = GameResultResolver.ERROR_COUNT_ONE_STAR + 1; break;
+            case ONE_STAR: errors = GameResultResolver.ERROR_COUNT_ONE_STAR - 1; break;
+            case TWO_STAR: errors = GameResultResolver.ERROR_COUNT_TWO_STARS - 1; break;
+            default: errors = GameResultResolver.ERROR_COUNT_THREE_STARS - 1; break;
+        }
+        GameDAO.setGameScore(getGame(), SCORE_KEY_ERRORS_COUNT, Integer.toString(errors));
+        endGame();
+        showGameResultDialog();
+    }
 }
diff --git a/core/src/cz/nic/tablexia/game/games/kidnapping/KidnappingGame.java b/core/src/cz/nic/tablexia/game/games/kidnapping/KidnappingGame.java
index aa064f28fdacf85e1a902a16a708d2d7e77bb8a1..bee5545402a15bd3d8bf09d9773dd9ac95af8c83 100644
--- a/core/src/cz/nic/tablexia/game/games/kidnapping/KidnappingGame.java
+++ b/core/src/cz/nic/tablexia/game/games/kidnapping/KidnappingGame.java
@@ -2,7 +2,6 @@ package cz.nic.tablexia.game.games.kidnapping;
 
 import com.badlogic.gdx.audio.Music;
 import com.badlogic.gdx.graphics.Color;
-import com.badlogic.gdx.scenes.scene2d.EventListener;
 import com.badlogic.gdx.scenes.scene2d.Group;
 import com.badlogic.gdx.scenes.scene2d.InputEvent;
 import com.badlogic.gdx.scenes.scene2d.actions.Actions;
@@ -418,4 +417,33 @@ public class KidnappingGame extends AbstractTablexiaGame<GameState> {
                 PRELOADER_RIGHT_COLUMN_RATIO,
                 PRELOADER_ROW_HEIGHT));
     }
+
+//////////////////////////////////////////// DEBUG - FORCE GAME END
+
+    @Override
+    protected void forceGameEnd(GameResult result) {
+        int[] levels = Properties.GAMERULE_CUPS[getGame().getGameDifficulty() - 1];
+        int misses;
+        switch (result) {
+            case NO_STAR:
+                misses = levels[2] + 1;
+                break;
+            case ONE_STAR:
+                misses = levels[2];
+                break;
+            case TWO_STAR:
+                misses = levels[1];
+                break;
+            default:
+                misses = 0;
+                break;
+        }
+
+        setGameScore(GameState.GAME_MISSES, Integer.toString(misses));
+
+        waitForActualGameScore();
+
+        endGame();
+        showGameResultDialog();
+    }
 }
\ No newline at end of file
diff --git a/core/src/cz/nic/tablexia/game/games/kidnapping/util/KidnappingResultResolver.java b/core/src/cz/nic/tablexia/game/games/kidnapping/util/KidnappingResultResolver.java
index fde3a17ee663c84e11c71a07f6c9bc2896559009..3497decb2297ca5abea50ccc50ee9670d935964c 100644
--- a/core/src/cz/nic/tablexia/game/games/kidnapping/util/KidnappingResultResolver.java
+++ b/core/src/cz/nic/tablexia/game/games/kidnapping/util/KidnappingResultResolver.java
@@ -5,7 +5,6 @@ import cz.nic.tablexia.game.GameDefinition;
 import cz.nic.tablexia.game.games.kidnapping.Properties;
 import cz.nic.tablexia.game.games.kidnapping.model.GameState;
 import cz.nic.tablexia.shared.model.Game;
-import cz.nic.tablexia.util.Log;
 
 /**
  * Created by lhoracek on 10/6/15.
diff --git a/core/src/cz/nic/tablexia/game/games/night_watch/NightWatchGame.java b/core/src/cz/nic/tablexia/game/games/night_watch/NightWatchGame.java
index c984ddab581b354e20efac58432447c0de357e67..a5058aa71bc66b393483197c4363262dd9434ab2 100644
--- a/core/src/cz/nic/tablexia/game/games/night_watch/NightWatchGame.java
+++ b/core/src/cz/nic/tablexia/game/games/night_watch/NightWatchGame.java
@@ -309,10 +309,10 @@ public class NightWatchGame extends AbstractTablexiaGame<int[][]> {
 
                 Solution correctSolution = gameSolutions.get(currentLevel).get(currentRound);
                 boolean correct = correctSolution.check(windows, userSetTime);
-                if (!correctSolution.checkWindows(windows)) {
+                if (!correctSolution.checkWindows(windows) && !isGameFinished()) {
                     setGameScore(SCORE_WRONG_WINDOWS, ++wrongWindows);
                 }
-                if(!correctSolution.checkTime(userSetTime)){
+                if(!correctSolution.checkTime(userSetTime) && !isGameFinished()){
                     setGameScore(SCORE_WRONG_TIME, ++wrongTime);
                 }
                 Log.info(getClass(), "CORRECT: " + correct);
@@ -564,4 +564,39 @@ public class NightWatchGame extends AbstractTablexiaGame<int[][]> {
         return true;
     }
 
+
+//////////////////////////////////////////// DEBUG - FORCE GAME END
+
+    @Override
+    protected void forceGameEnd(GameResult result) {
+        int wrongWindows;
+        int wrongTimeCount;
+
+        switch (result) {
+            case NO_STAR:
+                wrongWindows = LEVELS_COUNT - 1;
+                wrongTimeCount = LEVELS_COUNT - 1;
+                break;
+            case ONE_STAR:
+                wrongWindows = ((2 * LEVELS_COUNT) - GameRulesHelper.SCORE_ONE_STAR - 1) / 2;
+                wrongTimeCount = wrongWindows;
+                break;
+            case TWO_STAR:
+                wrongWindows = ((2 * LEVELS_COUNT) - GameRulesHelper.SCORE_TWO_STARS - 1) / 2;
+                wrongTimeCount = wrongWindows;
+                break;
+            default:
+                wrongWindows = ((2 * LEVELS_COUNT) - GameRulesHelper.SCORE_THREE_STARS - 1) / 2;
+                wrongTimeCount = wrongWindows;
+                break;
+        }
+
+        setGameScore(SCORE_WRONG_WINDOWS, Integer.toString(wrongWindows));
+        setGameScore(SCORE_WRONG_TIME,    Integer.toString(wrongTimeCount));
+
+        waitForActualGameScore();
+
+        endGame();
+        showGameResultDialog();
+    }
 }
diff --git a/core/src/cz/nic/tablexia/game/games/night_watch/helper/GameRulesHelper.java b/core/src/cz/nic/tablexia/game/games/night_watch/helper/GameRulesHelper.java
index 92dd552524f7777b0a7b8474cfb969bcfe0e9361..719f89caf43aa985891fd448b46a4ded25ea4203 100644
--- a/core/src/cz/nic/tablexia/game/games/night_watch/helper/GameRulesHelper.java
+++ b/core/src/cz/nic/tablexia/game/games/night_watch/helper/GameRulesHelper.java
@@ -12,6 +12,11 @@ public class GameRulesHelper {
     private static final float  END_LID_TIME        = 0.7f;
     private static final int    NUMBER_OF_LEVELS    = 2;
 
+
+    public static final int     SCORE_THREE_STARS   = 13;
+    public static final int     SCORE_TWO_STARS     = 8;
+    public static final int     SCORE_ONE_STAR      = 4;
+
     public static int getRoundsPerLevelCount(GameDifficulty gameDifficulty, int level) {
         switch (gameDifficulty) {
             case EASY:
@@ -90,11 +95,11 @@ public class GameRulesHelper {
     }
 
     public static AbstractTablexiaGame.GameResult getNumberOfStarsForResult(int points){
-        if (points > 13) {
+        if (points > SCORE_THREE_STARS) {
             return AbstractTablexiaGame.GameResult.THREE_STAR;
-        } else if (points > 8) {
+        } else if (points > SCORE_TWO_STARS) {
             return AbstractTablexiaGame.GameResult.TWO_STAR;
-        } else if (points > 4) {
+        } else if (points > SCORE_ONE_STAR) {
             return AbstractTablexiaGame.GameResult.ONE_STAR;
         }
         return AbstractTablexiaGame.GameResult.NO_STAR;
diff --git a/core/src/cz/nic/tablexia/game/games/pursuit/PursuitGame.java b/core/src/cz/nic/tablexia/game/games/pursuit/PursuitGame.java
index ac676afd5259be9d0f5f86eb794b6a14184ccef7..03311a0a068e71fc1f483ccdf51b83d7de946e8d 100644
--- a/core/src/cz/nic/tablexia/game/games/pursuit/PursuitGame.java
+++ b/core/src/cz/nic/tablexia/game/games/pursuit/PursuitGame.java
@@ -12,6 +12,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.Image;
 import com.badlogic.gdx.utils.Align;
 import com.badlogic.gdx.utils.Array;
 import com.badlogic.gdx.utils.Scaling;
+import com.badlogic.gdx.utils.TimeUtils;
 import com.badlogic.gdx.utils.viewport.ExtendViewport;
 import com.badlogic.gdx.utils.viewport.Viewport;
 
@@ -552,4 +553,20 @@ public class PursuitGame extends AbstractTablexiaGame<int[][]> {
                 PRELOADER_RIGHT_COLUMN_RATIO,
                 PRELOADER_ROW_HEIGHT));
     }
+
+//////////////////////////////////////////// DEBUG - FORCE GAME END
+
+    @Override
+    protected void forceGameEnd(GameResult result) {
+        backgroundImage.removeListener(dragAndRotateActorListener);
+
+        long duration = GameRulesHelper.getDurationForStars(GameDifficulty.getByGame(getGame()), result.getStarCount());
+        GameDAO.startGame(getGame(), TimeUtils.millis() - duration);
+        GameDAO.setGameScore(getGame(), SCORE_KEY_MOVE_COUNT, Integer.toString(30));
+
+        endGame();
+        gameFinished.set(true);
+
+        showGameResultDialog();
+    }
 }
diff --git a/core/src/cz/nic/tablexia/game/games/pursuit/helper/GameRulesHelper.java b/core/src/cz/nic/tablexia/game/games/pursuit/helper/GameRulesHelper.java
index bed683b4265870d567e5c178bb9962ba307bd170..d70a01735e713a1fe6dc7939385eacbeddc0970e 100644
--- a/core/src/cz/nic/tablexia/game/games/pursuit/helper/GameRulesHelper.java
+++ b/core/src/cz/nic/tablexia/game/games/pursuit/helper/GameRulesHelper.java
@@ -7,41 +7,102 @@ import cz.nic.tablexia.game.difficulty.GameDifficulty;
  * Created by Václav Tarantík on 27.7.15.
  */
 public class GameRulesHelper {
+    private static final int EASY_ONE_STAR_DURATION         = 300;
+    private static final int EASY_TWO_STARS_DURATION        = 160;
+    private static final int EASY_THREE_STARS_DURATION      = 80;
+
+    private static final int MEDIUM_ONE_STAR_DURATION       = 600;
+    private static final int MEDIUM_TWO_STARS_DURATION      = 360;
+    private static final int MEDIUM_THREE_STARS_DURATION    = 160;
+
+    private static final int HARD_ONE_STAR_DURATION         = 800;
+    private static final int HARD_TWO_STARS_DURATION        = 460;
+    private static final int HARD_THREE_STARS_DURATION      = 320;
+
     public static final int[] COLUMNS_FOR_DIFFICULTY = new int[]{3,4,5};
 
     public static int getNumberOfColumns(GameDifficulty difficulty){
         return difficulty!=GameDifficulty.TUTORIAL?COLUMNS_FOR_DIFFICULTY[difficulty.ordinal()-1]:3;
     }
 
+    /**
+     * This method is used for force game end debug button.
+     * This method returns time in milliseconds, which is supposed to be saved in a database to get the exact star count for difficulty
+     * @param difficulty difficulty of the game
+     * @param stars star count you wish to get
+     * @return duration of the game in milliseconds
+     */
+    public static long getDurationForStars(GameDifficulty difficulty, int stars) {
+        int durationSeconds = 0;
+
+        switch (difficulty) {
+            case EASY:
+                if (stars == 0) {
+                    durationSeconds = EASY_ONE_STAR_DURATION + 1;
+                } else if (stars == 1) {
+                    durationSeconds = EASY_TWO_STARS_DURATION + 1;
+                } else if (stars == 2) {
+                    durationSeconds = EASY_THREE_STARS_DURATION + 1;
+                } else {
+                    durationSeconds = EASY_THREE_STARS_DURATION - 1;
+                }
+                break;
+            case MEDIUM:
+                if (stars == 0) {
+                    durationSeconds = MEDIUM_ONE_STAR_DURATION + 1;
+                } else if (stars == 1) {
+                    durationSeconds = MEDIUM_TWO_STARS_DURATION + 1;
+                } else if (stars == 2) {
+                    durationSeconds = MEDIUM_THREE_STARS_DURATION + 1;
+                } else {
+                    durationSeconds = MEDIUM_THREE_STARS_DURATION - 1;
+                }
+                break;
+            case HARD:
+                if (stars == 0) {
+                    durationSeconds = HARD_ONE_STAR_DURATION + 1;
+                } else if (stars == 1) {
+                    durationSeconds = HARD_TWO_STARS_DURATION + 1;
+                } else if (stars == 2) {
+                    durationSeconds = HARD_THREE_STARS_DURATION + 1;
+                } else {
+                    durationSeconds = HARD_THREE_STARS_DURATION - 1;
+                }
+                break;
+        }
+
+        return durationSeconds * 1000;
+    }
+
     public static AbstractTablexiaGame.GameResult getNumberOfStarsForTime(GameDifficulty difficulty, float millis){
         float seconds = millis/1000;
         switch (difficulty) {
             case EASY:
-                if (seconds >= 300) {
+                if (seconds > EASY_ONE_STAR_DURATION) {
                     return AbstractTablexiaGame.GameResult.NO_STAR;
-                } else if (seconds >= 160) {
+                } else if (seconds > EASY_TWO_STARS_DURATION) {
                     return AbstractTablexiaGame.GameResult.ONE_STAR;
-                } else if (seconds >= 80) {
+                } else if (seconds > EASY_THREE_STARS_DURATION) {
                     return AbstractTablexiaGame.GameResult.TWO_STAR;
                 } else {
                     return AbstractTablexiaGame.GameResult.THREE_STAR;
                 }
             case MEDIUM:
-                if (seconds >= 600) {
+                if (seconds > MEDIUM_ONE_STAR_DURATION) {
                     return AbstractTablexiaGame.GameResult.NO_STAR;
-                } else if (seconds >= 360) {
+                } else if (seconds > MEDIUM_TWO_STARS_DURATION) {
                     return AbstractTablexiaGame.GameResult.ONE_STAR;
-                } else if (seconds >= 160) {
+                } else if (seconds > MEDIUM_THREE_STARS_DURATION) {
                     return AbstractTablexiaGame.GameResult.TWO_STAR;
                 } else {
                     return AbstractTablexiaGame.GameResult.THREE_STAR;
                 }
             case HARD:
-                if (seconds >= 800) {
+                if (seconds > HARD_ONE_STAR_DURATION) {
                     return AbstractTablexiaGame.GameResult.NO_STAR;
-                } else if (seconds >= 460) {
+                } else if (seconds > HARD_TWO_STARS_DURATION) {
                     return AbstractTablexiaGame.GameResult.ONE_STAR;
-                } else if (seconds >= 320) {
+                } else if (seconds > HARD_THREE_STARS_DURATION) {
                     return AbstractTablexiaGame.GameResult.TWO_STAR;
                 } else {
                     return AbstractTablexiaGame.GameResult.THREE_STAR;
diff --git a/core/src/cz/nic/tablexia/game/games/robbery/RobberyGame.java b/core/src/cz/nic/tablexia/game/games/robbery/RobberyGame.java
index aa411f36ea4bac822085029e2627526fb47aadf4..e3417fba8f155b71f59d2ae2790f0751ceb72f0b 100644
--- a/core/src/cz/nic/tablexia/game/games/robbery/RobberyGame.java
+++ b/core/src/cz/nic/tablexia/game/games/robbery/RobberyGame.java
@@ -18,6 +18,7 @@ import cz.nic.tablexia.game.games.robbery.creature.CreatureFactory;
 import cz.nic.tablexia.game.games.robbery.rules.GameRule;
 import cz.nic.tablexia.game.games.robbery.rules.GameRulesDefinition;
 import cz.nic.tablexia.loader.application.ApplicationTextManager;
+import cz.nic.tablexia.model.game.GameDAO;
 import cz.nic.tablexia.shared.model.User;
 import cz.nic.tablexia.shared.model.Game;
 import cz.nic.tablexia.screen.AbstractTablexiaScreen;
@@ -30,14 +31,18 @@ import cz.nic.tablexia.util.ui.dialog.components.TwoColumnContentDialogComponent
 public class RobberyGame extends AbstractTablexiaGame<GameRule> {
 
 	public static class GameResultResolver implements GameDefinition.GameResultResolver {
+		public static final int FINAL_SCORE_THREE_STARS = 47;
+		public static final int FINAL_SCORE_TWO_STARS 	= 29;
+		public static final int FINAL_SCORE_ONE_STAR 	= 15;
+
 		@Override
 		public GameResult getGameCupsResult(Game game) {
 			int creaturesCount = getFinalScore(game);
-			if (creaturesCount > 47) {
+			if (creaturesCount > FINAL_SCORE_THREE_STARS) {
 				return AbstractTablexiaGame.GameResult.THREE_STAR;
-			} else if (creaturesCount > 29) {
+			} else if (creaturesCount > FINAL_SCORE_TWO_STARS) {
 				return AbstractTablexiaGame.GameResult.TWO_STAR;
-			} else if (creaturesCount > 15) {
+			} else if (creaturesCount > FINAL_SCORE_ONE_STAR) {
 				return AbstractTablexiaGame.GameResult.ONE_STAR;
 			} else {
 				return AbstractTablexiaGame.GameResult.NO_STAR;
@@ -313,11 +318,15 @@ public class RobberyGame extends AbstractTablexiaGame<GameRule> {
 	}
 
 	public void setActualCreatureNumber(int actualCreatureNumber) {
+		if(isGameFinished()) return;
+
 		this.actualCreatureNumber = actualCreatureNumber;
 		setGameScore(SCORE_KEY_PERSON_NUMBER, actualCreatureNumber);
 	}
 
 	public void setInnocencePersons(int innocencePersons) {
+		if(isGameFinished()) return;
+
 		this.innocencePersons = innocencePersons;
 		setGameScore(SCORE_KEY_INNOCENCE_PERSON, innocencePersons);
 	}
@@ -327,6 +336,8 @@ public class RobberyGame extends AbstractTablexiaGame<GameRule> {
 	}
 
 	public void setThievesEscaped(int thievesEscaped) {
+		if(isGameFinished()) return;
+
 		this.thievesEscaped = thievesEscaped;
 		setGameScore(SCORE_KEY_ESCAPED_THIEVES, thievesEscaped);
 	}
@@ -379,4 +390,31 @@ public class RobberyGame extends AbstractTablexiaGame<GameRule> {
 				PRELOADER_RIGHT_COLUMN_RATIO,
 				PRELOADER_ROW_HEIGHT));
 	}
+
+	//////////////////////////////////////////// DEBUG - FORCE GAME END
+
+
+	@Override
+	protected void forceGameEnd(GameResult result) {
+		switch (result) {
+			case NO_STAR:
+				GameDAO.setGameScore(getGame(), SCORE_KEY_PERSON_NUMBER   , Integer.toString(GameResultResolver.FINAL_SCORE_ONE_STAR));
+				break;
+			case ONE_STAR:
+				GameDAO.setGameScore(getGame(), SCORE_KEY_PERSON_NUMBER   , Integer.toString(GameResultResolver.FINAL_SCORE_ONE_STAR + 3));
+				break;
+			case TWO_STAR:
+				GameDAO.setGameScore(getGame(), SCORE_KEY_PERSON_NUMBER   , Integer.toString(GameResultResolver.FINAL_SCORE_TWO_STARS + 3));
+				break;
+			default:
+				GameDAO.setGameScore(getGame(), SCORE_KEY_PERSON_NUMBER   , Integer.toString(GameResultResolver.FINAL_SCORE_THREE_STARS + 3));
+				break;
+		}
+
+		//One escaped thief and one innocent person identified as a thief...
+		GameDAO.setGameScore(getGame(), SCORE_KEY_ESCAPED_THIEVES , Integer.toString(1));
+		GameDAO.setGameScore(getGame(), SCORE_KEY_INNOCENCE_PERSON, Integer.toString(1));
+
+		this.actualCreatureNumber = CREATURES_COUNT;
+	}
 }
diff --git a/core/src/cz/nic/tablexia/game/games/shooting_range/ShootingRangeGame.java b/core/src/cz/nic/tablexia/game/games/shooting_range/ShootingRangeGame.java
index f9638055c8f3581d64913a1e009a9b49a5e99692..aefc41272fb01bb9c8c4b78df3529e7de4f8734f 100644
--- a/core/src/cz/nic/tablexia/game/games/shooting_range/ShootingRangeGame.java
+++ b/core/src/cz/nic/tablexia/game/games/shooting_range/ShootingRangeGame.java
@@ -21,6 +21,7 @@ import cz.nic.tablexia.TablexiaSettings;
 import cz.nic.tablexia.game.AbstractTablexiaGame;
 import cz.nic.tablexia.game.common.media.GfxLibrary;
 import cz.nic.tablexia.game.common.media.SfxLibrary;
+import cz.nic.tablexia.game.difficulty.GameDifficulty;
 import cz.nic.tablexia.game.games.shooting_range.actors.Carousel;
 import cz.nic.tablexia.game.games.shooting_range.actors.Effect;
 import cz.nic.tablexia.game.games.shooting_range.actors.Row;
@@ -39,6 +40,7 @@ import cz.nic.tablexia.game.games.shooting_range.tools.TargetGenerator;
 import cz.nic.tablexia.game.games.shooting_range.tools.TargetPositionController;
 import cz.nic.tablexia.loader.application.ApplicationFontManager;
 import cz.nic.tablexia.loader.application.ApplicationTextManager;
+import cz.nic.tablexia.model.game.GameDAO;
 import cz.nic.tablexia.shared.model.Game;
 import cz.nic.tablexia.util.ui.AnimatedImage;
 import cz.nic.tablexia.util.ui.TablexiaLabel;
@@ -66,6 +68,7 @@ public class ShootingRangeGame extends AbstractTablexiaGame<GameState> {
     private static final int							        ONE_SECOND_DELAY		   			= 1;
     private static final float							        FLOWER_ANIMATION_DURATION			= 0.35f;
     private static final float							        WATCH_AND_CAROUSEL_HIDE_DURATION	= 0.5f;
+    private static final float                                  WATCH_PADDING_LEFT                  = 0.09f;
 
     private GfxLibrary gfxLibrary = new GfxLibrary(this, TextureType.values());
     private SfxLibrary sfxLibrary = new SfxLibrary(this, SoundType.values());
@@ -356,7 +359,7 @@ public class ShootingRangeGame extends AbstractTablexiaGame<GameState> {
         TablexiaLabel.TablexiaLabelStyle labelStyle = new TablexiaLabel.TablexiaLabelStyle(SCORE_COUNTER_TEXT_FONT, SCORE_COUNTER_TEXT_COLOR);
         getStage().addActor(score = new TablexiaLabel("0", labelStyle));
         scene.setBounds(0, getStage().getCamera().position.y - getViewportHeight() / 2, getViewportWidth(), getViewportHeight()); // scaling viewport camera y-position adjustment
-        watch.setPosition(0, getStage().getCamera().position.y - getViewportHeight() / 2);
+        watch.setPosition(getSceneWidth() * WATCH_PADDING_LEFT, getStage().getCamera().position.y - getViewportHeight() / 2);
         carousel.setPosition(getViewportWidth() - (carousel.getWidth() / 2), getStage().getCamera().position.y + (getViewportHeight() / 2) - (carousel.getHeight() / 2));
         score.setPosition(getViewportWidth() - score.getWidth() - SCORE_HORIZONTAL_PAD, SCORE_BOTTOM_PAD);
 		carousel.setVisible(false);
@@ -445,4 +448,47 @@ public class ShootingRangeGame extends AbstractTablexiaGame<GameState> {
                 PRELOADER_LEFT_COLUMN_WIDTH_RATIO,
                 PRELOADER_ROW_HEIGHT));
     }
+
+    //////////////////////////////////////////// DEBUG - FORCE GAME END
+
+
+    @Override
+    protected void forceGameEnd(GameResult result) {
+        int[] arrCups;
+
+        switch (GameDifficulty.getByGame(getGame())) {
+            case EASY:
+                arrCups = Properties.CUPS_EASY;
+                break;
+            case MEDIUM:
+                arrCups = Properties.CUPS_MEDIUM;
+                break;
+            case HARD:
+                arrCups = Properties.CUPS_HARD;
+                break;
+            default:
+                arrCups = Properties.CUPS_MEDIUM;
+                break;
+        }
+
+        int totalScore;
+
+        switch (result) {
+            case NO_STAR:
+                totalScore = arrCups[0] - 1;
+                break;
+            case ONE_STAR:
+                totalScore = arrCups[0] + 1;
+                break;
+            case TWO_STAR:
+                totalScore = arrCups[1] + 1;
+                break;
+            default:
+                totalScore = arrCups[2] + 1;
+                break;
+        }
+
+        GameDAO.setGameScore(getGame(), Properties.SCORE_TOTAL, Integer.toString(totalScore));
+        finishGame();
+    }
 }
diff --git a/core/src/cz/nic/tablexia/game/ranksystem/RankAnimation.java b/core/src/cz/nic/tablexia/game/ranksystem/RankAnimation.java
new file mode 100644
index 0000000000000000000000000000000000000000..ca7ffb14e3373cac0edf71935d71403016a1a817
--- /dev/null
+++ b/core/src/cz/nic/tablexia/game/ranksystem/RankAnimation.java
@@ -0,0 +1,244 @@
+package cz.nic.tablexia.game.ranksystem;
+
+import com.badlogic.gdx.graphics.Color;
+import com.badlogic.gdx.math.Interpolation;
+import com.badlogic.gdx.scenes.scene2d.EventListener;
+import com.badlogic.gdx.scenes.scene2d.Group;
+import com.badlogic.gdx.scenes.scene2d.Stage;
+import com.badlogic.gdx.scenes.scene2d.actions.Actions;
+import com.badlogic.gdx.scenes.scene2d.actions.ParallelAction;
+import com.badlogic.gdx.scenes.scene2d.actions.SequenceAction;
+import com.badlogic.gdx.scenes.scene2d.ui.Image;
+import com.badlogic.gdx.utils.Align;
+
+import cz.nic.tablexia.TablexiaSettings;
+import cz.nic.tablexia.loader.application.ApplicationAtlasManager;
+import cz.nic.tablexia.loader.application.ApplicationExternalSoundManager;
+import cz.nic.tablexia.loader.application.ApplicationFontManager;
+import cz.nic.tablexia.loader.application.ApplicationTextManager;
+import cz.nic.tablexia.util.Log;
+import cz.nic.tablexia.util.ScaleUtil;
+import cz.nic.tablexia.util.ui.TablexiaLabel;
+
+/**
+ * Created by drahomir on 6/8/16.
+ */
+public class RankAnimation extends Group {
+    private static final ApplicationFontManager.FontType_NEW RANK_NAME_LABEL_FONT  = ApplicationFontManager.FontType_NEW.BOLD_26;
+    private static final Color                               RANK_NAME_LABEL_COLOR = Color.WHITE;
+
+    private static final float   DIMMER_ALPHA                           = 0.7f;
+    private static final Color   DIMMER_COLOR                           = new Color(0, 0, 0, DIMMER_ALPHA);
+
+    private static final int     BACKGROUND_SHINE_COUNT                 = 3;
+    private static final float   BACKGROUND_SHINE_SIZE                  = 0.92f;
+
+    private static final float   BACKGROUND_SHINE_ROTATION              = 67.8f;
+    private static final float   BACKGROUND_SHINE_ROTATION_SPEED        = 9;
+    private static final float   BACKGROUND_SHINE_ROTATION_SPEED_DIFF   = 2;
+    private static final float   BACKGROUND_SHINE_FADEIN_DURATION       = 0.5f;
+
+    private static final float   BACKGROUND_SHINE_ALPHA                 = 0.65f;
+    private static final Color[] BACKGROUND_SHINE_COLORS                = new Color[] {
+            new Color(1, 1, 190/255f, BACKGROUND_SHINE_ALPHA),
+            new Color(1, 190/255f, 1, BACKGROUND_SHINE_ALPHA),
+            new Color(190/255f, 1, 1, BACKGROUND_SHINE_ALPHA)
+    };
+
+    private static final float   BADGE_HEIGHT                           = 0.31f;
+    private static final float   BADGE_SLIDE_DISTANCE                   = 0.6f;
+
+    private static final float   PROMOTION_TEXT_OFFSET                  = 0.24f;
+    private static final float   PROMOTION_TEXT_WIDTH                   = 0.35f;
+
+    private static final float   HIDE_FADEOUT_DURATION                  = 1f;
+    private static final float   SHOW_FADEIN_DURATION                   = 1f;
+
+    private static final float         SLIDE_ANIMATION_TIME            = 1.0f;
+    private static final Interpolation SLIDE_ANIMATION_INTERPOLATION   = Interpolation.pow4;
+
+
+    private final Group oldBadgeGroup, newBadgeGroup;
+
+    private final Group shinesGroup;
+    private final UserRankManager.UserRank oldRank, newRank;
+
+    private RankAnimation(float width, float height, UserRankManager.UserRank oldRank, UserRankManager.UserRank newRank) {
+        setSize(width, height);
+        this.oldRank = oldRank;
+        this.newRank = newRank;
+
+        //Creating
+        shinesGroup   = new Group();
+
+        oldBadgeGroup = new Group();
+        newBadgeGroup = new Group();
+
+        addAction(Actions.alpha(0));
+    }
+
+    public static final RankAnimation createRankAnimation(Stage stage, UserRankManager.UserRank oldRank, UserRankManager.UserRank newRank) {
+        float width  = TablexiaSettings.getViewportWidth(stage);
+        float height = TablexiaSettings.getViewportHeight(stage);
+        float posX   = TablexiaSettings.getViewportLeftX(stage);
+        float posY   = TablexiaSettings.getViewportBottomY(stage);
+
+        RankAnimation rankAnimation = new RankAnimation(width, height, oldRank, newRank);
+        rankAnimation.setPosition(posX, posY);
+
+        rankAnimation.prepareDimmer();
+        rankAnimation.prepareShines();
+        rankAnimation.preparePromotionImage();
+        rankAnimation.prepareOldBadge();
+        rankAnimation.prepareNewBadge();
+
+        return rankAnimation;
+    }
+
+    private void prepareDimmer() {
+        Image dimmer = new Image(ApplicationAtlasManager.getInstance().getColorTexture(DIMMER_COLOR));
+        dimmer.setSize(this.getWidth(), this.getHeight());
+        this.addActor(dimmer);
+    }
+
+    private void prepareShines() {
+        shinesGroup.setSize(this.getWidth(), this.getHeight());
+
+        Image[] shineImages = new Image[BACKGROUND_SHINE_COUNT];
+
+        for(int i = 0; i < BACKGROUND_SHINE_COUNT; i++) {
+            shineImages[i] = new Image(ApplicationAtlasManager.getInstance().getTextureRegion(ApplicationAtlasManager.RANK_UP_BACKGROUND));
+            shineImages[i].setSize(this.getWidth() * BACKGROUND_SHINE_SIZE, this.getWidth() * BACKGROUND_SHINE_SIZE);
+            shineImages[i].setPosition(this.getWidth()/2 - shineImages[i].getWidth()/2, this.getHeight()/2 - shineImages[i].getHeight()/2);
+            shineImages[i].setOrigin(Align.center);
+            shineImages[i].setColor(BACKGROUND_SHINE_COLORS[i % BACKGROUND_SHINE_COLORS.length]);
+
+            //Initial rotation
+            shineImages[i].setRotation(i * BACKGROUND_SHINE_ROTATION);
+
+            //Rotating animation
+            int direction = (i % 2) == 0 ? 1 : -1;
+            shineImages[i].addAction(Actions.forever(Actions.rotateBy(direction * 360, BACKGROUND_SHINE_ROTATION_SPEED + i * BACKGROUND_SHINE_ROTATION_SPEED_DIFF)));
+
+            //Add shine image
+            shinesGroup.addActor(shineImages[i]);
+        }
+
+        //Initially hidden
+        shinesGroup.addAction(Actions.alpha(0f));
+        this.addActor(shinesGroup);
+    }
+
+    private void preparePromotionImage() {
+        Image promotionImage = ScaleUtil.createImageToWidth(ApplicationAtlasManager.getInstance().getTextureRegion(ApplicationAtlasManager.RANK_UP_PROMOTION), PROMOTION_TEXT_WIDTH * this.getWidth());
+        promotionImage.setPosition(this.getWidth() / 2 - promotionImage.getWidth() / 2, this.getHeight() / 2 - promotionImage.getHeight() / 2 + PROMOTION_TEXT_OFFSET * this.getHeight());
+        this.addActor(promotionImage);
+    }
+
+    private void prepareOldBadge() {
+        prepareBadgeGroup(oldBadgeGroup, oldRank);
+
+        this.addActor(oldBadgeGroup);
+    }
+
+    private void prepareNewBadge() {
+        prepareBadgeGroup(newBadgeGroup, newRank);
+
+        newBadgeGroup.addAction(Actions.alpha(0));
+        newBadgeGroup.addAction(Actions.moveBy(BADGE_SLIDE_DISTANCE * this.getWidth(), 0));
+
+        this.addActor(newBadgeGroup);
+    }
+
+    private void prepareBadgeGroup(Group group, UserRankManager.UserRank userRank) {
+        Image badgeImage = createBadgeImage(userRank);
+        group.setSize(badgeImage.getWidth(), badgeImage.getHeight());
+        group.setPosition(this.getWidth() / 2f - group.getWidth() / 2f, this.getHeight() / 2f - group.getHeight() / 2f);
+        group.addActor(badgeImage);
+
+        if(userRank.hasBadgeName()) {
+            TablexiaLabel badgeLabel = createBadgeLabel(userRank);
+            badgeLabel.setPosition(badgeImage.getX() + badgeImage.getWidth() / 2f - badgeLabel.getWidth() / 2f, badgeImage.getY() - badgeLabel.getHeight());
+            group.addActor(badgeLabel);
+        }
+    }
+
+    private TablexiaLabel createBadgeLabel(UserRankManager.UserRank userRank) {
+        TablexiaLabel badgeLabel = new TablexiaLabel(
+                ApplicationTextManager.getInstance().getText(userRank.getNameKey()),
+                new TablexiaLabel.TablexiaLabelStyle(RANK_NAME_LABEL_FONT, RANK_NAME_LABEL_COLOR)
+        );
+
+        badgeLabel.setAlignment(Align.center);
+        return  badgeLabel;
+    }
+
+    private Image createBadgeImage(UserRankManager.UserRank userRank) {
+        return ScaleUtil.createImageToHeight(ApplicationAtlasManager.getInstance().getTextureRegion(userRank.getBadgeImageKey()), this.getHeight() * BADGE_HEIGHT);
+    }
+
+    private void animateBadges() {
+        oldBadgeGroup.addAction(
+            new ParallelAction(
+                Actions.moveBy(-BADGE_SLIDE_DISTANCE * this.getWidth(), 0, SLIDE_ANIMATION_TIME, SLIDE_ANIMATION_INTERPOLATION),
+                Actions.fadeOut(SLIDE_ANIMATION_TIME, SLIDE_ANIMATION_INTERPOLATION)
+            )
+        );
+
+        newBadgeGroup.addAction(
+                new ParallelAction(
+                        Actions.moveBy(-BADGE_SLIDE_DISTANCE * this.getWidth(), 0, SLIDE_ANIMATION_TIME, SLIDE_ANIMATION_INTERPOLATION),
+                        Actions.fadeIn(SLIDE_ANIMATION_TIME, SLIDE_ANIMATION_INTERPOLATION)
+                )
+        );
+
+        shinesGroup.addAction(
+            new SequenceAction(
+                Actions.delay(SLIDE_ANIMATION_TIME),
+                new ParallelAction(
+                    Actions.fadeIn(BACKGROUND_SHINE_FADEIN_DURATION),
+                    Actions.run(new Runnable() {
+                        @Override
+                        public void run() {
+                            ApplicationExternalSoundManager.getInstance().getSound(ApplicationExternalSoundManager.RANKUP).play();
+                        }
+                    })
+                )
+            )
+        );
+    }
+
+    ////////////////////////////////
+    /////    PUBLIC METHODS    /////
+    ////////////////////////////////
+
+    public void hide() {
+        this.addAction(new SequenceAction(
+                Actions.fadeOut(HIDE_FADEOUT_DURATION),
+                Actions.removeActor()
+        ));
+    }
+
+    public void show() {
+        if(getStage() == null) {
+            Log.err(getClass(), "Couldn't show Rank Animation, because there is not stage!");
+        }
+
+        this.addAction(new SequenceAction(
+            Actions.fadeIn(SHOW_FADEIN_DURATION),
+            Actions.run(new Runnable() {
+                @Override
+                public void run() {
+                    animateBadges();
+                }
+            })
+        ));
+    }
+
+    public void setNewBadgeEventListener(EventListener eventListener) {
+        if(eventListener == null) return;
+
+        newBadgeGroup.clearListeners();
+        newBadgeGroup.addListener(eventListener);
+    }
+}
\ No newline at end of file
diff --git a/core/src/cz/nic/tablexia/game/ranksystem/UserRankManager.java b/core/src/cz/nic/tablexia/game/ranksystem/UserRankManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..1d2fa996518f2cfa90f4390ea16c92ca4ead0240
--- /dev/null
+++ b/core/src/cz/nic/tablexia/game/ranksystem/UserRankManager.java
@@ -0,0 +1,352 @@
+package cz.nic.tablexia.game.ranksystem;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import cz.nic.tablexia.bus.ApplicationBus;
+import cz.nic.tablexia.game.AbstractTablexiaGame;
+import cz.nic.tablexia.game.GameDefinition;
+import cz.nic.tablexia.game.difficulty.GameDifficulty;
+import cz.nic.tablexia.loader.application.ApplicationAtlasManager;
+import cz.nic.tablexia.loader.application.ApplicationTextManager;
+import cz.nic.tablexia.model.game.GameDAO;
+import cz.nic.tablexia.shared.model.Game;
+import cz.nic.tablexia.shared.model.User;
+import cz.nic.tablexia.util.Log;
+
+/**
+ * Created by bcx on 4/15/16.
+ */
+public class UserRankManager {
+    public enum UserRank {
+        RANK_NONE ( 0, false, false, null,                                                       ApplicationAtlasManager.BADGE_NONE, ApplicationAtlasManager.BADGE_NONE_ICON, new int[]{  0,   0,   0,   0,   0,   0}),
+        RANK_I    ( 1, true,  true,  ApplicationTextManager.ApplicationTextsAssets.USER_RANK_1,  ApplicationAtlasManager.BADGE_1,    ApplicationAtlasManager.BADGE_1_ICON,    new int[]{  3,   3,   3,   3,   3,   3}),
+        RANK_II   ( 2, true,  true,  ApplicationTextManager.ApplicationTextsAssets.USER_RANK_2,  ApplicationAtlasManager.BADGE_2,    ApplicationAtlasManager.BADGE_2_ICON,    new int[]{  9,   9,   9,   9,   9,   9}),
+        RANK_III  ( 3, true,  true,  ApplicationTextManager.ApplicationTextsAssets.USER_RANK_3,  ApplicationAtlasManager.BADGE_3,    ApplicationAtlasManager.BADGE_3_ICON,    new int[]{ 18,  18,  18,  18,  18,  18}),
+        RANK_IV   ( 4, true,  true,  ApplicationTextManager.ApplicationTextsAssets.USER_RANK_4,  ApplicationAtlasManager.BADGE_4,    ApplicationAtlasManager.BADGE_4_ICON,    new int[]{ 30,  30,  30,  30,  30,  30}),
+        RANK_V    ( 5, true,  true,  ApplicationTextManager.ApplicationTextsAssets.USER_RANK_5,  ApplicationAtlasManager.BADGE_5,    ApplicationAtlasManager.BADGE_5_ICON,    new int[]{ 48,  48,  48,  48,  48,  48}),
+        RANK_VI   ( 6, true,  true,  ApplicationTextManager.ApplicationTextsAssets.USER_RANK_6,  ApplicationAtlasManager.BADGE_6,    ApplicationAtlasManager.BADGE_6_ICON,    new int[]{ 73,  73,  73,  73,  73,  73}),
+        RANK_VII  ( 7, true,  true,  ApplicationTextManager.ApplicationTextsAssets.USER_RANK_7,  ApplicationAtlasManager.BADGE_7,    ApplicationAtlasManager.BADGE_7_ICON,    new int[]{105, 105, 105, 105, 105, 105}),
+        RANK_VIII ( 8, true,  true,  ApplicationTextManager.ApplicationTextsAssets.USER_RANK_8,  ApplicationAtlasManager.BADGE_8,    ApplicationAtlasManager.BADGE_8_ICON,    new int[]{145, 145, 145, 145, 145, 145}),
+        RANK_IX   ( 9, true,  true,  ApplicationTextManager.ApplicationTextsAssets.USER_RANK_9,  ApplicationAtlasManager.BADGE_9,    ApplicationAtlasManager.BADGE_9_ICON,    new int[]{193, 193, 193, 193, 193, 193}),
+        RANK_X    (10, true,  true,  ApplicationTextManager.ApplicationTextsAssets.USER_RANK_10, ApplicationAtlasManager.BADGE_10,   ApplicationAtlasManager.BADGE_10_ICON,   new int[]{248, 248, 248, 248, 248, 248}),
+        RANK_XI   (11, true,  true,  ApplicationTextManager.ApplicationTextsAssets.USER_RANK_11, ApplicationAtlasManager.BADGE_11,   ApplicationAtlasManager.BADGE_11_ICON,   new int[]{316, 316, 316, 316, 316, 316});
+
+        private int id;
+        private String nameKey;
+        private String badgeImage, badgeIcon;
+        private int[] experiencePointsNeeded;
+
+        private boolean userMenu, badgeBoard;
+
+        UserRank(int id, boolean userMenu, boolean badgeBoard, String nameKey, String badgeImage, String badgeIcon, int[] experiencePointsNeeded) {
+            this.id = id;
+            this.nameKey = nameKey;
+            this.badgeImage = badgeImage;
+            this.badgeIcon = badgeIcon;
+            this.experiencePointsNeeded = experiencePointsNeeded;
+
+            this.userMenu = userMenu;
+            this.badgeBoard = badgeBoard;
+        }
+
+        public int getId() {
+            return id;
+        }
+
+        public static UserRank getInitialRank() {
+            return RANK_NONE;
+        }
+
+        public static UserRank getRank(int id) {
+            for(UserRank rank : values()) {
+                if(rank.getId() == id)
+                    return rank;
+            }
+
+            return null;
+        }
+
+        public static UserRank getNextRank(UserRank rank) {
+            UserRank next = UserRank.getRank(rank.getId() + 1);
+            return next != null ? next : rank;
+        }
+
+        public boolean hasBadgeName() {
+            return nameKey != null;
+        }
+
+        public boolean isShownOnUserMenu() {
+            return userMenu;
+        }
+
+        public boolean isShownOnBadgeBoard() {
+            return badgeBoard;
+        }
+
+        //TODO - Don't return keys, return actual texture regions and texts...
+        public String getBadgeImageKey() {
+            return badgeImage;
+        }
+
+        public String getBadgeIconKey() {
+            return badgeIcon;
+        }
+
+        public String getNameKey() {
+            return nameKey;
+        }
+
+        public int[] getExperiencePointsNeeded() {
+            return experiencePointsNeeded;
+        }
+    }
+
+    public static class RankProgress {
+        int minXP, currXP, nextXP;
+
+        public RankProgress(int minXP, int currXP, int nextXP) {
+            this.minXP = minXP;
+            this.currXP = currXP;
+            this.nextXP = nextXP;
+        }
+
+        public int getMinXP() {
+            return minXP;
+        }
+
+        public void setMinXP(int minXP) {
+            this.minXP = minXP;
+        }
+
+        public int getCurrXP() {
+            return currXP;
+        }
+
+        public void setCurrXP(int currXP) {
+            this.currXP = currXP;
+        }
+
+        public int getNextXP() {
+            return nextXP;
+        }
+
+        public void setNextXP(int nextXP) {
+            this.nextXP = nextXP;
+        }
+
+
+        public float getPercentDone() {
+            if(nextXP - minXP == 0) return 1f; //divide by zero case
+            return (currXP - minXP) / (float) (nextXP - minXP);
+        }
+
+        @Override
+        public String toString() {
+            return "Min: " + minXP + "   Curr: " + currXP + "   NextRank: " + nextXP;
+        }
+    }
+
+    //FIELDS
+    private static UserRankManager instance;
+
+    //Caches users progress
+    private Map<Long, RankProgress[]> gameRankProgressMap;
+
+    //Caches users ranks
+    private Map<Long, UserRank> userRankMap;
+
+    //Keeps track of user that need to be refreshed
+    private Map<Long, Boolean> userRefreshMap;
+
+    //When was the last time user ranked up
+    private Map<Long, Long> userLastRankUpTime;
+
+    private UserRankManager() {
+        gameRankProgressMap = new HashMap<Long, RankProgress[]>();
+        userRankMap         = new HashMap<Long, UserRank>();
+        userRefreshMap      = new HashMap<Long, Boolean>();
+        userLastRankUpTime  = new HashMap<Long, Long>();
+    }
+
+    public static final UserRankManager getInstance() {
+        if(instance == null)
+            instance = new UserRankManager();
+
+        return instance;
+    }
+
+    private boolean isRankRefreshNeeded(User user) {
+        if(userRefreshMap.get(user.getId()) == null || userRefreshMap.get(user.getId())) return true;
+        return false;
+    }
+
+    public void setRankRefreshNeeded(User user, boolean refreshNeeded) {
+        userRefreshMap.put(user.getId(), refreshNeeded);
+    }
+
+    public RankProgress[] getGameRankProgresses(User user) {
+        if(isRankRefreshNeeded(user))
+            refreshUserRank(user);
+
+        RankProgress[] result = gameRankProgressMap.get(user.getId());
+        if(result == null) {
+            refreshUserRank(user);
+            result = gameRankProgressMap.get(user.getId());
+        }
+
+        return result;
+    }
+
+    public RankProgress getGameRankProgress(User user, GameDefinition game) {
+        if(isRankRefreshNeeded(user))
+            refreshUserRank(user);
+
+
+        RankProgress[] result = gameRankProgressMap.get(user.getId());
+        if(result == null) {
+            refreshUserRank(user);
+            result = gameRankProgressMap.get(user.getId());
+        }
+
+        return result[game.getGameNumber() - 1];
+    }
+
+    public RankProgress getTotalUserRankProgress(User user) {
+        RankProgress resultRankProgress = new RankProgress(0, 0, 0);
+
+        RankProgress[] gameRankProgresses =  UserRankManager.getInstance().getGameRankProgresses(user);
+
+        for(RankProgress rankProgress : gameRankProgresses) {
+            int min = rankProgress.getMinXP();
+            int curr = rankProgress.getCurrXP() > rankProgress.getNextXP() ? rankProgress.getNextXP() : rankProgress.getCurrXP();
+            int next = rankProgress.getNextXP();
+
+            resultRankProgress.setMinXP(resultRankProgress.getMinXP() + min);
+            resultRankProgress.setCurrXP(resultRankProgress.getCurrXP() + curr);
+            resultRankProgress.setNextXP(resultRankProgress.getNextXP() + next);
+        }
+
+        return resultRankProgress;
+    }
+
+    public UserRank getRank(User user) {
+        if(isRankRefreshNeeded(user))
+            refreshUserRank(user);
+
+        return userRankMap.get(user.getId());
+    }
+
+    public long getLastTimeRankedUp(User user) {
+        long result = 0;
+
+        if(userLastRankUpTime.containsKey(user.getId()))
+            result = userLastRankUpTime.get(user.getId());
+
+        return result;
+    }
+
+    private int getExperiencePoints(int cupsCount, int difficulty) {
+        return cupsCount * difficulty;
+    }
+
+    public synchronized void forceRefreshUserRank(User user) {
+        setRankRefreshNeeded(user, true);
+        refreshUserRank(user);
+    }
+
+    private synchronized void refreshUserRank(User user) {
+        if(!isRankRefreshNeeded(user)) {
+            return;
+        }
+
+        setRankRefreshNeeded(user, false);
+
+        UserRank oldRank;
+        boolean firstRefresh = false;
+        if((oldRank = userRankMap.get(user.getId())) == null) {
+            oldRank = UserRank.getInitialRank();
+            userRankMap.put(user.getId(), oldRank);
+            firstRefresh = true;
+        }
+
+        UserRank currRank = UserRank.getInitialRank();
+        UserRank nextRank = UserRank.getNextRank(currRank);
+
+        //TODO cache 'em for currently logged user
+        List<Game> userGames = GameDAO.selectUserGamesForRankManager(user.getId());
+
+        int[] gamesExperiencePoints = new int[GameDefinition.values().length];
+
+        Log.info(getClass(), "Calculating rank for user: " + user.getName() + " from " + userGames.size() + " games.");
+        for(Game game : userGames) {
+            if(!game.isFinished()) continue;
+            if(game.getGameDifficulty() == GameDifficulty.TUTORIAL.getDifficultyNumber()) continue;
+
+            AbstractTablexiaGame.GameResult gameResult = GameDAO.getGameResult(game);
+            int experiencePoints = getExperiencePoints(gameResult.getStarCount(), game.getGameDifficulty());
+            int gameNumber = game.getGameNumber();
+
+            //Increases games cups by starCount
+            gamesExperiencePoints[gameNumber - 1] += experiencePoints;
+
+            //Ignore experience points If user got more than is requested for the next rank
+            if(gamesExperiencePoints[gameNumber - 1] > nextRank.getExperiencePointsNeeded()[gameNumber - 1])
+                gamesExperiencePoints[gameNumber - 1] = nextRank.getExperiencePointsNeeded()[gameNumber - 1];
+
+            //checking rank...
+            boolean result = true;
+
+            for(int i = 0; i < nextRank.getExperiencePointsNeeded().length; i++) {
+                if(gamesExperiencePoints[i] < nextRank.getExperiencePointsNeeded()[i]) {
+                    result = false;
+                    break;
+                }
+            }
+
+            //Rank up
+            if(result) {
+                currRank = nextRank;
+                nextRank = UserRank.getNextRank(currRank);
+                userLastRankUpTime.put(user.getId(), game.getEndTime());
+            }
+        }
+
+        RankProgress[] gameRankProgresses = new RankProgress[GameDefinition.values().length];
+        for(int i = 0; i < gameRankProgresses.length; i++) {
+            gameRankProgresses[i] = new RankProgress(currRank.getExperiencePointsNeeded()[i], gamesExperiencePoints[i], nextRank.getExperiencePointsNeeded()[i]);
+        }
+
+        gameRankProgressMap.put(user.getId(), gameRankProgresses);
+        userRankMap.put(user.getId(), currRank);
+
+        if(oldRank != null && currRank != null && oldRank != currRank && !firstRefresh && currRank.getId() > oldRank.getId()) {
+            //User has ranked up since the last time we checked....
+            ApplicationBus.getInstance().post(new UserRankUpEvent(user, oldRank, currRank)).asynchronously();
+        }
+    }
+
+    public static class UserRankUpEvent implements ApplicationBus.ApplicationEvent {
+        private User user;
+        private UserRank previousRank, newRank;
+
+        private UserRankUpEvent(User user, UserRank previousRank, UserRank newRank) {
+            this.previousRank = previousRank;
+            this.newRank = newRank;
+            this.user = user;
+        }
+
+        public User getUser() {
+            return user;
+        }
+
+        public UserRank getPreviousRank() {
+            return previousRank;
+        }
+
+        public UserRank getNewRank() {
+            return newRank;
+        }
+    }
+}
\ No newline at end of file
diff --git a/core/src/cz/nic/tablexia/loader/application/ApplicationAtlasManager.java b/core/src/cz/nic/tablexia/loader/application/ApplicationAtlasManager.java
index acf0021daeac7ff80cd8118c066c4bd9c5cc9a8f..55bf268af1c734d12fad0cdc50aef22c7fa980bd 100644
--- a/core/src/cz/nic/tablexia/loader/application/ApplicationAtlasManager.java
+++ b/core/src/cz/nic/tablexia/loader/application/ApplicationAtlasManager.java
@@ -44,6 +44,8 @@ public class ApplicationAtlasManager extends TablexiaAtlasManager implements IAp
     public static final String MAINMENU_ICON_GAMES_UNPRESSED            = MAINMENU_PATH + "icon_games_unpressed";
     public static final String MAINMENU_ICON_HALLOFFAME_PRESSED         = MAINMENU_PATH + "icon_halloffame_pressed";
     public static final String MAINMENU_ICON_HALLOFFAME_UNPRESSED       = MAINMENU_PATH + "icon_halloffame_unpressed";
+    public static final String MAINMENU_ICON_PROFILE_PRESSED            = MAINMENU_PATH + "icon_profile_pressed";
+    public static final String MAINMENU_ICON_PROFILE_UNPRESSED          = MAINMENU_PATH + "icon_profile_unpressed";
     public static final String MAINMENU_ICON_LOGOUT_PRESSED             = MAINMENU_PATH + "icon_logout_pressed";
     public static final String MAINMENU_ICON_LOGOUT_UNPRESSED           = MAINMENU_PATH + "icon_logout_unpressed";
     public static final String MAINMENU_ICON_STATISTICS_PRESSED         = MAINMENU_PATH + "icon_statistics_pressed";
@@ -72,8 +74,39 @@ public class ApplicationAtlasManager extends TablexiaAtlasManager implements IAp
     public static final String USERMENU_MENUITEM_AVATAR_11              = AVATAR_PATH+"11";
     public static final String USERMENU_MENUITEM_AVATAR_12              = AVATAR_PATH+"12";
 
+    public static final String BADGE_PATH                               = "badge/";
+    public static final String BADGE_NONE                               = BADGE_PATH + "badge_none";
+    public static final String BADGE_1                                  = BADGE_PATH + "badge1";
+    public static final String BADGE_2                                  = BADGE_PATH + "badge2";
+    public static final String BADGE_3                                  = BADGE_PATH + "badge3";
+    public static final String BADGE_4                                  = BADGE_PATH + "badge4";
+    public static final String BADGE_5                                  = BADGE_PATH + "badge5";
+    public static final String BADGE_6                                  = BADGE_PATH + "badge6";
+    public static final String BADGE_7                                  = BADGE_PATH + "badge7";
+    public static final String BADGE_8                                  = BADGE_PATH + "badge8";
+    public static final String BADGE_9                                  = BADGE_PATH + "badge9";
+    public static final String BADGE_10                                 = BADGE_PATH + "badge10";
+    public static final String BADGE_11                                 = BADGE_PATH + "badge11";
+
+    public static final String BADGE_NONE_ICON                          = BADGE_PATH + "badge_none_icon";
+    public static final String BADGE_1_ICON                             = BADGE_PATH + "badge1_icon";
+    public static final String BADGE_2_ICON                             = BADGE_PATH + "badge2_icon";
+    public static final String BADGE_3_ICON                             = BADGE_PATH + "badge3_icon";
+    public static final String BADGE_4_ICON                             = BADGE_PATH + "badge4_icon";
+    public static final String BADGE_5_ICON                             = BADGE_PATH + "badge5_icon";
+    public static final String BADGE_6_ICON                             = BADGE_PATH + "badge6_icon";
+    public static final String BADGE_7_ICON                             = BADGE_PATH + "badge7_icon";
+    public static final String BADGE_8_ICON                             = BADGE_PATH + "badge8_icon";
+    public static final String BADGE_9_ICON                             = BADGE_PATH + "badge9_icon";
+    public static final String BADGE_10_ICON                             = BADGE_PATH + "badge10_icon";
+    public static final String BADGE_11_ICON                            = BADGE_PATH + "badge11_icon";
+
     public static final String SCREEN_LOADER_MOUSE                      = "screenloader/mouse";
 
+    public static final String UI_PATH                               = "ui/";
+    public static final String BACK_BUTTON                           = UI_PATH + "back_button";
+    public static final String BACK_BUTTON_PRESSED                   = UI_PATH + "back_button_pressed";
+
     public static final String DIALOG_PATH                           = "dialog/";
     public static final String DIALOG_BUBBLE_CLASSIC                 = DIALOG_PATH + "bubble_classic";
     public static final String DIALOG_BUBBLE_CLASSIC_ROUND           = DIALOG_PATH + "bubble_classic_round";
@@ -84,6 +117,7 @@ public class ApplicationAtlasManager extends TablexiaAtlasManager implements IAp
     public static final String DIALOG_RECTANGLE                      = DIALOG_PATH + "dialog_rectangle";
     public static final String DIALOG_SQUARE                         = DIALOG_PATH + "dialog_square";
     public static final String DIALOG_SQUARE_BORDER_LINES            = DIALOG_PATH + "dialog_square_borderlines";
+    public static final String DIALOG_BADGE_BOARD                    = DIALOG_PATH + "dialog_badgeboard";
 
     public static final String DIALOG_BUBBLE_ARROW_BOTTOM            = DIALOG_PATH + "bubble_arrow_bottom";
     public static final String DIALOG_BUBBLE_ARROW_TOP               = DIALOG_PATH + "bubble_arrow_top";
@@ -114,6 +148,14 @@ public class ApplicationAtlasManager extends TablexiaAtlasManager implements IAp
 
     public static final String DIALOG_WARNING                        = DIALOG_PATH + "quitdialog_warning";
 
+    public static final String PROGRESS_BAR             = UI_PATH + "progressbar";
+    public static final String PROGRESS_BAR_FILL        = UI_PATH + "progressbar_fill";
+    public static final String RANK_UP_BACKGROUND       = UI_PATH + "rankup_bg";
+    public static final String RANK_UP_PROMOTION        = UI_PATH + "promotion_label";
+    public static final String RANK_UP_STAR             = UI_PATH + "rankup_star";
+    public static final String DEBUG_CUP_BUTTON_RELEASED= UI_PATH + "debug_cup_released";
+    public static final String DEBUG_CUP_BUTTON_PRESSED = UI_PATH + "debug_cup_pressed";
+
     public static final String UNIVERSAL_PATH    = "universal/";
     public static final String BACKGROUND_WOODEN = UNIVERSAL_PATH + "background_wooden";
 
diff --git a/core/src/cz/nic/tablexia/loader/application/ApplicationExternalSoundManager.java b/core/src/cz/nic/tablexia/loader/application/ApplicationExternalSoundManager.java
index f0497472e497fa980d9e935ddb49478bc179e997..ceaf4582d0d2f2a885da27a4ffb4c97ded34cb68 100644
--- a/core/src/cz/nic/tablexia/loader/application/ApplicationExternalSoundManager.java
+++ b/core/src/cz/nic/tablexia/loader/application/ApplicationExternalSoundManager.java
@@ -37,9 +37,12 @@ public class ApplicationExternalSoundManager extends TablexiaSoundManager implem
 	public 	static final String MAINMENU_OPEN		= MAINMENU_PATH + "mainmenu_open.mp3";
     public 	static final String MAINMENU_CLOSE		= MAINMENU_PATH + "mainmenu_close.mp3";
 
+	public  static final String RANKUP				= "badge/rankup_sound.mp3";
+
     public void load() {
         loadSound(MAINMENU_OPEN);
         loadSound(MAINMENU_CLOSE);
+		loadSound(RANKUP);
     }
 
 	private String createAssetPath(String fileName) {
diff --git a/core/src/cz/nic/tablexia/loader/application/ApplicationFontManager.java b/core/src/cz/nic/tablexia/loader/application/ApplicationFontManager.java
index 354d3812208cb12c1bc3ea36dd9676ebff703ae3..1f9887639349c199eb0a55136e91d8ea914ea944 100644
--- a/core/src/cz/nic/tablexia/loader/application/ApplicationFontManager.java
+++ b/core/src/cz/nic/tablexia/loader/application/ApplicationFontManager.java
@@ -43,7 +43,8 @@ public class ApplicationFontManager implements IApplicationLoader {
 		BOLD_40  (40, true),
 		BOLD_45  (45, true),
 		BOLD_50  (50, true),
-		BOLD_55  (55, true);
+		BOLD_55  (55, true),
+		BOLD_65  (65, true);
 
 		int size;
 		boolean bold;
diff --git a/core/src/cz/nic/tablexia/loader/application/ApplicationTextManager.java b/core/src/cz/nic/tablexia/loader/application/ApplicationTextManager.java
index dc9ca8288d880a77c1e8458868b743e2984ec65f..103169d91045bcd906936dab51dcc41d649fd2bc 100644
--- a/core/src/cz/nic/tablexia/loader/application/ApplicationTextManager.java
+++ b/core/src/cz/nic/tablexia/loader/application/ApplicationTextManager.java
@@ -56,6 +56,7 @@ public class ApplicationTextManager extends TablexiaDataManager<I18NBundle> impl
 		public static final String MAINMENU_STATISTICS 				= "mainmenu_statistics";
 		public static final String MAINMENU_ENCYCLOPEDIA			= "mainmenu_encyclopedia";
 		public static final String MAINMENU_ABOUT					= "mainmenu_about";
+		public static final String MAINMENU_PROFILE					= "mainmenu_profile";
 		public static final String MAINMENU_LOGOUT					= "mainmenu_logout";
 		public static final String MAINMENU_DEBUG					= "mainmenu_screendebug";
 
@@ -93,6 +94,18 @@ public class ApplicationTextManager extends TablexiaDataManager<I18NBundle> impl
 
 		public static final String SYNC_REQUEST_DIALOG_TEXT				= "sync_request_dialog_text";
 		public static final String SYNC_REQUEST_BUTTON					= "sync_request_button";
+
+		public static final String USER_RANK_1							= "user_rank_1";
+		public static final String USER_RANK_2							= "user_rank_2";
+		public static final String USER_RANK_3							= "user_rank_3";
+		public static final String USER_RANK_4							= "user_rank_4";
+		public static final String USER_RANK_5							= "user_rank_5";
+		public static final String USER_RANK_6							= "user_rank_6";
+		public static final String USER_RANK_7							= "user_rank_7";
+		public static final String USER_RANK_8							= "user_rank_8";
+		public static final String USER_RANK_9							= "user_rank_9";
+		public static final String USER_RANK_10							= "user_rank_10";
+		public static final String USER_RANK_11							= "user_rank_11";
     }
 	
 	private static final String APPLICATION_TEXT_RESOURCE_FILE = "text/application/application";
diff --git a/core/src/cz/nic/tablexia/menu/main/MainMenuDefinition.java b/core/src/cz/nic/tablexia/menu/main/MainMenuDefinition.java
index 2cc97cd30f293c971aced387a0960cf9bd9db592..a5aba243d575848c60ce176fb9bdfbb538319770 100644
--- a/core/src/cz/nic/tablexia/menu/main/MainMenuDefinition.java
+++ b/core/src/cz/nic/tablexia/menu/main/MainMenuDefinition.java
@@ -19,6 +19,7 @@ import cz.nic.tablexia.menu.game.GameMenuDefinition;
 import cz.nic.tablexia.screen.about.AboutScreen;
 import cz.nic.tablexia.screen.encyclopedia.EncyclopediaScreen;
 import cz.nic.tablexia.screen.halloffame.HallOfFameScreen;
+import cz.nic.tablexia.screen.profile.ProfileScreen;
 import cz.nic.tablexia.screen.statistics.StatisticsScreen;
 import cz.nic.tablexia.screen.viewport.ViewportDebugScreen;
 
@@ -32,11 +33,12 @@ public enum MainMenuDefinition implements IMenuItem {
 			ApplicationBus.getInstance().post(new SubMenuControlEvent(MainMenu.class, this, SubMenuControlEvent.SubMenuAction.TOGGLE)).asynchronously();
 		}
 	},
-	HALL_OF_FAME		(false, new String[]{ApplicationAtlasManager.MAINMENU_ICON_HALLOFFAME_UNPRESSED, ApplicationAtlasManager.MAINMENU_ICON_HALLOFFAME_PRESSED}, ApplicationTextManager.ApplicationTextsAssets.MAINMENU_HALLOFFAME, null, AbstractMenu.MenuAction.CLOSE, new Tablexia.ChangeScreenEvent(HallOfFameScreen.class,     TablexiaApplication.ScreenTransaction.FADE)),
-	STATISTICS			(false, new String[]{ApplicationAtlasManager.MAINMENU_ICON_STATISTICS_UNPRESSED, ApplicationAtlasManager.MAINMENU_ICON_STATISTICS_PRESSED}, ApplicationTextManager.ApplicationTextsAssets.MAINMENU_STATISTICS, null, AbstractMenu.MenuAction.CLOSE, new Tablexia.ChangeScreenEvent(StatisticsScreen.class,     TablexiaApplication.ScreenTransaction.FADE)),
-	ENCYCLOPEDIA		(false, new String[]{ApplicationAtlasManager.MAINMENU_ICON_ENCYCLOPEDIA_UNPRESSED, ApplicationAtlasManager.MAINMENU_ICON_ENCYCLOPEDIA_PRESSED}, ApplicationTextManager.ApplicationTextsAssets.MAINMENU_ENCYCLOPEDIA, null, AbstractMenu.MenuAction.CLOSE, new Tablexia.ChangeScreenEvent(EncyclopediaScreen.class,   TablexiaApplication.ScreenTransaction.FADE)),
-	ABOUT_APPLICATION	(false, new String[]{ApplicationAtlasManager.MAINMENU_ICON_ABOUT_UNPRESSED, ApplicationAtlasManager.MAINMENU_ICON_ABOUT_PRESSED}, ApplicationTextManager.ApplicationTextsAssets.MAINMENU_ABOUT, null, AbstractMenu.MenuAction.CLOSE, new Tablexia.ChangeScreenEvent(AboutScreen.class,          TablexiaApplication.ScreenTransaction.FADE)),
-	LOGOUT				(false, new String[]{ApplicationAtlasManager.MAINMENU_ICON_LOGOUT_UNPRESSED, ApplicationAtlasManager.MAINMENU_ICON_LOGOUT_PRESSED}, ApplicationTextManager.ApplicationTextsAssets.MAINMENU_LOGOUT, null, AbstractMenu.MenuAction.CLOSE,  null) {
+	HALL_OF_FAME		(false, new String[]{ApplicationAtlasManager.MAINMENU_ICON_HALLOFFAME_UNPRESSED,    ApplicationAtlasManager.MAINMENU_ICON_HALLOFFAME_PRESSED},      ApplicationTextManager.ApplicationTextsAssets.MAINMENU_HALLOFFAME,      null, AbstractMenu.MenuAction.CLOSE,    new Tablexia.ChangeScreenEvent(HallOfFameScreen.class,      TablexiaApplication.ScreenTransaction.FADE)),
+	STATISTICS			(false, new String[]{ApplicationAtlasManager.MAINMENU_ICON_STATISTICS_UNPRESSED,    ApplicationAtlasManager.MAINMENU_ICON_STATISTICS_PRESSED},      ApplicationTextManager.ApplicationTextsAssets.MAINMENU_STATISTICS,      null, AbstractMenu.MenuAction.CLOSE,    new Tablexia.ChangeScreenEvent(StatisticsScreen.class,      TablexiaApplication.ScreenTransaction.FADE)),
+	ENCYCLOPEDIA		(false, new String[]{ApplicationAtlasManager.MAINMENU_ICON_ENCYCLOPEDIA_UNPRESSED,  ApplicationAtlasManager.MAINMENU_ICON_ENCYCLOPEDIA_PRESSED},    ApplicationTextManager.ApplicationTextsAssets.MAINMENU_ENCYCLOPEDIA,    null, AbstractMenu.MenuAction.CLOSE,    new Tablexia.ChangeScreenEvent(EncyclopediaScreen.class,    TablexiaApplication.ScreenTransaction.FADE)),
+	ABOUT_APPLICATION	(false, new String[]{ApplicationAtlasManager.MAINMENU_ICON_ABOUT_UNPRESSED,         ApplicationAtlasManager.MAINMENU_ICON_ABOUT_PRESSED},           ApplicationTextManager.ApplicationTextsAssets.MAINMENU_ABOUT,           null, AbstractMenu.MenuAction.CLOSE,    new Tablexia.ChangeScreenEvent(AboutScreen.class,           TablexiaApplication.ScreenTransaction.FADE)),
+	PROFILE				(false, new String[]{ApplicationAtlasManager.MAINMENU_ICON_PROFILE_UNPRESSED,       ApplicationAtlasManager.MAINMENU_ICON_PROFILE_PRESSED},         ApplicationTextManager.ApplicationTextsAssets.MAINMENU_PROFILE,         null, AbstractMenu.MenuAction.CLOSE,    new Tablexia.ChangeScreenEvent(ProfileScreen.class,         TablexiaApplication.ScreenTransaction.FADE)),
+	LOGOUT				(false, new String[]{ApplicationAtlasManager.MAINMENU_ICON_LOGOUT_UNPRESSED,        ApplicationAtlasManager.MAINMENU_ICON_LOGOUT_PRESSED},          ApplicationTextManager.ApplicationTextsAssets.MAINMENU_LOGOUT,          null, AbstractMenu.MenuAction.CLOSE,    null) {
 
 		@Override
 		public void performAction() {
diff --git a/core/src/cz/nic/tablexia/menu/main/user/UserSelectBox.java b/core/src/cz/nic/tablexia/menu/main/user/UserSelectBox.java
index 193420267bd8d68534bbd6a5a093657fb36fb9fe..20e3198898d50340983342605dfc8c0706a9045a 100644
--- a/core/src/cz/nic/tablexia/menu/main/user/UserSelectBox.java
+++ b/core/src/cz/nic/tablexia/menu/main/user/UserSelectBox.java
@@ -15,6 +15,7 @@ import cz.nic.tablexia.Tablexia;
 import cz.nic.tablexia.TablexiaApplication;
 import cz.nic.tablexia.TablexiaSettings;
 import cz.nic.tablexia.bus.ApplicationBus;
+import cz.nic.tablexia.game.ranksystem.UserRankManager;
 import cz.nic.tablexia.loader.application.ApplicationAtlasManager;
 import cz.nic.tablexia.menu.user.UserMenuItem;
 import cz.nic.tablexia.menu.user.UserMenuNewSelectBoxItemGroup;
@@ -141,6 +142,9 @@ public class UserSelectBox extends AbstractTablexiaSelectBox<UserSelectBox.UserS
                 if(item.getUser() == null) { //Creating new user...
                     ApplicationBus.getInstance().post(new Tablexia.ChangeScreenEvent(PanoramaScreen.class, TablexiaApplication.ScreenTransaction.FADE)).asynchronously();
                 }
+                else {
+                    UserRankManager.getInstance().forceRefreshUserRank(item.getUser());
+                }
             }
         });
 
diff --git a/core/src/cz/nic/tablexia/menu/user/UserMenuSelectBoxItemGroup.java b/core/src/cz/nic/tablexia/menu/user/UserMenuSelectBoxItemGroup.java
index a3a5bff0fd815564ebe4229fb64c9c241a8e9cd0..33993cabd6a992cbb25d77f60a44434a36d1c516 100644
--- a/core/src/cz/nic/tablexia/menu/user/UserMenuSelectBoxItemGroup.java
+++ b/core/src/cz/nic/tablexia/menu/user/UserMenuSelectBoxItemGroup.java
@@ -9,11 +9,16 @@ import com.badlogic.gdx.scenes.scene2d.Group;
 import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
 import com.badlogic.gdx.utils.Align;
 
+import net.engio.mbassy.listener.Handler;
+
+import cz.nic.tablexia.bus.ApplicationBus;
+import cz.nic.tablexia.game.ranksystem.UserRankManager;
 import cz.nic.tablexia.loader.application.ApplicationAtlasManager;
 import cz.nic.tablexia.loader.application.ApplicationFontManager;
 import cz.nic.tablexia.menu.IMenuItem;
 import cz.nic.tablexia.menu.main.user.UserSelectBox;
 import cz.nic.tablexia.shared.model.User;
+import cz.nic.tablexia.util.Log;
 import cz.nic.tablexia.util.ui.TablexiaLabel;
 
 /**
@@ -25,6 +30,8 @@ public class UserMenuSelectBoxItemGroup extends Group implements UserSelectBox.U
     private static final int                                    TEXT_LEFT_OFFSET            = 20;
     private static final int                                    IMAGE_BORDER_OFFSET         = 4;
     private static final int                                    IMAGE_WIDTH_OFFSET          = 10;
+    private static final float                                  BADGE_ICON_HEIGHT           = 0.42f;
+    private static final float                                  BADGE_ICON_OFFSET_X         = -0.75f;
     private static final Color                                  FOREGROUND_COLOR            = new Color(0.322f, 0.278f, 0.255f, 1f);
     private static final int                                    MAX_VISIBLE_TITLE_WIDTH     = 150;
     private static final String                                 THREE_DOTS                  = "\u2026";
@@ -34,6 +41,9 @@ public class UserMenuSelectBoxItemGroup extends Group implements UserSelectBox.U
     private final TextureRegionDrawable image;
     private final UserMenuItem          userMenuItem;
     private final String                visibleName;
+    private       boolean               showBadge = false;
+
+    private       TextureRegionDrawable badgeIcon;
 
     private TablexiaLabel textLabel;
 
@@ -45,6 +55,7 @@ public class UserMenuSelectBoxItemGroup extends Group implements UserSelectBox.U
         visibleName = userMenuItem.getTitle().length() <= MIN_VISIBLE_TITLE_LENGTH ? userMenuItem.getTitle() : getVisibleTitle(userMenuItem.getTitle());
         textLabel   = new TablexiaLabel("", new TablexiaLabel.TablexiaLabelStyle(TEXT_FONT, FOREGROUND_COLOR));
         textLabel.setAlignment(Align.left);
+        setShowBadge(true);
     }
 
     public void performAction() {
@@ -55,6 +66,36 @@ public class UserMenuSelectBoxItemGroup extends Group implements UserSelectBox.U
         return userMenuItem.getUser();
     }
 
+    public void setShowBadge(boolean showBadge) {
+        this.showBadge = showBadge;
+        onShowBadgeSet();
+    }
+
+    private void onShowBadgeSet() {
+        if(isShowBadge()) {
+            ApplicationBus.getInstance().subscribe(this);
+            updateBadgeIcon();
+        }
+        else {
+            ApplicationBus.getInstance().unsubscribe(this);
+            badgeIcon = null;
+        }
+    }
+
+    private void updateBadgeIcon() {
+        if(!UserRankManager.getInstance().getRank(getUser()).isShownOnUserMenu())
+            return;
+
+        if (badgeIcon == null)
+            badgeIcon = new TextureRegionDrawable();
+
+        badgeIcon.setRegion(ApplicationAtlasManager.getInstance().getTextureRegion(UserRankManager.getInstance().getRank(getUser()).getBadgeIconKey()));
+    }
+
+    public boolean isShowBadge() {
+        return showBadge;
+    }
+
     @Override
     public void draw(Batch batch, float parentAlpha) {
         FOREGROUND_COLOR.a = parentAlpha;
@@ -65,9 +106,21 @@ public class UserMenuSelectBoxItemGroup extends Group implements UserSelectBox.U
         float imageWidth = getHeight();
         image.draw(batch, getX() + IMAGE_BORDER_OFFSET, getY() + IMAGE_BORDER_OFFSET, imageWidth - IMAGE_BORDER_OFFSET * 2 - IMAGE_WIDTH_OFFSET, getHeight() - IMAGE_BORDER_OFFSET * 2 );
 
+        if(badgeIcon != null) {
+            float badgeIconHeight = BADGE_ICON_HEIGHT * getHeight();
+            float badgeIconWidth  = badgeIconHeight * (badgeIcon.getRegion().getRegionWidth() / (float) badgeIcon.getRegion().getRegionHeight());
+
+            badgeIcon.draw(
+                    batch,
+                    getX() + imageWidth - IMAGE_BORDER_OFFSET - IMAGE_WIDTH_OFFSET + (badgeIconWidth * BADGE_ICON_OFFSET_X),
+                    getY() + IMAGE_BORDER_OFFSET,
+                    badgeIconWidth,
+                    badgeIconHeight
+            );
+        }
+
         float textPositionXOffset = imageWidth + TEXT_LEFT_OFFSET;
         float textPositionX = getX() + textPositionXOffset;
-        float textPositionY = getY() + getHeight() / 2;
 
         textLabel.setText(visibleName);
         textLabel.setBounds(textPositionX, getY(), getWidth() - textPositionXOffset, getHeight());
@@ -92,4 +145,13 @@ public class UserMenuSelectBoxItemGroup extends Group implements UserSelectBox.U
         }
         return visibleTitle;
     }
-}
+
+    @Handler
+    public void onUserRankUpEvent(UserRankManager.UserRankUpEvent userRankUpEvent) {
+        if(!userRankUpEvent.getUser().equals(getUser())) {
+            return;
+        }
+
+        updateBadgeIcon();
+    }
+}
\ No newline at end of file
diff --git a/core/src/cz/nic/tablexia/model/game/GameDAO.java b/core/src/cz/nic/tablexia/model/game/GameDAO.java
index 375adb48756f1c4fb1edcff1f1401af3f21869dc..3f4ca57b15e8f1f2a3a51a8e1983128802a253e9 100644
--- a/core/src/cz/nic/tablexia/model/game/GameDAO.java
+++ b/core/src/cz/nic/tablexia/model/game/GameDAO.java
@@ -8,6 +8,7 @@ import java.sql.SQLException;
 import java.sql.Statement;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import cz.nic.tablexia.TablexiaSettings;
 import cz.nic.tablexia.TablexiaStorage;
@@ -28,6 +29,7 @@ import cz.nic.tablexia.util.Log;
 public class GameDAO {
 
     private static final Object ATOMIC_LOCK = new Object();
+    private static final AtomicInteger gameScoreSetCounter = new AtomicInteger(0);
 
 //////////////////////////// Game API
 
@@ -57,6 +59,10 @@ public class GameDAO {
         game.setStartTime(gameUpdateStart(game.getId(), TimeUtils.millis()));
     }
 
+    public static void startGame(Game game, long startTime) {
+        game.setStartTime(gameUpdateStart(game.getId(), startTime));
+    }
+
     public static void endGame(Game game) {
         game.setEndTime(gameUpdateEnd(game.getId(), TimeUtils.millis()));
     }
@@ -95,6 +101,7 @@ public class GameDAO {
 	}
 
     public static void setGameScore(final Game game, final String key, final String value) {
+        gameScoreSetCounter.getAndIncrement();
         new Thread(new Runnable() {
             @Override
             public void run() {
@@ -109,11 +116,20 @@ public class GameDAO {
                             storedScore.setValue(value);
                         }
                     }
+                    gameScoreSetCounter.getAndDecrement();
                 }
             }
         }).start();
     }
 
+    /**
+     * Is there any background thread setting up game score values ?
+     * @return
+     */
+    public static boolean isGameScoreActual() {
+        return gameScoreSetCounter.get() == 0;
+    }
+
     public static AbstractTablexiaGame.GameResult getGameResult(Game game) {
         return GameDefinition.getGameDefinitionForGameNumber(game.getGameNumber()).getGameResultResolver().getGameCupsResult(game);
     }
@@ -143,6 +159,7 @@ public class GameDAO {
     public static final String GAME_SELECT_ALL_FOR_USER_SYNC = "SELECT id, user_id, difficulty_number, game_number, random_seed, start_time, end_time FROM game where user_id = ? AND sync_at is null";
     public static final String GAME_SELECT_BY_START_AND_END = "SELECT id FROM game WHERE user_id = ? AND start_time = ? AND end_time = ?";
     public static final String GAME_SELECT_LAST_SCORES_FOR_USER_AND_GAME = "SELECT value FROM game_score INNER JOIN game ON game_score.game_id=game.id AND game.user_id=? AND game.game_number=? WHERE game_score.key=? AND end_time IS NOT NULL ORDER BY game_id DESC LIMIT 1";
+    public static final String GAME_SELECT_FOR_RANK_MANAGER = "SELECT id, difficulty_number, game_number, start_time, end_time FROM game WHERE user_id = ? AND end_time IS NOT NULL AND end_time != 0 ORDER BY end_time ASC";
 
     // classic statements
     public static final String IMPORT_GAME_INSERT = "INSERT INTO game (user_id, difficulty_number, game_number, random_seed, start_time, end_time, sync_at) VALUES (%d, %d, %d, %d, %d, %d, %d)";
@@ -286,6 +303,51 @@ public class GameDAO {
         return games;
     }
 
+    public static List<Game> selectUserGamesForRankManager(long userId) {
+        List<Game> games = new ArrayList<Game>();
+        try {
+            PreparedStatement statement = TablexiaStorage.getInstance().prepareStatement(GAME_SELECT_FOR_RANK_MANAGER);
+            statement.setLong(1, userId);
+            try {
+
+                ResultSet resultSet = statement.executeQuery();
+                while (resultSet.next()) {
+                    long id  = resultSet.getLong(1);
+                    int diff = resultSet.getInt(2);
+                    int gameNum = resultSet.getInt(3);
+                    String startTime = resultSet.getString(4);
+                    String endTime   = resultSet.getString(5);
+
+                    Long startTimeLong = startTime != null ? Long.valueOf(startTime) : null;
+                    Long endTimeLong   = endTime   != null ? Long.valueOf(endTime)   : null;
+
+                    if(startTime == null || endTime == null) continue; //only game that were finished
+
+                    Game game = new Game(
+                        id,
+                        UserDAO.selectUser(userId),
+                        diff,
+                        gameNum,
+                        0L,
+                        startTimeLong,
+                        endTimeLong
+                    );
+
+                    game.setGamePauses(GamePauseDAO.selectGamePausesForGame(game));
+                    game.getGameScoreMap().addAll(GameScoreDAO.selectGameScores(game.getId()));
+                    games.add(game);
+                }
+                resultSet.close();
+            } catch (SQLException e) {
+                Log.err(User.class, "Cannot select games for user_id: " + userId, e);
+            }
+            statement.close();
+        } catch (SQLException e) {
+            Log.err(User.class, "Cannot select games for user_id: " + userId, e);
+        }
+        return games;
+    }
+
     private static List<Game> selectGamesForUserAndDefinition(long userId, GameDefinition definition) {
 
         List<Game> selectedGames = new ArrayList<Game>();
diff --git a/core/src/cz/nic/tablexia/model/screen/ScreenDAO.java b/core/src/cz/nic/tablexia/model/screen/ScreenDAO.java
index 5dbe47560ff2d055d7271d849302c76041b36c07..c432ed3bb1c8989f6082fa80be23f80592a843cd 100644
--- a/core/src/cz/nic/tablexia/model/screen/ScreenDAO.java
+++ b/core/src/cz/nic/tablexia/model/screen/ScreenDAO.java
@@ -21,6 +21,7 @@ public class ScreenDAO {
     public static final String SCREEN_SELECT = "SELECT time FROM screen WHERE user_id = ? AND screen_name = ?";
     public static final String SCREEN_SELECT_ALL_FOR_SYNC = "SELECT * FROM screen WHERE user_id = ? AND sync_at IS NULL";
     public static final String SCREEN_UPDATE_SYNC_AT = "UPDATE screen SET sync_at = ? WHERE id = ?";
+    public static final String SCREEN_LAST_VISIT = "SELECT max(time) FROM screen WHERE user_id = ? AND screen_name = ?";
 
 
     /////API
@@ -32,6 +33,32 @@ public class ScreenDAO {
         insertScreen(userId, screenName, time);
     }
 
+    public static long getScreenLastVisitTime(long userId, String screenName) {
+        long result = 0;
+
+        try {
+            PreparedStatement statement = TablexiaStorage.getInstance().prepareStatement(SCREEN_LAST_VISIT);
+            statement.setLong(1, userId);
+            statement.setString(2, screenName);
+
+            try {
+                ResultSet resultSet = statement.executeQuery();
+                if(resultSet.next()) {
+                    result = resultSet.getLong(1);
+                }
+                resultSet.close();
+            } catch (SQLException e) {
+                Log.err(ScreenDAO.class, "Cannot select time from DB!", e);
+            }
+            statement.close();
+
+        } catch (SQLException e) {
+            e.printStackTrace();
+        }
+
+        return result;
+    }
+
     ////DB ACCESS
     public static int selectScreenCount(long userId, String screenName) {
         int screenCount = 0;
diff --git a/core/src/cz/nic/tablexia/screen/AbstractTablexiaScreen.java b/core/src/cz/nic/tablexia/screen/AbstractTablexiaScreen.java
index c84fc188ed1ca3225c14fd217e940762c1c6f559..0a78c0ecf882587b77066491f168dff1f16ea8f0 100644
--- a/core/src/cz/nic/tablexia/screen/AbstractTablexiaScreen.java
+++ b/core/src/cz/nic/tablexia/screen/AbstractTablexiaScreen.java
@@ -8,7 +8,6 @@ import com.badlogic.gdx.audio.Sound;
 import com.badlogic.gdx.files.FileHandle;
 import com.badlogic.gdx.graphics.Color;
 import com.badlogic.gdx.graphics.g2d.Animation;
-import com.badlogic.gdx.graphics.g2d.BitmapFont;
 import com.badlogic.gdx.graphics.g2d.NinePatch;
 import com.badlogic.gdx.graphics.g2d.TextureRegion;
 import com.badlogic.gdx.scenes.scene2d.Action;
@@ -749,6 +748,10 @@ public abstract class AbstractTablexiaScreen<T> extends ScreenAdapter {
 		}
 	}
 
+    public boolean hasSoftBackButton() {
+        return TablexiaSettings.getInstance().hasSoftBackButton();
+    }
+
 //////////////////////////// ASSETS ACCESS
 
     public Animation getAnimationForAtlas(String atlasName, String regionName, int framesCount, float frameDuration) {
diff --git a/core/src/cz/nic/tablexia/screen/about/AboutScreen.java b/core/src/cz/nic/tablexia/screen/about/AboutScreen.java
index d850e808bae899538abddfe69564774031c1441f..78849cc96a6bd23e506f0531a0842f8ef6d7b9e8 100644
--- a/core/src/cz/nic/tablexia/screen/about/AboutScreen.java
+++ b/core/src/cz/nic/tablexia/screen/about/AboutScreen.java
@@ -23,14 +23,12 @@ import cz.nic.tablexia.screen.AbstractTablexiaScreen;
 import cz.nic.tablexia.screen.about.assets.AboutAssets;
 import cz.nic.tablexia.util.ui.ClickListenerWithSound;
 import cz.nic.tablexia.util.ui.TablexiaLabel;
-import cz.nic.tablexia.util.ui.button.CloseTablexiaButton;
 import cz.nic.tablexia.util.ui.button.TablexiaButton;
 
 public class AboutScreen extends AbstractTablexiaScreen<Void> {
     private static final Color   DEFAULT_FONT_COLOR       = TablexiaSettings.getDefaultFontColor();
     private static final Color   DEFAULT_BACKGROUND_COLOR = TablexiaSettings.getDefaultBackgroundColor();
     private static final Color   DEFAULT_LINK_COLOR       = new Color(0.27f, 0.53f, 0.8f,1);
-    private static final boolean SHOW_BOUNDING_BOXES      = TablexiaSettings.getInstance().isShowBoundingBoxes();
 
     private static final float CONTENT_RELATIVE_WIDTH   = 0.9f;
     private static final float CONTENT_RELATIVE_HEIGHT  = 0.85f;
@@ -40,8 +38,6 @@ public class AboutScreen extends AbstractTablexiaScreen<Void> {
     private static final int   CONTENT_PAD              = 10;
     private static final int   SMALL_PAD                = 5;
     private static final int   BIG_PAD                  = 20;
-    private static final int   CLOSE_BUTTON_PAD_BOTTOM  = 10;
-    private static final int   CLOSE_BUTTON_PAD_LEFT    = 10;
 
     private static final int DEFAULT_FONT_PAD  = 5;
     private static final int BIG_FONT_PAD      = 10;
@@ -63,6 +59,10 @@ public class AboutScreen extends AbstractTablexiaScreen<Void> {
 
     private LabelClickListener labelClickListener;
 
+    @Override
+    public boolean hasSoftBackButton() {
+        return true;
+    }
 
     @Override
     protected Viewport createViewport() {
@@ -100,30 +100,17 @@ public class AboutScreen extends AbstractTablexiaScreen<Void> {
         contentHeight = CONTENT_RELATIVE_HEIGHT * getViewportHeight();
 
         content = new Table();
-//        content.setDebug(SHOW_BOUNDING_BOXES);
         content.setSize(contentWidth, contentHeight);
         labelClickListener = new LabelClickListener();
 
         prepareContent();
 
-        TablexiaButton closeButton = new CloseTablexiaButton()
-                .setInputListener(new ClickListener() {
-                    @Override
-                    public void clicked(InputEvent event, float x, float y) {
-                        super.clicked(event, x, y);
-                        backToInitialScreen();
-                    }
-                });
-
         contentScrollPane = new ScrollPane(content);
         contentScrollPane.setScrollingDisabled(true, false);
         contentScrollPane.setFillParent(true);
 
         contentStack.setFillParent(true);
         contentStack.align(Align.bottomLeft);
-        contentStack.setActor(closeButton);
-        contentStack.padLeft(CLOSE_BUTTON_PAD_LEFT);
-        contentStack.padBottom(CLOSE_BUTTON_PAD_BOTTOM);
 
         getStage().addActor(backgroundTable);
         getStage().addActor(contentScrollPane);
diff --git a/core/src/cz/nic/tablexia/screen/createuser/FormScreen.java b/core/src/cz/nic/tablexia/screen/createuser/FormScreen.java
index 41b5287cb611917dfeaa4d59499edbf116092142..58887265a7cfae5f39bc9ad55491eff719e14c93 100644
--- a/core/src/cz/nic/tablexia/screen/createuser/FormScreen.java
+++ b/core/src/cz/nic/tablexia/screen/createuser/FormScreen.java
@@ -43,6 +43,7 @@ import cz.nic.tablexia.TablexiaApplication;
 import cz.nic.tablexia.TablexiaSettings;
 import cz.nic.tablexia.bus.ApplicationBus;
 import cz.nic.tablexia.bus.event.StartFullSynchronizationEvent;
+import cz.nic.tablexia.game.ranksystem.UserRankManager;
 import cz.nic.tablexia.loader.application.ApplicationAtlasManager;
 import cz.nic.tablexia.loader.application.ApplicationFontManager;
 import cz.nic.tablexia.menu.user.UserAvatarDefinition;
@@ -67,6 +68,7 @@ import cz.nic.tablexia.util.ui.dialog.TablexiaComponentDialogFactory;
 import cz.nic.tablexia.util.ui.dialog.components.AdaptiveSizeDialogComponent;
 import cz.nic.tablexia.util.ui.dialog.components.CenterPositionDialogComponent;
 import cz.nic.tablexia.util.ui.dialog.components.DimmerDialogComponent;
+import cz.nic.tablexia.util.ui.dialog.components.DividerContentDialogComponent;
 import cz.nic.tablexia.util.ui.dialog.components.FixedSpaceContentDialogComponent;
 import cz.nic.tablexia.util.ui.dialog.components.ResizableSpaceContentDialogComponent;
 import cz.nic.tablexia.util.ui.dialog.components.SpeechDialogComponent;
@@ -79,17 +81,10 @@ import cz.nic.tablexia.util.ui.dialog.components.ViewportMaximumSizeComponent;
 public class FormScreen extends AbstractTablexiaScreen<Void> {
     //TODO - Get rid of all magic values and strings in the code (Use constants)
 
-    private static final String                             CREATEUSER_FORM_AGE_TEXT_KEY    = "createuser_form_age";
-    private static final String                             CREATEUSER_FORM_GENDER_TEXT_KEY = "createuser_form_gender";
-    private static final String                             VALIDATION_MUGSHOT_SOUND        = "mfx/profil_foto.mp3";
-    private static final String                             VALIDATION_USERNAME_SOUND       = "mfx/profil_jmeno.mp3";
-    private static final String                             VALIDATION_SIGNATURE_SOUND      = "mfx/profil_podpis_pero.mp3";
-    private static final String                             VALIDATION_GENDER_SOUND         = "mfx/profil_klukholka.mp3";
-    private static final String                             VALIDATION_AGE_SOUND            = "mfx/profil_vek.mp3";
-    private static final String                             VALIDATION_STAMP_SOUND          = "mfx/profil_razitko.mp3";
-    private static final Color                              TEXT_COLOR                      = Color.BLACK;
+    private static final Color                                  TEXT_COLOR                      = Color.BLACK;
     private static final ApplicationFontManager.FontType_NEW    TEXT_14                         = ApplicationFontManager.FontType_NEW.REGULAR_14;
     private static final ApplicationFontManager.FontType_NEW    TEXT_20                         = ApplicationFontManager.FontType_NEW.REGULAR_20;
+    private static final ApplicationFontManager.FontType_NEW    TEXT_26                         = ApplicationFontManager.FontType_NEW.REGULAR_26;
 
     private static final int    DEFAULT_USER_AGE                = 10;
     private static final int    MAX_USER_AGE                    = 99;
@@ -108,10 +103,6 @@ public class FormScreen extends AbstractTablexiaScreen<Void> {
 
     private static final int    TEXT_FIELD_HINT_DELAY           = 5000;
 
-    public static final  String GFX_PATH            = "gfx/";
-    public static final  String AVATAR_PATH         = GFX_PATH + "avatar/";
-    public static final  String HINT_FINGER_SOUND   = "mfx/profil_podpis_prst.mp3";
-
     protected Actor pen, mugshotFrame, stamp, inkpad, ink;
     protected Image stampPlaceholder, mugshotImage, badge, book;
     protected Actor buttonPlus, buttonMinus;
@@ -150,24 +141,23 @@ public class FormScreen extends AbstractTablexiaScreen<Void> {
         validations = new HashMap<FormValidationEnum, Boolean>();
         alreadyPlayedHints = new HashSet<String>();
 
-        Image background = new TablexiaNoBlendingImage(getScreenTextureRegion(GFX_PATH + "table"));
+        Image background = new TablexiaNoBlendingImage(getScreenTextureRegion(FormScreenAssets.TABLE));
         ScaleUtil.setBackgroundBounds(background);
         group.addActor(background);
 
         Image coverName;
 
-        group.addActor(book = ScaleUtil.createImageSizePosition(getScreenTextureRegion(GFX_PATH + "background"), getStage().getWidth() * FormActorsLayout.BACKGROUND_WIDTH, TablexiaSettings.getMinWorldHeight() * FormActorsLayout.BACKGROUND_HEIGHT, getStage().getWidth() * FormActorsLayout.BACKGROUND_X, 0));
-        group.addActor(inkpad = ScaleUtil.createImageWidthPosition(getScreenTextureRegion(GFX_PATH + "inkpad"), getStage().getWidth() * FormActorsLayout.INK_PAD_WIDTH, getStage().getWidth() * FormActorsLayout.INK_PAD_X, getStage().getWidth() * FormActorsLayout.INK_PAD_Y));
-        group.addActor(badge = ScaleUtil.createImageWidthPosition(getScreenTextureRegion(GFX_PATH + "badge"), getStage().getWidth() * FormActorsLayout.BADGE_WIDTH, getStage().getWidth() * FormActorsLayout.BADGE_X, getStage().getWidth() * FormActorsLayout.BADGE_Y));
+        group.addActor(book = ScaleUtil.createImageSizePosition(getScreenTextureRegion(FormScreenAssets.BACKGROUND), getStage().getWidth() * FormActorsLayout.BACKGROUND_WIDTH, TablexiaSettings.getMinWorldHeight() * FormActorsLayout.BACKGROUND_HEIGHT, getStage().getWidth() * FormActorsLayout.BACKGROUND_X, 0));
+        group.addActor(inkpad = ScaleUtil.createImageWidthPosition(getScreenTextureRegion(FormScreenAssets.INKPAD), getStage().getWidth() * FormActorsLayout.INK_PAD_WIDTH, getStage().getWidth() * FormActorsLayout.INK_PAD_X, getStage().getWidth() * FormActorsLayout.INK_PAD_Y));
         group.addActor(mugshotImage = ScaleUtil.createImageWidthPosition(getApplicationTextureRegion(ApplicationAtlasManager.USERMENU_MENUITEM_AVATAR_0), getStage().getWidth() * FormActorsLayout.MUGSHOT_IMAGE_WIDTH, getStage().getWidth() * FormActorsLayout.MUGSHOT_IMAGE_X, getStage().getWidth() * FormActorsLayout.MUGSHOT_IMAGE_Y)); // size for all mugshots
-        group.addActor(mugshotFrame = ScaleUtil.createImageWidthPosition(getScreenTextureRegion(GFX_PATH + "mugshotframe"), getStage().getWidth() * FormActorsLayout.MUGSHOT_FRAME_WIDTH, getStage().getWidth() * FormActorsLayout.MUGSHOT_FRAME_X, getStage().getWidth() * FormActorsLayout.MUGSHOT_FRAME_Y));
-        group.addActor(coverName = ScaleUtil.createImageWidthPosition(getScreenTextureRegion(GFX_PATH + "textfield_covername"), getStage().getWidth() * FormActorsLayout.COVER_NAME_WIDTH, getStage().getWidth() * FormActorsLayout.COVER_NAME_X, getStage().getWidth() * FormActorsLayout.COVER_NAME_Y));
-        group.addActor(stampPlaceholder = ScaleUtil.createImageWidthPosition(getScreenTextureRegion(GFX_PATH + "stampplaceholder"), getStage().getWidth() * FormActorsLayout.STAMP_PLACEHOLDER_WIDTH, getStage().getWidth() * FormActorsLayout.STAMP_PLACEHOLDER_X, getStage().getWidth() * FormActorsLayout.STAMP_PLACEHOLDER_Y));
-        group.addActor(signaturePlace = ScaleUtil.createImageWidthPosition(getScreenTextureRegion(GFX_PATH + "texfield_signature"), getStage().getWidth() * FormActorsLayout.SIGNATURE_PLACE_WIDTH, getStage().getWidth() * FormActorsLayout.SIGNATURE_PLACE_X, getStage().getWidth() * FormActorsLayout.SIGNATURE_PLACE_Y));
-        group.addActor(ink = ScaleUtil.createImageWidthPosition(getScreenTextureRegion(GFX_PATH + "ink"), getStage().getWidth() * FormActorsLayout.INK_WIDTH, getStage().getWidth() * FormActorsLayout.INK_X, getStage().getHeight() / 2));
+        group.addActor(mugshotFrame = ScaleUtil.createImageWidthPosition(getScreenTextureRegion(FormScreenAssets.MUGSHOT_FRAME), getStage().getWidth() * FormActorsLayout.MUGSHOT_FRAME_WIDTH, getStage().getWidth() * FormActorsLayout.MUGSHOT_FRAME_X, getStage().getWidth() * FormActorsLayout.MUGSHOT_FRAME_Y));
+        group.addActor(coverName = ScaleUtil.createImageWidthPosition(getScreenTextureRegion(FormScreenAssets.TEXTFIELD_COVERNAME), getStage().getWidth() * FormActorsLayout.COVER_NAME_WIDTH, getStage().getWidth() * FormActorsLayout.COVER_NAME_X, getStage().getWidth() * FormActorsLayout.COVER_NAME_Y));
+        group.addActor(stampPlaceholder = ScaleUtil.createImageWidthPosition(getScreenTextureRegion(FormScreenAssets.STAMP_PLACEHOLDER), getStage().getWidth() * FormActorsLayout.STAMP_PLACEHOLDER_WIDTH, getStage().getWidth() * FormActorsLayout.STAMP_PLACEHOLDER_X, getStage().getWidth() * FormActorsLayout.STAMP_PLACEHOLDER_Y));
+        group.addActor(signaturePlace = ScaleUtil.createImageWidthPosition(getScreenTextureRegion(FormScreenAssets.TEXTFIELD_SIGNATURE), getStage().getWidth() * FormActorsLayout.SIGNATURE_PLACE_WIDTH, getStage().getWidth() * FormActorsLayout.SIGNATURE_PLACE_X, getStage().getWidth() * FormActorsLayout.SIGNATURE_PLACE_Y));
+        group.addActor(ink = ScaleUtil.createImageWidthPosition(getScreenTextureRegion(FormScreenAssets.INK), getStage().getWidth() * FormActorsLayout.INK_WIDTH, getStage().getWidth() * FormActorsLayout.INK_X, getStage().getHeight() / 2));
 
         // button for clearing user cover name
-        clearName = new Image(getScreenTextureRegion(GFX_PATH + "clear"));
+        clearName = new Image(getScreenTextureRegion(FormScreenAssets.CLEAR));
         clearName.setPosition(coverName.getX() + coverName.getWidth() + FormActorsLayout.CLEAR_NAME_BUTTON_PADDING, coverName.getY());
         clearName.setSize(clearName.getWidth() / 2, clearName.getHeight() / 2);
         clearName.addListener(new ClickListener() {
@@ -193,9 +183,9 @@ public class FormScreen extends AbstractTablexiaScreen<Void> {
         TablexiaLabel.TablexiaLabelStyle labelStyleFontSize16 = new TablexiaLabel.TablexiaLabelStyle(TEXT_14, TEXT_COLOR);
         TablexiaLabel.TablexiaLabelStyle labelStyleFontSize20 = new TablexiaLabel.TablexiaLabelStyle(TEXT_20, TEXT_COLOR);
 
-        ageLabel = new TablexiaLabel(getText(CREATEUSER_FORM_AGE_TEXT_KEY), labelStyleFontSize16);
+        ageLabel = new TablexiaLabel(getText(FormScreenAssets.TEXT_FORM_AGE), labelStyleFontSize16);
         ageValue = new TablexiaLabel(String.valueOf(this.age), labelStyleFontSize20);
-        genderLabel = new TablexiaLabel(getText(CREATEUSER_FORM_GENDER_TEXT_KEY), labelStyleFontSize16);
+        genderLabel = new TablexiaLabel(getText(FormScreenAssets.TEXT_FORM_GENDER), labelStyleFontSize16);
 
         nameField = new TextFieldWithPlaceholder("", new TextFieldWithPlaceholder.TablexiaTextFieldStyle(ApplicationFontManager.FontType_NEW.REGULAR_18, TEXT_COLOR, createCursorForTextField(), null, null), getText("createuser_form_username"));
         nameField.setSize(getStage().getWidth() * FormActorsLayout.NAME_FIELD_WIDTH, getStage().getWidth() * FormActorsLayout.NAME_FIELD_HEIGHT);
@@ -237,11 +227,11 @@ public class FormScreen extends AbstractTablexiaScreen<Void> {
         group.addActor(ageValue);
         group.addActor(ageLabel);
         group.addActor(genderLabel);
-        group.addActor(imageFemale = ScaleUtil.createImageWidthPosition(getScreenTextureRegion(GFX_PATH + "sex_female"), getStage().getWidth() * FormActorsLayout.IMAGE_FEMALE_WIDTH, getStage().getWidth() * FormActorsLayout.IMAGE_FEMALE_X, getStage().getWidth() * FormActorsLayout.IMAGE_FEMALE_Y));
-        group.addActor(imageMale = ScaleUtil.createImageWidthPosition(getScreenTextureRegion(GFX_PATH + "sex_male"), getStage().getWidth() * FormActorsLayout.IMAGE_MALE_WIDTH, getStage().getWidth() * FormActorsLayout.IMAGE_MALE_X, getStage().getWidth() * FormActorsLayout.IMAGE_MALE_Y));
-
-        group.addActor(buttonMinus = new Button(new TextureRegionDrawable(getScreenTextureRegion(GFX_PATH + "button_minus")), new TextureRegionDrawable(getScreenTextureRegion(GFX_PATH + "button_minus_pressed"))));
-        group.addActor(buttonPlus = new Button(new TextureRegionDrawable(getScreenTextureRegion(GFX_PATH + "button_plus")), new TextureRegionDrawable(getScreenTextureRegion(GFX_PATH + "button_plus_pressed"))));
+        group.addActor(imageFemale = ScaleUtil.createImageWidthPosition(getScreenTextureRegion(FormScreenAssets.SEX_FEMALE), getStage().getWidth() * FormActorsLayout.IMAGE_FEMALE_WIDTH, getStage().getWidth() * FormActorsLayout.IMAGE_FEMALE_X, getStage().getWidth() * FormActorsLayout.IMAGE_FEMALE_Y));
+        group.addActor(imageMale = ScaleUtil.createImageWidthPosition(getScreenTextureRegion(FormScreenAssets.SEX_MALE), getStage().getWidth() * FormActorsLayout.IMAGE_MALE_WIDTH, getStage().getWidth() * FormActorsLayout.IMAGE_MALE_X, getStage().getWidth() * FormActorsLayout.IMAGE_MALE_Y));
+        group.addActor(prepareBadge());
+        group.addActor(buttonMinus = new Button(new TextureRegionDrawable(getScreenTextureRegion(FormScreenAssets.BUTTON_MINUS)), new TextureRegionDrawable(getScreenTextureRegion(FormScreenAssets.BUTTON_MINUS_PRESSED))));
+        group.addActor(buttonPlus = new Button(new TextureRegionDrawable(getScreenTextureRegion(FormScreenAssets.BUTTON_PLUS)), new TextureRegionDrawable(getScreenTextureRegion(FormScreenAssets.BUTTON_PLUS_PRESSED))));
         buttonMinus.setBounds(getStage().getWidth() * FormActorsLayout.BUTTON_MINUS_X, getStage().getWidth() * FormActorsLayout.BUTTON_MINUS_Y, getStage().getWidth() * FormActorsLayout.BUTTON_MINUS_WIDTH, getStage().getWidth() * FormActorsLayout.BUTTON_MINUS_HEIGHT);
         buttonPlus.setBounds(getStage().getWidth() * FormActorsLayout.BUTTON_PLUS_X, getStage().getWidth() * FormActorsLayout.BUTTON_PLUS_Y, getStage().getWidth() * FormActorsLayout.BUTTON_PLUS_WIDTH, getStage().getWidth() * FormActorsLayout.BUTTON_PLUS_HEIGHT);
         buttonPlus.addListener(new ClickListenerWithSound() {
@@ -261,7 +251,8 @@ public class FormScreen extends AbstractTablexiaScreen<Void> {
             }
         });
 
-        switchGender = new Switch(getScreenTextureRegion(GFX_PATH + "switch_background"), getScreenTextureRegion(GFX_PATH + "switch_left"), getScreenTextureRegion(GFX_PATH + "switch_center"), getScreenTextureRegion(GFX_PATH + "switch_right")); // TODO images
+        // TODO images as parameters for Switch's constructor
+        switchGender = new Switch(getScreenTextureRegion(FormScreenAssets.SWITCH_BACKGROUND), getScreenTextureRegion(FormScreenAssets.SWITCH_LEFT), getScreenTextureRegion(FormScreenAssets.SWITCH_CENTER), getScreenTextureRegion(FormScreenAssets.SWITCH_RIGHT));
         switchGender.setPosition(getStage().getWidth() * FormActorsLayout.SWITCH_GENDER_X, getStage().getWidth() * FormActorsLayout.SWITCH_GENDER_Y);
         switchGender.setScale(FormActorsLayout.SWITCH_GENDER_SCALE);
         switchGender.setSwitchSelectedListener(new Switch.DragSwitchListener.SwitchSelectedListener() {
@@ -297,13 +288,13 @@ public class FormScreen extends AbstractTablexiaScreen<Void> {
         // signature pen needs to be below pen and stamp
         signaturePane = new SignaturePane();
         group.addActor(signaturePane);
-        signaturePane.setBounds(getSceneWidth() / 2, getSceneInnerHeight() * FormActorsLayout.SIGNATURE_PANE_Y, getSceneInnerHeight() / 2, getSceneInnerHeight() * FormActorsLayout.SIGNATURE_PANE_HEIGHT);
+        signaturePane.setBounds(getSceneWidth() * FormActorsLayout.SIGNATURE_PANE_X, getSceneInnerHeight() * FormActorsLayout.SIGNATURE_PANE_Y, getSceneWidth() * FormActorsLayout.SIGNATURE_PANE_WIDTH, getSceneInnerHeight() * FormActorsLayout.SIGNATURE_PANE_HEIGHT);
 
         signaturePane.setDebug(TablexiaSettings.getInstance().isShowBoundingBoxes());
 
         // pencil and stamp layers
-        group.addActor(pen = ScaleUtil.createImageWidthPosition(getScreenTextureRegion(GFX_PATH + "pencil_dropped"), getStage().getWidth() * FormActorsLayout.PEN_WIDTH, getStage().getWidth() * FormActorsLayout.PEN_X, getStage().getWidth() * FormActorsLayout.PEN_Y));
-        group.addActor(stamp = ScaleUtil.createImageWidthPosition(getScreenTextureRegion(GFX_PATH + "stamp_left_dropped"), getStage().getWidth() * FormActorsLayout.STAMP_WIDTH, getStage().getWidth() * FormActorsLayout.STAMP_X, getStage().getWidth() * FormActorsLayout.STAMP_Y));
+        group.addActor(pen = ScaleUtil.createImageWidthPosition(getScreenTextureRegion(FormScreenAssets.PENCIL_DROPPED), getStage().getWidth() * FormActorsLayout.PEN_WIDTH, getStage().getWidth() * FormActorsLayout.PEN_X, getStage().getWidth() * FormActorsLayout.PEN_Y));
+        group.addActor(stamp = ScaleUtil.createImageWidthPosition(getScreenTextureRegion(FormScreenAssets.STAMP_LEFT_DROPPED), getStage().getWidth() * FormActorsLayout.STAMP_WIDTH, getStage().getWidth() * FormActorsLayout.STAMP_X, getStage().getWidth() * FormActorsLayout.STAMP_Y));
         pen.addListener(new DragActorListener(pen, true, new DragActorListener.DragListenerAdapter() {
             @Override
             public void onDropped(float x, float y) {
@@ -368,6 +359,11 @@ public class FormScreen extends AbstractTablexiaScreen<Void> {
         validate();
     }
 
+    protected Actor prepareBadge() {
+        badge = ScaleUtil.createImageWidthPosition(ApplicationAtlasManager.getInstance().getTextureRegion(UserRankManager.UserRank.getInitialRank().getBadgeImageKey()), getStage().getWidth() * FormActorsLayout.BADGE_WIDTH, getStage().getWidth() * FormActorsLayout.BADGE_X, getStage().getWidth() * FormActorsLayout.BADGE_Y);
+        return badge;
+    }
+
     private boolean validate() {
 
         if (validationEnabled() == false) {
@@ -379,14 +375,14 @@ public class FormScreen extends AbstractTablexiaScreen<Void> {
 		setValid(FormValidationEnum.MUGSHOT, mugshot != null);
         if (isValid(FormValidationEnum.MUGSHOT) == false) {
             displayHintDialog(FormValidationEnum.MUGSHOT, mugshotImage);
-            playValidationSound(VALIDATION_MUGSHOT_SOUND);
+            playValidationSound(FormScreenAssets.VALIDATION_MUGSHOT_SOUND);
             return false;
         }
 
 		setValid(FormValidationEnum.NAME, nameField.getText() != null && !nameField.getText().isEmpty() && nameField.getText().trim().length() > 0);
         if (isValid(FormValidationEnum.NAME) == false) {
             displayHintDialog(FormValidationEnum.NAME, nameField);
-            playValidationSound(VALIDATION_USERNAME_SOUND);
+            playValidationSound(FormScreenAssets.VALIDATION_USERNAME_SOUND);
             return false;
         }
 
@@ -398,28 +394,28 @@ public class FormScreen extends AbstractTablexiaScreen<Void> {
 
         if (isValid(FormValidationEnum.AGE) == false) {
             displayHintDialog(FormValidationEnum.AGE, ageValue);
-            playValidationSound(VALIDATION_AGE_SOUND);
+            playValidationSound(FormScreenAssets.VALIDATION_AGE_SOUND);
             return false;
         }
 
 		setValid(FormValidationEnum.GENDER, gender != null);
         if (isValid(FormValidationEnum.GENDER) == false) {
             displayHintDialog(FormValidationEnum.GENDER, switchGender);
-            playValidationSound(VALIDATION_GENDER_SOUND);
+            playValidationSound(FormScreenAssets.VALIDATION_GENDER_SOUND);
             return false;
         }
 
 		setValid(FormValidationEnum.SIGNATURE, signature != null);
         if (isValid(FormValidationEnum.SIGNATURE) == false) {
             displayHintDialog(FormValidationEnum.SIGNATURE, signaturePlace);
-            playValidationSound(VALIDATION_SIGNATURE_SOUND);
+            playValidationSound(FormScreenAssets.VALIDATION_SIGNATURE_SOUND);
             pen.addAction(Actions.forever(Actions.sequence(Actions.repeat(SHAKE_ANIMATION_REPEAT_COUNT, Actions.sequence(Actions.moveBy(SHAKE_ANIMATION_OFFSET, 0, SHAKE_ANIMATION_STEP_DURATION), Actions.moveBy(-SHAKE_ANIMATION_OFFSET, 0, SHAKE_ANIMATION_STEP_DURATION))), Actions.delay(1))));
             return false;
         }
 
         if (isValid(FormValidationEnum.STAMP) == false) {
             displayHintDialog(FormValidationEnum.STAMP, stampPlaceholder);
-            playValidationSound(VALIDATION_STAMP_SOUND);
+            playValidationSound(FormScreenAssets.VALIDATION_STAMP_SOUND);
             stamp.addAction(Actions.forever(Actions.sequence(Actions.repeat(SHAKE_ANIMATION_REPEAT_COUNT, Actions.sequence(Actions.moveBy(SHAKE_ANIMATION_OFFSET, 0, SHAKE_ANIMATION_STEP_DURATION), Actions.moveBy(-SHAKE_ANIMATION_OFFSET, 0, SHAKE_ANIMATION_STEP_DURATION))), Actions.delay(1))));
         }
 
@@ -479,7 +475,7 @@ public class FormScreen extends AbstractTablexiaScreen<Void> {
     }
 
     protected void stampIt() {
-        Drawable d = new TextureRegionDrawable(new TextureRegion(getScreenTextureRegion(GFX_PATH + "stamp")));
+        Drawable d = new TextureRegionDrawable(new TextureRegion(getScreenTextureRegion(FormScreenAssets.STAMP)));
         stampPlaceholder.setDrawable(d);
     }
 
@@ -536,15 +532,15 @@ public class FormScreen extends AbstractTablexiaScreen<Void> {
         Image avatar = ScaleUtil.createImageToHeight(getApplicationTextureRegion(UserAvatarDefinition.getAvatar(num)), FormActorsLayout.MUGSHOT_HEIGHT);
         avatar.getDrawable().setMinHeight(FormActorsLayout.MUGSHOT_HEIGHT);
         avatar.getDrawable().setMinWidth(mugshotWidth);
-        Image film = ScaleUtil.createImageToHeight(getScreenTextureRegion(AVATAR_PATH + "film_inside"), FormActorsLayout.MUGSHOT_HEIGHT);
+        Image film = ScaleUtil.createImageToHeight(getScreenTextureRegion(FormScreenAssets.FILM_INSIDE), FormActorsLayout.MUGSHOT_HEIGHT);
         film.getDrawable().setMinHeight(FormActorsLayout.MUGSHOT_HEIGHT);
         film.getDrawable().setMinWidth(mugshotWidth);
 
         VerticalGroup vg = new VerticalGroup();
-        Image frameTop = ScaleUtil.createImageToWidth(getScreenTextureRegion(AVATAR_PATH + "film_outerline"), mugshotWidth);
+        Image frameTop = ScaleUtil.createImageToWidth(getScreenTextureRegion(FormScreenAssets.FILM_OUTERLINE), mugshotWidth);
         frameTop.getDrawable().setMinWidth(mugshotWidth);
         frameTop.getDrawable().setMinHeight(frameTop.getHeight());
-        Image frameBottom = ScaleUtil.createImageToWidth(getScreenTextureRegion(AVATAR_PATH + "film_outerline"), mugshotWidth);
+        Image frameBottom = ScaleUtil.createImageToWidth(getScreenTextureRegion(FormScreenAssets.FILM_OUTERLINE), mugshotWidth);
         frameBottom.getDrawable().setMinWidth(mugshotWidth);
         frameBottom.getDrawable().setMinHeight(frameTop.getHeight());
 
@@ -559,7 +555,6 @@ public class FormScreen extends AbstractTablexiaScreen<Void> {
 
         vg.setHeight(FormActorsLayout.MUGSHOT_HEIGHT + frameBottom.getHeight() + frameTop.getHeight());
         vg.setWidth(mugshotWidth);
-        Log.info(((Object) this).getClass().getName(), "Vertical size " + vg.getWidth() + "x" + vg.getHeight());
 
         return vg;
     }
@@ -578,6 +573,13 @@ public class FormScreen extends AbstractTablexiaScreen<Void> {
         adapters.add(new CenterPositionDialogComponent());
         adapters.add(new DimmerDialogComponent(0.7f));
 
+        //Signature title and spacers...
+        adapters.add(new FixedSpaceContentDialogComponent());
+        adapters.add(new TextContentDialogComponent(getText(FormScreenAssets.TEXT_FORM_SIGNATURE), TEXT_26));
+        adapters.add(new FixedSpaceContentDialogComponent());
+        adapters.add(new DividerContentDialogComponent());
+        adapters.add(new FixedSpaceContentDialogComponent());
+
         //Anonymous signature component
         adapters.add(new TablexiaDialogComponentAdapter() {
             //TODO 4 Desktop - Override sizeChanged?? Resize SignaturePane when resizing the window
@@ -595,8 +597,8 @@ public class FormScreen extends AbstractTablexiaScreen<Void> {
 
         //Two button component (Cancel and Sign button)
         adapters.add(new TwoButtonContentDialogComponent(
-                getText("createuser_form_cancel"),
-                getText("createuser_form_sign"),
+                getText(FormScreenAssets.TEXT_FORM_CANCEL),
+                getText(FormScreenAssets.TEXT_FORM_SIGN),
                 StandardTablexiaButton.TablexiaButtonType.RED,
                 StandardTablexiaButton.TablexiaButtonType.GREEN,
                 new ClickListener() {
diff --git a/core/src/cz/nic/tablexia/screen/createuser/FormScreenAssets.java b/core/src/cz/nic/tablexia/screen/createuser/FormScreenAssets.java
new file mode 100644
index 0000000000000000000000000000000000000000..af10e03169fdc356c1bcd768c97ce0c1071a1b67
--- /dev/null
+++ b/core/src/cz/nic/tablexia/screen/createuser/FormScreenAssets.java
@@ -0,0 +1,58 @@
+package cz.nic.tablexia.screen.createuser;
+
+/**
+ * Created by drahomir on 6/1/16.
+ */
+public class FormScreenAssets {
+    public static final String GFX_PATH            = "gfx/";
+    public static final String AVATAR_PATH         = GFX_PATH + "avatar/";
+
+    public static final String TABLE                = GFX_PATH + "table";
+    public static final String BACKGROUND           = GFX_PATH + "background";
+    public static final String INKPAD               = GFX_PATH + "inkpad";
+    public static final String MUGSHOT_FRAME        = GFX_PATH + "mugshotframe";
+    public static final String TEXTFIELD_COVERNAME  = GFX_PATH + "textfield_covername";
+    public static final String STAMP_PLACEHOLDER    = GFX_PATH + "stampplaceholder";
+    public static final String TEXTFIELD_SIGNATURE  = GFX_PATH + "texfield_signature";
+    public static final String INK                  = GFX_PATH + "ink";
+    public static final String CLEAR                = GFX_PATH + "clear";
+    public static final String SEX_FEMALE           = GFX_PATH + "sex_female";
+    public static final String SEX_MALE             = GFX_PATH + "sex_male";
+
+    public static final String BUTTON_MINUS         = GFX_PATH + "button_minus";
+    public static final String BUTTON_PLUS          = GFX_PATH + "button_plus";
+    public static final String BUTTON_MINUS_PRESSED = GFX_PATH + "button_minus_pressed";
+    public static final String BUTTON_PLUS_PRESSED  = GFX_PATH + "button_plus_pressed";
+
+    public static final String SWITCH_BACKGROUND    = GFX_PATH + "switch_background";
+    public static final String SWITCH_LEFT          = GFX_PATH + "switch_left";
+    public static final String SWITCH_CENTER        = GFX_PATH + "switch_center";
+    public static final String SWITCH_RIGHT         = GFX_PATH + "switch_right";
+
+    public static final String PENCIL_DROPPED       = GFX_PATH + "pencil_dropped";
+    public static final String STAMP_LEFT_DROPPED   = GFX_PATH + "stamp_left_dropped";
+
+    public static final String STAMP                = GFX_PATH + "stamp";
+
+    public static final String FILM_OUTERLINE       = AVATAR_PATH + "film_outerline";
+    public static final String FILM_INSIDE          = AVATAR_PATH + "film_inside";
+
+    ///// TEXT ASSET KEYS
+    public static final String TEXT_FORM_CANCEL     = "createuser_form_cancel";
+    public static final String TEXT_FORM_SIGN       = "createuser_form_sign";
+    public static final String TEXT_FORM_AGE        = "createuser_form_age";
+    public static final String TEXT_FORM_GENDER     = "createuser_form_gender";
+    public static final String TEXT_FORM_SIGNATURE  = "createuser_form_signature";
+
+
+    ///// MUSIC ASSETS
+    public static final String MFX_PATH             = "mfx/";
+
+    public static final String VALIDATION_MUGSHOT_SOUND   = MFX_PATH + "profil_foto.mp3";
+    public static final String VALIDATION_USERNAME_SOUND  = MFX_PATH + "profil_jmeno.mp3";
+    public static final String VALIDATION_SIGNATURE_SOUND = MFX_PATH + "profil_podpis_pero.mp3";
+    public static final String VALIDATION_GENDER_SOUND    = MFX_PATH + "profil_klukholka.mp3";
+    public static final String VALIDATION_AGE_SOUND       = MFX_PATH + "profil_vek.mp3";
+    public static final String VALIDATION_STAMP_SOUND     = MFX_PATH + "profil_razitko.mp3";
+
+}
diff --git a/core/src/cz/nic/tablexia/screen/createuser/form/FormActorsLayout.java b/core/src/cz/nic/tablexia/screen/createuser/form/FormActorsLayout.java
index b5b04fd0bed48c1132f09f4eceb56ae2249b0453..9b44e408726074373c52df68ccd9c0e882fa1f41 100644
--- a/core/src/cz/nic/tablexia/screen/createuser/form/FormActorsLayout.java
+++ b/core/src/cz/nic/tablexia/screen/createuser/form/FormActorsLayout.java
@@ -34,8 +34,10 @@ public class FormActorsLayout {
     public static final float  STAMP_X                          = -0.01f;
     public static final float  STAMP_Y                          = -0.05f;
 
+    public static final float  SIGNATURE_PANE_X                 = 0.53f;
     public static final float  SIGNATURE_PANE_Y                 = 0.1f;
-    public static final float  SIGNATURE_PANE_HEIGHT            = 0.1f;
+    public static final float  SIGNATURE_PANE_WIDTH             = 0.2f;
+    public static final float  SIGNATURE_PANE_HEIGHT            = 0.12f;
 
     public static final float  SWITCH_GENDER_SCALE              = 0.8f;
     public static final float  SWITCH_GENDER_X                  = 0.725f;
@@ -52,16 +54,16 @@ public class FormActorsLayout {
 
     public static final float  IMAGE_FEMALE_WIDTH               = 0.015f;
     public static final float  IMAGE_FEMALE_X                   = 0.80f;
-    public static final float  IMAGE_FEMALE_Y                   = 0.18f;
+    public static final float  IMAGE_FEMALE_Y                   = 0.183f;
     public static final float  IMAGE_MALE_WIDTH                 = 0.015f;
     public static final float  IMAGE_MALE_X                     = 0.69f;
-    public static final float  IMAGE_MALE_Y                     = 0.18f;
+    public static final float  IMAGE_MALE_Y                     = 0.183f;
 
     public static final float  AGE_LABEL_X                      = 0.58f;
     public static final float  AGE_LABEL_Y                      = 0.225f;
 
     public static final float  AGE_VALUE_X                      = 0.58f;
-    public static final float  AGE_VALUE_Y                      = 0.185f;
+    public static final float  AGE_VALUE_Y                      = 0.18f;
 
     public static final float  GENDER_LABEL_X                   = 0.73f;
     public static final float  GENDER_LABEL_Y                   = 0.225f;
diff --git a/core/src/cz/nic/tablexia/screen/encyclopedia/EncyclopediaScreen.java b/core/src/cz/nic/tablexia/screen/encyclopedia/EncyclopediaScreen.java
index 7cc1deb4a4b46bf0e4481fce1df3ea9c86c7949c..656df4e7be790cd9b5116bb46b692b41414f72a8 100644
--- a/core/src/cz/nic/tablexia/screen/encyclopedia/EncyclopediaScreen.java
+++ b/core/src/cz/nic/tablexia/screen/encyclopedia/EncyclopediaScreen.java
@@ -29,7 +29,6 @@ import cz.nic.tablexia.screen.encyclopedia.widget.ResizableWidgetGroup;
 import cz.nic.tablexia.util.Log;
 import cz.nic.tablexia.util.MusicUtil;
 import cz.nic.tablexia.util.Point;
-import cz.nic.tablexia.util.ui.button.CloseTablexiaButton;
 import cz.nic.tablexia.util.ui.button.ImageTablexiaButton;
 import cz.nic.tablexia.util.ui.button.StandardTablexiaButton;
 import cz.nic.tablexia.util.ui.button.TablexiaButton;
@@ -44,14 +43,7 @@ public class EncyclopediaScreen extends AbstractTablexiaScreen<Void> {
     private static final float  CONTENT_RELATIVE_WIDTH          = 0.70f;
     private static final int    CONTENT_PAD_TOP                 = 30;
     private static final float  MENU_RELATIVE_HEIGHT            = 0.80f;
-    private static final int    CONTENT_PAD_LEFT                = 40;
-
-    private static final int CLOSE_BUTTON_WIDTH       = 35;
-    private static final int CLOSE_BUTTON_PAD_RIGHT   = 20;
-    private static final int CLOSE_BUTTON_PAD_TOP     = 0;
-    private static final int CLOSE_BUTTON_PAD_LEFT    = 10;
-    private static final int CLOSE_BUTTON_PAD_BOTTOM  = 10;
-
+    private static final int    CONTENT_PAD_LEFT                = 120;
 
     private static final int RIGHT_BUTTONS_PAD_BOTTOM = 10;
 
@@ -92,6 +84,11 @@ public class EncyclopediaScreen extends AbstractTablexiaScreen<Void> {
         return playedMusic;
     }
 
+    @Override
+    public boolean hasSoftBackButton() {
+        return true;
+    }
+
     @Override
     protected Viewport createViewport() {
         return new ExtendViewport(TablexiaSettings.getWorldSize(), TablexiaSettings.getMinWorldHeight());
@@ -182,15 +179,6 @@ public class EncyclopediaScreen extends AbstractTablexiaScreen<Void> {
         contentScrollPane.setScrollingDisabled(true, false);
         contentScrollPane.setSize(CONTENT_RELATIVE_WIDTH * getViewportWidth(), getViewportHeight());
 
-        TablexiaButton closeButton = new CloseTablexiaButton().setInputListener(new ClickListener() {
-            @Override
-            public void clicked(InputEvent event, float x, float y) {
-                super.clicked(event, x, y);
-                disposeMusic();
-                backToInitialScreen();
-            }
-        });
-        contentStack.add(closeButton).bottom().left().pad(CLOSE_BUTTON_PAD_TOP, CLOSE_BUTTON_PAD_LEFT, CLOSE_BUTTON_PAD_BOTTOM, CLOSE_BUTTON_PAD_RIGHT);
         contentStack.add(contentScrollPane).padTop(CONTENT_PAD_TOP);
         container.add(contentStack);
     }
@@ -255,7 +243,7 @@ public class EncyclopediaScreen extends AbstractTablexiaScreen<Void> {
         List<Content> contentList = ContentParser.parseEncyclopediaPageContent(fileHandle.readString());
 
         for (Content c : contentList) {
-            c.addToCell(content, this, (CONTENT_RELATIVE_WIDTH * getViewportWidth()) - CLOSE_BUTTON_PAD_LEFT - CLOSE_BUTTON_WIDTH - CLOSE_BUTTON_PAD_RIGHT - CONTENT_PAD_LEFT);
+            c.addToCell(content, this, (CONTENT_RELATIVE_WIDTH * getViewportWidth()) - CONTENT_PAD_LEFT);
             content.row();
         }
     }
diff --git a/core/src/cz/nic/tablexia/screen/gamemenu/GameMenuAssets.java b/core/src/cz/nic/tablexia/screen/gamemenu/GameMenuAssets.java
index ca13a733a9dbb0f38e1ad8bd82caf91ca5cdb2fe..cbd3bed12c5d93b23e6f5c3879b23656443e7a18 100644
--- a/core/src/cz/nic/tablexia/screen/gamemenu/GameMenuAssets.java
+++ b/core/src/cz/nic/tablexia/screen/gamemenu/GameMenuAssets.java
@@ -32,6 +32,7 @@ public final class GameMenuAssets {
     public static final String DIFF_THUMB_EASY = GFX_PATH + "difficultyseekbar_thumb_easy";
     public static final String DIFF_THUMB_HARD = GFX_PATH + "difficultyseekbar_thumb_hard";
     public static final String DIFF_THUMB_MEDIUM = GFX_PATH + "difficultyseekbar_thumb_medium";
+    public static final String PROGRESSBAR_FILL = GFX_PATH + "progressbar_fill";
 
     public static final String BASE_ASSETS_ROBBERY = "bankovniloupez";
     public static final String BASE_ASSETS_PURSUIT = "pronasledovani";
@@ -47,6 +48,7 @@ public final class GameMenuAssets {
     public static final String BASE_ASSETS_MIDDLE_POSTFIX = "mid";
     public static final String BASE_ASSETS_BACKGROUND_POSTFIX = "back";
     public static final String BASE_ASSETS_TITLE_POSTFIX = "title";
+    public static final String BASE_ASSETS_PROGRESSBAR_POSTFIX = "progressbar";
     public static final String BASE_ASSETS_START_BUTTON_RELEASED_POSTFIX = "startbutton";
     public static final String BASE_ASSETS_START_BUTTON_PRESSED_POSTFIX = "startbutton_pressed";
     public static final String BASE_ASSETS_INTRO_SOUND_POSTFIX = "intro.mp3";
@@ -75,6 +77,7 @@ public final class GameMenuAssets {
         MID                 (GFX_PATH, BASE_ASSETS_MIDDLE_POSTFIX),
         BACK                (GFX_PATH, BASE_ASSETS_BACKGROUND_POSTFIX),
         TITLE               (GFX_PATH, BASE_ASSETS_TITLE_POSTFIX),
+        PROGRESSBAR         (GFX_PATH, BASE_ASSETS_PROGRESSBAR_POSTFIX),
         STARTBUTTON         (GFX_PATH, BASE_ASSETS_START_BUTTON_RELEASED_POSTFIX),
         STARTBUTTON_PRESSED (GFX_PATH, BASE_ASSETS_START_BUTTON_PRESSED_POSTFIX),
         INTRO               (SFX_PATH, BASE_ASSETS_INTRO_SOUND_POSTFIX);
diff --git a/core/src/cz/nic/tablexia/screen/gamemenu/GameMenuScreen.java b/core/src/cz/nic/tablexia/screen/gamemenu/GameMenuScreen.java
index 116a0143dc6a94f9547f08505307c543a920ebc8..bed02ff41b790d1d021e08e2c6c89eb92d957faa 100644
--- a/core/src/cz/nic/tablexia/screen/gamemenu/GameMenuScreen.java
+++ b/core/src/cz/nic/tablexia/screen/gamemenu/GameMenuScreen.java
@@ -7,6 +7,7 @@ import com.badlogic.gdx.math.Vector2;
 import com.badlogic.gdx.scenes.scene2d.Actor;
 import com.badlogic.gdx.scenes.scene2d.Touchable;
 import com.badlogic.gdx.scenes.scene2d.actions.Actions;
+import com.badlogic.gdx.scenes.scene2d.actions.SequenceAction;
 import com.badlogic.gdx.scenes.scene2d.ui.Image;
 
 import net.engio.mbassy.listener.Handler;
@@ -18,7 +19,9 @@ import java.util.Map;
 
 import cz.nic.tablexia.bus.ApplicationBus;
 import cz.nic.tablexia.game.GameDefinition;
+import cz.nic.tablexia.menu.AbstractMenu;
 import cz.nic.tablexia.menu.game.GameMenuDefinition;
+import cz.nic.tablexia.menu.main.MainMenu;
 import cz.nic.tablexia.model.screen.ScreenDAO;
 import cz.nic.tablexia.screen.AbstractTablexiaScreen;
 import cz.nic.tablexia.screen.gamemenu.actions.ScrollHomeAction;
@@ -27,6 +30,7 @@ import cz.nic.tablexia.screen.gamemenu.pages.GameMenuPage;
 import cz.nic.tablexia.screen.gamemenu.pages.MenuPage;
 import cz.nic.tablexia.screen.gamemenu.pages.OfficeMenuPage;
 import cz.nic.tablexia.screen.gamemenu.pages.WallPage;
+import cz.nic.tablexia.util.MusicUtil;
 import cz.nic.tablexia.util.Utility;
 
 /**
@@ -41,6 +45,12 @@ public class GameMenuScreen extends AbstractTablexiaScreen<int[][]> {
 
     private Music ambientMusic;
 
+    private Music introSpeechMusic;
+    private Music.OnCompletionListener introSpeechMusicCompleteListener;
+
+    private SequenceAction initialScrollAction;
+    private boolean initialScrollActive = false;
+
     public enum GameMenuPageDefinition {
         OFFICE_PAGE(0, null, null, null),
         ROBBERY_PAGE(        1, GameDefinition.ROBBERY,          GameMenuAssets.BASE_ASSETS_ROBBERY,         new Vector2(0.168f, 0.016f)),
@@ -166,10 +176,10 @@ public class GameMenuScreen extends AbstractTablexiaScreen<int[][]> {
         }
 
         // show intro scroll and play intro speech only first time user visits GameMenuScreen
-        Music music = null;
+        introSpeechMusic = null;
         if(isFirstLogIn) {
-            music = getMusic(INTRO_SPEECH);
-            music.play();
+            introSpeechMusic = getMusic(INTRO_SPEECH);
+            introSpeechMusic.play();
 
             pagedScrollPane.setTouchable(Touchable.disabled);
             pagedScrollPane.scrollToPage(pagedScrollPane.getChildren().size - 1, false);
@@ -178,26 +188,31 @@ public class GameMenuScreen extends AbstractTablexiaScreen<int[][]> {
             pagedScrollPane.setScrollX(pagedScrollPane.getContent().getWidth());
             pagedScrollPane.updateVisualScroll();
 
-            pagedScrollPane.addAction(Actions.sequence(Actions.delay(1f), ScrollHomeAction.createInstace(), Actions.run(new Runnable() {
+            initialScrollAction = Actions.sequence(Actions.delay(1f), ScrollHomeAction.createInstace(), Actions.run(new Runnable() {
                 @Override
                 public void run() {
                     pagedScrollPane.setTouchable(Touchable.enabled);
+                    initialScrollActive = false;
                 }
-            })));
+            }));
+            pagedScrollPane.addAction(initialScrollAction);
+            initialScrollActive = true;
         }
 
         //sound effect of street is waiting, until intro speech is finished
         //game sound effects in menu are turned of after intro speech is finished
         if(isFirstLogIn) {
-            if (music != null) {
-                music.setOnCompletionListener(new Music.OnCompletionListener() {
+            if (introSpeechMusic != null) {
+                introSpeechMusicCompleteListener = new Music.OnCompletionListener() {
                     @Override
                     public void onCompletion(Music music) {
                         music.dispose();
                         playAmbientMusic();
                         resetGameMenuSounds(gameMenuPages);
                     }
-                });
+                };
+
+                introSpeechMusic.setOnCompletionListener(introSpeechMusicCompleteListener);
             }
         } else {
             playAmbientMusic();
@@ -206,6 +221,18 @@ public class GameMenuScreen extends AbstractTablexiaScreen<int[][]> {
         screenResized(0, 0);
     }
 
+    private void cancelInitialScroll() {
+        initialScrollActive = false;
+        pagedScrollPane.removeAction(initialScrollAction);
+        pagedScrollPane.cancel();
+        pagedScrollPane.scrollToInitialPage();
+        pagedScrollPane.setTouchable(Touchable.enabled);
+
+        if(introSpeechMusic != null && introSpeechMusic.isPlaying()) {
+            MusicUtil.fadeOut(introSpeechMusic, 1f, introSpeechMusicCompleteListener);
+        }
+    }
+
     private void playAmbientMusic() {
         ambientMusic = getMusic(GameMenuAssets.AMBIENT_MUSIC);
         ambientMusic.setVolume(AMBIENT_SOUND_VOLUME);
@@ -284,10 +311,22 @@ public class GameMenuScreen extends AbstractTablexiaScreen<int[][]> {
 
     @Override
     public void backButtonPressed() {
+        if(initialScrollActive) {
+            cancelInitialScroll();
+            return;
+        }
+
         if (!pagedScrollPane.getCurrentPage().backButtonPressed()) {
             if (!pagedScrollPane.scrollToInitialPage()) {
                 Gdx.app.exit();
             }
         }
     }
+
+    @Handler
+    public void onMenuEvent(AbstractMenu.MenuEvent menuEvent) {
+        if(initialScrollActive && menuEvent.getTargetMenu() == MainMenu.class) {
+            cancelInitialScroll();
+        }
+    }
 }
\ No newline at end of file
diff --git a/core/src/cz/nic/tablexia/screen/gamemenu/PagedScrollPane.java b/core/src/cz/nic/tablexia/screen/gamemenu/PagedScrollPane.java
index c48a065b2fd7ddbc9125a6fa41b4cbc897c4c501..b4df09713f3860267b260530ce9b0e0d475938f5 100644
--- a/core/src/cz/nic/tablexia/screen/gamemenu/PagedScrollPane.java
+++ b/core/src/cz/nic/tablexia/screen/gamemenu/PagedScrollPane.java
@@ -9,6 +9,7 @@ import com.badlogic.gdx.scenes.scene2d.InputEvent;
 import com.badlogic.gdx.scenes.scene2d.InputListener;
 import com.badlogic.gdx.scenes.scene2d.ui.HorizontalGroup;
 import com.badlogic.gdx.scenes.scene2d.ui.Image;
+import com.badlogic.gdx.utils.SnapshotArray;
 
 import cz.nic.tablexia.screen.gamemenu.pages.MenuPage;
 import cz.nic.tablexia.util.ui.ScrollPaneWithBorders;
@@ -148,6 +149,20 @@ public class PagedScrollPane extends ScrollPaneWithBorders {
         });
     }
 
+    @Override
+    public void setScrollX(float pixels) {
+        super.setScrollX(pixels);
+
+        SnapshotArray<Actor> pages = content.getChildren();
+        int page = 0;
+        for(int i = 0; i < pages.size; i++) {
+            if(pages.get(i).getX() < getScrollX()) {
+                page++;
+            }
+        }
+        currentPage = page;
+    }
+
     /**
      * Determinates if PagedScrollPane should change page or not
      * according to swipes X coordinate
diff --git a/core/src/cz/nic/tablexia/screen/gamemenu/pages/GameMenuPage.java b/core/src/cz/nic/tablexia/screen/gamemenu/pages/GameMenuPage.java
index a1de6a256b07bee852ac253badb680ad599d3394..346f7698853dbf1c8009c78f005221b489e2f466 100644
--- a/core/src/cz/nic/tablexia/screen/gamemenu/pages/GameMenuPage.java
+++ b/core/src/cz/nic/tablexia/screen/gamemenu/pages/GameMenuPage.java
@@ -9,6 +9,7 @@ import com.badlogic.gdx.math.MathUtils;
 import com.badlogic.gdx.scenes.scene2d.Actor;
 import com.badlogic.gdx.scenes.scene2d.InputEvent;
 import com.badlogic.gdx.scenes.scene2d.InputListener;
+import com.badlogic.gdx.scenes.scene2d.Touchable;
 import com.badlogic.gdx.scenes.scene2d.actions.Actions;
 import com.badlogic.gdx.scenes.scene2d.actions.SequenceAction;
 import com.badlogic.gdx.scenes.scene2d.ui.Image;
@@ -24,12 +25,16 @@ import cz.nic.tablexia.TablexiaSettings;
 import cz.nic.tablexia.bus.ApplicationBus;
 import cz.nic.tablexia.game.GameDefinition;
 import cz.nic.tablexia.game.difficulty.GameDifficulty;
+import cz.nic.tablexia.game.ranksystem.UserRankManager;
 import cz.nic.tablexia.loader.application.ApplicationFontManager;
 import cz.nic.tablexia.model.UserDifficultySettingsDAO;
 import cz.nic.tablexia.screen.gamemenu.GameMenuAssets;
 import cz.nic.tablexia.screen.gamemenu.GameMenuScreen;
+import cz.nic.tablexia.screen.profile.ProfileScreen;
 import cz.nic.tablexia.util.MusicUtil;
+import cz.nic.tablexia.util.ui.ClickListenerWithSound;
 import cz.nic.tablexia.util.ui.Switch;
+import cz.nic.tablexia.util.ui.TablexiaProgressBar;
 import cz.nic.tablexia.util.ui.TablexiaLabel;
 import cz.nic.tablexia.util.ui.button.TablexiaButton;
 
@@ -53,9 +58,9 @@ public class GameMenuPage extends MenuPage {
      * Offset is represented as a percentage of the screens height
      * for example 0.05 means that actor will have offset of 5% of the screens height
      */
-    private static final float TITLE_TOP_OFFSET             = 0.05f;
-    private static final float START_BUTTON_BOTTOM_OFFSET   = 0.22f;
-    private static final float DIFFICULTY_BOTTOM_OFFSET     = 0.045f;
+    private static final float TITLE_TOP_OFFSET             = 0.03f;
+    private static final float START_BUTTON_BOTTOM_OFFSET   = 0.26f;
+    private static final float DIFFICULTY_BOTTOM_OFFSET     = 0.1f;
     private static final float DIFFICULTY_BAR_BOTTOM_OFFSET = 0.04f;
 
 	/*
@@ -77,12 +82,21 @@ public class GameMenuPage extends MenuPage {
      */
     private static final float DIFFICULTY_BAR_EDGE_OFFSET   = 14/251f;
 
+    private static final float PROGRESS_BAR_WIDTH           = 0.6f;
+    private static final float PROGRESS_BAR_BOTTOM_OFFSET   = 0.002f;
+
+    private static final char  PROGRESS_STATUS_SEPARATOR    = '/';
+    private static final float PROGRESS_STATUS_OFFSET_X     = 0.01f;
+
     private static final float INTRO_SOUND_DELAY    =   1.0f; //Delay in seconds
     
     private static final int DRAGGING_THRESHOLD = 20;
 
     //Font for difficulty labels
-    private static final ApplicationFontManager.FontType_NEW LABELS_FONT_STYLE = ApplicationFontManager.FontType_NEW.BOLD_18;
+    private static final ApplicationFontManager.FontType_NEW DIFFICULTY_FONT_STYLE = ApplicationFontManager.FontType_NEW.BOLD_18;
+
+    //Progress status font
+    private static final ApplicationFontManager.FontType_NEW PROGRESS_STATUS_FONT  = ApplicationFontManager.FontType_NEW.BOLD_18;
 
     private GameDefinition game;
     private GameMenuScreen.GameMenuPageDefinition gameMenuPageDefinition;
@@ -118,6 +132,10 @@ public class GameMenuPage extends MenuPage {
     //Is this first display of this page (and should we play sound effects?)
     private boolean isFirstLogin = false;
 
+    private TablexiaProgressBar gameMenuPageProgress;
+
+    private TablexiaLabel progressLabel;
+
 	private TextureRegion background;
 
     private TextureRegion midLayer;
@@ -138,6 +156,7 @@ public class GameMenuPage extends MenuPage {
 		prepareTitle();
         prepareStartButton();
         prepareDifficulty();
+        prepareGameProgress();
 
 		// init event bus handlers
 		ApplicationBus.getInstance().subscribe(this);
@@ -300,7 +319,7 @@ public class GameMenuPage extends MenuPage {
         diffHardX = centerDiffX + (diffBarWidth / 2) - (diffWidth / 2) - (diffBarWidth * DIFFICULTY_BAR_EDGE_OFFSET);// - (diffWidth * 0.1f);
 
         // Labels for diffuculty slider
-        TablexiaLabel.TablexiaLabelStyle labelStyle = new TablexiaLabel.TablexiaLabelStyle(LABELS_FONT_STYLE, Color.BLACK);
+        TablexiaLabel.TablexiaLabelStyle labelStyle = new TablexiaLabel.TablexiaLabelStyle(DIFFICULTY_FONT_STYLE, Color.BLACK);
 
         TablexiaLabel easy = new TablexiaLabel(GameDifficulty.EASY.getTextDescription(), labelStyle);
         TablexiaLabel medium = new TablexiaLabel(GameDifficulty.MEDIUM.getTextDescription(), labelStyle);
@@ -339,6 +358,7 @@ public class GameMenuPage extends MenuPage {
         buttonDifficultyEasy.addListener(new ClickListener() {
             @Override
             public void clicked(InputEvent event, float x, float y) {
+                super.clicked(event, x, y);
                 dragSwitchListener.switchToStep(GameDifficulty.EASY.getDifficultyNumber() - 1);
             }
         });
@@ -346,6 +366,7 @@ public class GameMenuPage extends MenuPage {
         buttonDifficultyMedium.addListener(new ClickListener() {
             @Override
             public void clicked(InputEvent event, float x, float y) {
+                super.clicked(event, x, y);
                 dragSwitchListener.switchToStep(GameDifficulty.MEDIUM.getDifficultyNumber() - 1);
             }
         });
@@ -353,6 +374,7 @@ public class GameMenuPage extends MenuPage {
         buttonDifficultyHard.addListener(new ClickListener() {
             @Override
             public void clicked(InputEvent event, float x, float y) {
+                super.clicked(event, x, y);
                 dragSwitchListener.switchToStep(GameDifficulty.HARD.getDifficultyNumber() - 1);
             }
         });
@@ -401,12 +423,60 @@ public class GameMenuPage extends MenuPage {
                 difficultyChanged(GameDifficulty.getVisibleGameDifficultyList().get(step));
             }
         });
-        gameDifficulty = UserDifficultySettingsDAO.getUserSettingsByGame(TablexiaSettings.getInstance().getSelectedUser().getId(), game.getGameNumber());
-        dragSwitchListener.switchToStep(gameDifficulty.getDifficultyNumber() - 1);
+		gameDifficulty = UserDifficultySettingsDAO.getUserSettingsByGame(TablexiaSettings.getInstance().getSelectedUser().getId(), game.getGameNumber());
+        dragSwitchListener.switchToStep(gameDifficulty.getDifficultyNumber() - 1, false);
 
         stepSoundsEnabled = true;
     }
 
+    public void prepareGameProgress() {
+        this.gameMenuPageProgress = new TablexiaProgressBar(
+                getScreen().getScreenTextureRegion(GameMenuScreen.GameMenuPageDefinition.getResourcePath(game, GameMenuAssets.AssetType.PROGRESSBAR)),
+                getScreen().getScreenTextureRegion(GameMenuAssets.PROGRESSBAR_FILL)
+        );
+
+        this.gameMenuPageProgress.setWidth(getScreen().getSceneWidth() * PROGRESS_BAR_WIDTH);
+        this.gameMenuPageProgress.setPosition(
+                getScreen().getSceneWidth() / 2 - gameMenuPageProgress.getWidth() / 2,
+                getScreen().getSceneInnerBottomY() + (getScreen().getSceneOuterHeight() * PROGRESS_BAR_BOTTOM_OFFSET) - pagedScrollPaneOffsetY
+        );
+
+        UserRankManager.RankProgress rankProgress = UserRankManager.getInstance().getGameRankProgress(TablexiaSettings.getInstance().getSelectedUser(), game);
+
+        this.progressLabel = new TablexiaLabel(getProgressLabelText(rankProgress), new TablexiaLabel.TablexiaLabelStyle(PROGRESS_STATUS_FONT, Color.BLACK));
+        this.progressLabel.setPosition(
+                gameMenuPageProgress.getX() + gameMenuPageProgress.getWidth() + PROGRESS_STATUS_OFFSET_X * getScreen().getSceneWidth(),
+                gameMenuPageProgress.getY() + gameMenuPageProgress.getHeight()/2 - progressLabel.getHeight()/2
+        );
+
+        this.gameMenuPageProgress.addListener(new ClickListenerWithSound() {
+            @Override
+            public void onClick(InputEvent event, float x, float y) {
+                ApplicationBus.getInstance().publish(new Tablexia.ChangeScreenEvent(ProfileScreen.class, TablexiaApplication.ScreenTransaction.FADE));
+                gameMenuPageProgress.setTouchable(Touchable.disabled); //Makes sure you wont click twice...
+            }
+        });
+
+        updateGameProgress();
+
+        addActor(gameMenuPageProgress);
+        addActor(progressLabel);
+    }
+
+    public void updateGameProgress() {
+        UserRankManager.RankProgress rankProgress = UserRankManager.getInstance().getGameRankProgress(TablexiaSettings.getInstance().getSelectedUser(), game);
+
+        if(gameMenuPageProgress == null) return;
+        this.gameMenuPageProgress.setPercent(rankProgress.getPercentDone());
+
+        if(progressLabel == null) return;
+        progressLabel.setText(getProgressLabelText(rankProgress));
+    }
+
+    private String getProgressLabelText(UserRankManager.RankProgress rankProgress) {
+        return (rankProgress.getCurrXP() - rankProgress.getMinXP()) + Character.toString(PROGRESS_STATUS_SEPARATOR) + (rankProgress.getNextXP() - rankProgress.getMinXP());
+    }
+
     /**
      * Called when difficulty is changed
      *
@@ -415,7 +485,6 @@ public class GameMenuPage extends MenuPage {
     public void difficultyChanged(final GameDifficulty difficulty) {
         gameDifficulty = difficulty;
         TablexiaSettings.getInstance().setGameDifficulty(game, difficulty);
-
 		new Runnable() {
 			@Override
 			public void run() {
@@ -574,8 +643,10 @@ public class GameMenuPage extends MenuPage {
 					gameDifficulty = UserDifficultySettingsDAO.getUserSettingsByGame(TablexiaSettings.getInstance().getSelectedUser().getId(), game.getGameNumber());
 					dragSwitchListener.switchToStep(gameDifficulty.getDifficultyNumber() - 1);
                     stepSoundsEnabled = true;
+
+                    updateGameProgress();
 				}
 			}
 		});
 	}
-}
\ No newline at end of file
+}
diff --git a/core/src/cz/nic/tablexia/screen/halloffame/HallOfFameScreen.java b/core/src/cz/nic/tablexia/screen/halloffame/HallOfFameScreen.java
index 9407a89267e9da6fbed4fdb1ac2b6ae7d448811d..f3b927db712ca79357bd5b2328237de1301db0ae 100644
--- a/core/src/cz/nic/tablexia/screen/halloffame/HallOfFameScreen.java
+++ b/core/src/cz/nic/tablexia/screen/halloffame/HallOfFameScreen.java
@@ -5,16 +5,16 @@ import com.badlogic.gdx.graphics.g2d.DistanceFieldFont;
 import com.badlogic.gdx.graphics.g2d.GlyphLayout;
 import com.badlogic.gdx.graphics.g2d.Sprite;
 import com.badlogic.gdx.graphics.g2d.TextureRegion;
-import com.badlogic.gdx.math.MathUtils;
 import com.badlogic.gdx.math.Vector2;
 import com.badlogic.gdx.scenes.scene2d.Group;
 import com.badlogic.gdx.scenes.scene2d.InputEvent;
 import com.badlogic.gdx.scenes.scene2d.Touchable;
 import com.badlogic.gdx.scenes.scene2d.actions.Actions;
+import com.badlogic.gdx.scenes.scene2d.ui.Cell;
 import com.badlogic.gdx.scenes.scene2d.ui.HorizontalGroup;
 import com.badlogic.gdx.scenes.scene2d.ui.Image;
-import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane;
 import com.badlogic.gdx.scenes.scene2d.ui.Stack;
+import com.badlogic.gdx.scenes.scene2d.ui.Table;
 import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
 import com.badlogic.gdx.scenes.scene2d.utils.SpriteDrawable;
 import com.badlogic.gdx.utils.Align;
@@ -33,18 +33,24 @@ import java.util.TimerTask;
 import cz.nic.tablexia.TablexiaSettings;
 import cz.nic.tablexia.game.AbstractTablexiaGame;
 import cz.nic.tablexia.game.GameDefinition;
+import cz.nic.tablexia.game.common.TablexiaRandom;
+import cz.nic.tablexia.game.ranksystem.UserRankManager;
 import cz.nic.tablexia.game.trophy.GameTrophyDefinition;
 import cz.nic.tablexia.game.trophy.ITrophyDefinition;
 import cz.nic.tablexia.game.trophy.UserTrophyDefinition;
+import cz.nic.tablexia.loader.application.ApplicationAtlasManager;
 import cz.nic.tablexia.loader.application.ApplicationFontManager;
+import cz.nic.tablexia.loader.application.ApplicationTextManager;
 import cz.nic.tablexia.menu.game.GameMenuDefinition;
 import cz.nic.tablexia.model.game.UserTrophy;
+import cz.nic.tablexia.model.screen.ScreenDAO;
 import cz.nic.tablexia.screen.AbstractTablexiaScreen;
 import cz.nic.tablexia.screen.halloffame.assets.HallOfFameAssets;
 import cz.nic.tablexia.screen.halloffame.trophy.TrophyHelper;
 import cz.nic.tablexia.shared.model.User;
 import cz.nic.tablexia.util.Log;
 import cz.nic.tablexia.util.Point;
+import cz.nic.tablexia.util.ScaleUtil;
 import cz.nic.tablexia.util.structure.Trio;
 import cz.nic.tablexia.util.ui.ComponentScaleUtil;
 import cz.nic.tablexia.util.ui.ScrollPaneWithBorders;
@@ -54,6 +60,8 @@ import cz.nic.tablexia.util.ui.dialog.TablexiaComponentDialog;
 import cz.nic.tablexia.util.ui.dialog.TablexiaComponentDialogFactory;
 import cz.nic.tablexia.util.ui.dialog.components.AdaptiveSizeDialogComponent;
 import cz.nic.tablexia.util.ui.dialog.components.BackButtonHideComponent;
+import cz.nic.tablexia.util.ui.dialog.components.CenterPositionDialogComponent;
+import cz.nic.tablexia.util.ui.dialog.components.DimmerDialogComponent;
 import cz.nic.tablexia.util.ui.dialog.components.DividerContentDialogComponent;
 import cz.nic.tablexia.util.ui.dialog.components.FixedSpaceContentDialogComponent;
 import cz.nic.tablexia.util.ui.dialog.components.ImageContentDialogComponent;
@@ -66,20 +74,27 @@ import cz.nic.tablexia.util.ui.dialog.components.TwoColumnTextContentDialogCompo
 
 public class HallOfFameScreen extends AbstractTablexiaScreen<Map<ITrophyDefinition, Boolean>> {
 
-    private static final Point  SCREEN_SIZE = new Point(TablexiaSettings.getWorldSize(), TablexiaSettings.getMinWorldHeight());
+    private static final Point  SCREEN_SIZE                         = new Point(TablexiaSettings.getWorldSize(), TablexiaSettings.getMinWorldHeight());
     private static final int    TROPHY_DIALOG_WIDTH                 = 350;
     private static final int    TROPHY_DIALOG_HEIGHT                = 350;
-    private static final int    BACKGROUND_TILE_REPEAT_COUNT        = 22;
+    private static final int    BACKGROUND_TILE_REPEAT_COUNT        = 23;
     private static final float  TILE_SCREE_WIDTH_RATIO              = 0.25f;
-    private static final long   MOUSE_DIALOG_DURATION               = 5000;
+    private static final long   MOUSE_CHEESE_ANIM_DURATION          = 1500;
+    private static final long   MOUSE_DIALOG_DURATION               = 8000;
     private static final float  MOUSE_DIALOG_PADDING                = 8;
     private static final float  MOUSE_DIALOG_PADDING_TRESHOLD_SCALE = 1.7f;
+    private static final int    MOUSE_RANK_UP_TIMEOUT               = 2 * 24 * 60 * 60 * 1000; //2 days in ms
+
+    private static final Vector2  MOUSE_DIALOG_OFFSET               = new Vector2(32, 16);
 
     public static final     String  HALL_OF_FAME_SPEECH             = MFX_PATH + "halloffame.mp3";
     private static final    String  SCREEN_STATE_SCROLL_POSITION_X  = "scrollPositionX";
     public static final     String  SCROLL_TO_TROPHY_KEY            = "scrollToTrophy";
     private static final    String  COUNT_SUM_TEXT_KEY              = "count_sum";
 
+    private static final    float   TROPHIES_OFFSET_X               = 0.2f;
+    private static final    float   TROPHIES_OFFSET_Y               = 0.0f;
+
     private static final ApplicationFontManager.FontType_NEW TROPHY_DIALOG_TITLE_FONT            = ApplicationFontManager.FontType_NEW.BOLD_20;
     private static final ApplicationFontManager.FontType_NEW TROPHY_DIALOG_DESCRIPTION_FONT      = ApplicationFontManager.FontType_NEW.REGULAR_16;
     private static final Color                              TROPHY_DIALOG_TITLE_COLOR           = Color.BLACK;
@@ -91,7 +106,7 @@ public class HallOfFameScreen extends AbstractTablexiaScreen<Map<ITrophyDefiniti
     private static final Scaling                            TROPHY_DIALOG_BANNER_SCALING        = Scaling.fit;
     private static final Scaling                            TROPHY_DIALOG_IMAGE_SCALING         = Scaling.fit;
 
-    private static final Trio<Float,Float,Float>    MOUSE_POSITION_PROPERTIES = new Trio<Float,Float,Float>(0.7f, 0.18f, 1f);
+    private static final Trio<Float,Float,Float>    MOUSE_POSITION_PROPERTIES = new Trio<Float,Float,Float>(0.8f, 0.18f, 1f);
     private static final Trio<Float,Float,Float>    CARPET_POSITION_PROPERTIES = new Trio<Float,Float,Float>(0.08f, 0.01f, 1f);
 
     private static final int                        BACKGROUND_IOS_SPACING_WORKAROUND = -2;
@@ -101,11 +116,30 @@ public class HallOfFameScreen extends AbstractTablexiaScreen<Map<ITrophyDefiniti
     private static final int                                SUM_DIALOG_TITLE_ALIGN  = Align.left;
     private static final int                                SUM_DIALOG_VALUE_ALIGN  = Align.right;
 
+    private static final float                              BADGE_TABLE_VERTICAL_SPACE          = 2f;
+    private static final float                              BADGE_TABLE_HORIZONTAL_SPACE        = 12f;
+    private static final float                              BADGE_TABLE_BADGE_HEIGHT            = 0.222f;
+
+    private static final float                              BADGE_BOARD_POS_X                   = 0.67f;
+    private static final float                              BADGE_BOARD_POS_Y                   = 0.47f;
+    private static final float                              BADGE_BOARD_WIDTH                   = 0.14f;
+    private static final float                              BADGE_BOARD_BADGE_WIDTH             = 0.132f;
+    private static final float                              BADGE_BOARD_BADGE_INACTIVE_ALPHA    = 0.5f;
+    private static final float                              BADGE_BOARD_BADGE_MAX_ANGLE         = 8f; //Ranges from -MAX_ANGLE to +MAX_ANGLE
+    private static final long                               BADGE_BOARD_RANDOM_SEED             = 1338L; //Random seed for badge rotation...
+    private static final int                                BADGE_BOARD_BADGES_PER_ROW          = 4;
+
+    private static final float                              BADGE_BOARD_DIALOG_WIDTH            = 0.8f;
+    private static final float                              BADGE_BOARD_DIALOG_HEIGHT           = 0.8f;
+    private static final float                              BADGE_BOARD_DIALOG_TABLE_WIDTH      = 0.9f;
+    private static final float                              BADGE_BOARD_DIALOG_TABLE_HEIGHT     = 0.85f;
+
     private HorizontalGroup backgroundGroup;
     private Group foregroundGroup;
     private TablexiaNoBlendingImage wallImage;
 
     private ScrollPaneWithBorders scrollPane;
+    private Image mouseImage;
 
     @Override
     protected Viewport createViewport() {
@@ -151,6 +185,8 @@ public class HallOfFameScreen extends AbstractTablexiaScreen<Map<ITrophyDefiniti
         if (screenState.containsKey(SCROLL_TO_TROPHY_KEY)) {
             scrollToTrophy(screenState.get(SCROLL_TO_TROPHY_KEY));
         }
+
+        handleMouseRankUpDialog();
     }
 
     @Override
@@ -232,6 +268,161 @@ public class HallOfFameScreen extends AbstractTablexiaScreen<Map<ITrophyDefiniti
         prepareTrophyHeap(threeStarsCount);
         prepareTrophies();
         prepareMouse(trophiesCount);
+        prepareBadgeBoard();
+    }
+
+    private void prepareBadgeBoard() {
+        Group badgeBoardGroup = new Group();
+        badgeBoardGroup.setPosition(BADGE_BOARD_POS_X * SCREEN_SIZE.x, BADGE_BOARD_POS_Y * SCREEN_SIZE.y);
+
+        final Image badgeBoard = ScaleUtil.createImageToHeight(getScreenTextureRegion(HallOfFameAssets.HALL_OF_FAME_BADGE_BOARD), SCREEN_SIZE.x * BADGE_BOARD_WIDTH);
+
+        badgeBoard.addListener(new ClickListener() {
+            @Override
+            public void clicked(InputEvent event, float x, float y) {
+                showBadgeBoardDialog();
+            }
+        });
+
+        badgeBoardGroup.addActor(badgeBoard);
+
+        TablexiaRandom random = new TablexiaRandom(BADGE_BOARD_RANDOM_SEED);
+
+        Table table = new Table();
+        table.setSize(badgeBoard.getWidth(), badgeBoard.getHeight());
+        table.defaults().space(BADGE_TABLE_VERTICAL_SPACE);
+        table.defaults().spaceLeft(BADGE_TABLE_HORIZONTAL_SPACE).spaceRight(BADGE_TABLE_HORIZONTAL_SPACE);
+
+        UserRankManager.UserRank currentRank = UserRankManager.getInstance().getRank(getSelectedUser());
+        int rowCount = 0;
+        for(UserRankManager.UserRank rank : UserRankManager.UserRank.values()) { //TODO - Add UserRankManager.getRanksOrdered() instead of values()...
+            if(!rank.isShownOnBadgeBoard()) continue;
+
+            Image badgeImage;
+
+            if(currentRank.getId() >= rank.getId()) {
+                badgeImage = ScaleUtil.createImageToWidth(ApplicationAtlasManager.getInstance().getTextureRegion(rank.getBadgeIconKey()), BADGE_BOARD_BADGE_WIDTH * badgeBoard.getWidth());
+            }
+            else {
+                //GreyScale image...
+                badgeImage = ScaleUtil.createGreyScaleImageToWidth(ApplicationAtlasManager.getInstance().getTextureRegion(rank.getBadgeIconKey()), BADGE_BOARD_BADGE_WIDTH * badgeBoard.getWidth());
+                badgeImage.setColor(badgeImage.getColor().r, badgeImage.getColor().g, badgeImage.getColor().b, badgeImage.getColor().a * BADGE_BOARD_BADGE_INACTIVE_ALPHA);
+            }
+
+            //Not touchable
+            badgeImage.setTouchable(Touchable.disabled);
+
+            //Rotate badge
+            badgeImage.setOrigin(Align.center);
+            float degrees = (random.nextFloat() - 0.5f) * BADGE_BOARD_BADGE_MAX_ANGLE;
+            badgeImage.rotateBy(degrees);
+
+            //Add badge to table
+            Cell<Image> badgeImageCell = table.add();
+            badgeImageCell.setActor(badgeImage);
+            badgeImageCell.width(badgeImage.getWidth());
+            badgeImageCell.height(badgeImage.getHeight());
+
+            rowCount++; //processing rows in table...
+            if(rowCount >= BADGE_BOARD_BADGES_PER_ROW) {
+                table.row();
+                rowCount = 0;
+            }
+        }
+
+        badgeBoardGroup.addActor(table);
+
+        foregroundGroup.addActor(badgeBoardGroup);
+    }
+
+    private void showBadgeBoardDialog() {
+        UserRankManager.UserRank currentRank = UserRankManager.getInstance().getRank(getSelectedUser());
+
+        float dialogWidth  = TablexiaComponentDialogFactory.getDialogStage().getWidth()  * BADGE_BOARD_DIALOG_WIDTH;
+        float dialogHeight = TablexiaComponentDialogFactory.getDialogStage().getHeight() * BADGE_BOARD_DIALOG_HEIGHT;
+
+        List<TablexiaDialogComponentAdapter> components = new ArrayList<TablexiaDialogComponentAdapter>();
+
+        components.add(new FixedSpaceContentDialogComponent());
+        components.add(new TextContentDialogComponent(getText(HallOfFameAssets.TEXT_BADGE_CABINET_LIST), ApplicationFontManager.FontType_NEW.BOLD_26, Color.WHITE, true));
+        components.add(new DividerContentDialogComponent(Color.WHITE));
+        components.add(new FixedSpaceContentDialogComponent());
+
+        TablexiaRandom random = new TablexiaRandom(BADGE_BOARD_RANDOM_SEED);
+
+        final Table table = new Table();
+        float tableWidth  = dialogWidth  * BADGE_BOARD_DIALOG_TABLE_WIDTH;
+        float tableHeight = dialogHeight * BADGE_BOARD_DIALOG_TABLE_HEIGHT;
+
+        table.setSize(tableWidth, tableHeight);
+
+        int rowCount = 0;
+        int badgesCount = UserRankManager.UserRank.values().length;
+        for(UserRankManager.UserRank rank : UserRankManager.UserRank.values()) {
+            if(!rank.isShownOnBadgeBoard()) continue;
+
+            Image badgeImage;
+            String badgeName = getText(HallOfFameAssets.TEXT_BADGE_CABINET_LOCKED);
+
+            if(currentRank.getId() >= rank.getId()) {
+                badgeImage = ScaleUtil.createImageToHeight(ApplicationAtlasManager.getInstance().getTextureRegion(rank.getBadgeImageKey()), BADGE_TABLE_BADGE_HEIGHT * tableHeight);
+                badgeName = ApplicationTextManager.getInstance().getText(rank.getNameKey());
+            }
+            else {
+                badgeImage = ScaleUtil.createGreyScaleImageToHeight(ApplicationAtlasManager.getInstance().getTextureRegion(rank.getBadgeImageKey()), BADGE_TABLE_BADGE_HEIGHT * tableHeight);
+                badgeImage.setColor(badgeImage.getColor().r, badgeImage.getColor().g, badgeImage.getColor().b, badgeImage.getColor().a * BADGE_BOARD_BADGE_INACTIVE_ALPHA);
+            }
+
+            TablexiaLabel badgeNameLabel = new TablexiaLabel(badgeName, new TablexiaLabel.TablexiaLabelStyle(ApplicationFontManager.FontType_NEW.BOLD_20, Color.WHITE));
+
+            //Create group for laben and badge image
+            Group group = new Group();
+            int rowsCount = badgesCount % 2 == 0 ? badgesCount / BADGE_BOARD_BADGES_PER_ROW : badgesCount / BADGE_BOARD_BADGES_PER_ROW + 1;
+            group.setSize(tableWidth / BADGE_BOARD_BADGES_PER_ROW, tableHeight / rowsCount);
+
+            //Set up badge label
+            badgeNameLabel.setWidth(group.getWidth());
+            badgeNameLabel.setAlignment(Align.center);
+            group.addActor(badgeNameLabel);
+
+            //Set up and rotate badge image
+            badgeImage.setPosition(group.getWidth()/2 - badgeImage.getWidth()/2, badgeNameLabel.getHeight());
+
+            badgeImage.setOrigin(Align.center);
+            float degrees = (random.nextFloat() - 0.5f) * BADGE_BOARD_BADGE_MAX_ANGLE;
+            badgeImage.rotateBy(degrees);
+
+            group.addActor(badgeImage);
+
+            //add badge group (image + label) to the actual table...
+            Cell<Group> groupCell = table.add(group);
+            groupCell.width(group.getWidth());
+            groupCell.height(group.getHeight());
+
+            rowCount++;
+            if(rowCount >= BADGE_BOARD_BADGES_PER_ROW) {
+                rowCount = 0;
+                table.row();
+            }
+        }
+
+        components.add(new TablexiaDialogComponentAdapter() {
+            @Override
+            public void prepareContent(Cell content) {
+                content.expand();
+                content.setActor(table);
+            }
+        });
+
+        components.add(new FixedSpaceContentDialogComponent());
+
+        components.add(new CenterPositionDialogComponent());
+        components.add(new DimmerDialogComponent());
+        components.add(new TouchCloseDialogComponent());
+        components.add(new BackButtonHideComponent());
+
+        TablexiaComponentDialog dialog = TablexiaComponentDialogFactory.getInstance().createDialog(TablexiaComponentDialog.TablexiaDialogType.DIALOG_BADGE_BOARD, components.toArray(new TablexiaDialogComponentAdapter[]{}));
+        dialog.show(dialogWidth, dialogHeight);
     }
 
     private void prepareTrophyHeap(int threeStarsCount) {
@@ -334,8 +525,8 @@ public class HallOfFameScreen extends AbstractTablexiaScreen<Map<ITrophyDefiniti
             });
 
             Trio<Float, Float, Float> properties = TrophyHelper.trophiesProperties.get(trophy);
-            int trophyX = (int) (properties.getFirst() * SCREEN_SIZE.x);
-            int trophyY = (int) (properties.getSecond() * SCREEN_SIZE.y);
+            int trophyX = (int) ((TROPHIES_OFFSET_X + properties.getFirst()) * SCREEN_SIZE.x);
+            int trophyY = (int) ((TROPHIES_OFFSET_Y + properties.getSecond()) * SCREEN_SIZE.y);
             float trophyScale = properties.getThird();
 
             trophyImage.setPosition(trophyX, trophyY);
@@ -348,7 +539,7 @@ public class HallOfFameScreen extends AbstractTablexiaScreen<Map<ITrophyDefiniti
         TrophyHelper.MouseTexts.resetAllTextCounters();
 
         final TextureRegion mouseTexture = getScreenTextureRegion(HallOfFameAssets.HALL_OF_FAME_MOUSE_UNPRESSED);
-        final Image mouseImage = new Image(mouseTexture);
+        mouseImage = new Image(mouseTexture);
 
         mouseImage.setScale(MOUSE_POSITION_PROPERTIES.getThird());
         mouseImage.setPosition(SCREEN_SIZE.x * MOUSE_POSITION_PROPERTIES.getFirst(), SCREEN_SIZE.y * MOUSE_POSITION_PROPERTIES.getSecond());
@@ -356,69 +547,113 @@ public class HallOfFameScreen extends AbstractTablexiaScreen<Map<ITrophyDefiniti
         mouseImage.addListener(new ClickListener() {
             @Override
             public void clicked(InputEvent event, float x, float y) {
-                final Timer timer = new Timer();
-
-                TextureRegion mousePressedTexture = getScreenTextureRegion(HallOfFameAssets.HALL_OF_FAME_MOUSE_PRESSED);
-                mouseImage.setDrawable(new SpriteDrawable(new Sprite(mousePressedTexture)));
-                mouseImage.setTouchable(Touchable.disabled);
-
-                float imageWidth  = mouseImage.getWidth()  * mouseImage.getScaleX();
-                float imageHeight = mouseImage.getHeight() * mouseImage.getScaleY();
-
-                float dialogX = mouseImage.getX() - scrollPane.getScrollX() + imageWidth/2f;
-                float dialogY = mouseImage.getY() + imageHeight/2f;
-
-                ArrayList<TablexiaDialogComponentAdapter> components = new ArrayList<TablexiaDialogComponentAdapter>();
-                components.add(new TouchCloseDialogComponent(new TouchCloseDialogComponent.TouchListener() {
-                    @Override
-                    public boolean dialogTouched(float x, float y, TablexiaComponentDialog dialog) {
-                        mouseImage.setDrawable(new SpriteDrawable(new Sprite(mouseTexture)));
-                        mouseImage.setTouchable(Touchable.enabled);
-                        timer.cancel();
-                        return true;
-                    }
-                }));
-                components.add(new AdaptiveSizeDialogComponent());
-                components.add(new SpeechDialogComponent(new Point(dialogX, dialogY), new Vector2(32, 16), SpeechDialogComponent.ArrowType.CLASSIC));
-
-                components.add(new FixedSpaceContentDialogComponent());
-                components.add(new ResizableSpaceContentDialogComponent());
-
-                String text = getText(TrophyHelper.MouseTexts.getMouseText(trophiesCount));
-                components.add(new TextContentDialogComponent(text, true));
-
-                components.add(new ResizableSpaceContentDialogComponent());
-                components.add(new FixedSpaceContentDialogComponent());
-
-                ApplicationFontManager.FontType_NEW defaultFontType = TextContentDialogComponent.getDefaultFontType();
-                DistanceFieldFont font = ApplicationFontManager.getInstance().getDistanceFieldFont(defaultFontType);
-                GlyphLayout layout = new GlyphLayout();
-                layout.setText(font, text);
-
-                float padding = ComponentScaleUtil.isUnderThreshold() ? MOUSE_DIALOG_PADDING * MOUSE_DIALOG_PADDING_TRESHOLD_SCALE : MOUSE_DIALOG_PADDING;
-                float dialogWidth  = layout.width * defaultFontType.getScale() + 2 * padding;
-                float dialogHeight = layout.height;
-
-                final TablexiaComponentDialog tcd = TablexiaComponentDialogFactory.getInstance().createDialog(
-                        getStage(),
-                        TablexiaComponentDialog.TablexiaDialogType.BUBBLE_ROUNDED,
-                        components.toArray(new TablexiaDialogComponentAdapter[]{}));
-                tcd.show(dialogWidth, dialogHeight);
-
-                timer.schedule(new TimerTask() {
-                    @Override
-                    public void run() {
-                        mouseImage.setDrawable(new SpriteDrawable(new Sprite(mouseTexture)));
-                        mouseImage.setTouchable(Touchable.enabled);
-                        tcd.hide();
-                    }
-                }, MOUSE_DIALOG_DURATION);
+                String textKey = TrophyHelper.MouseTexts.getMouseText(trophiesCount);
+                String actualText = textKey == null ? null : getText(textKey);
+                showMouseDialog(actualText);
             }
         });
 
         foregroundGroup.addActor(mouseImage);
     }
 
+    private void handleMouseRankUpDialog() {
+        long rankUpTime = UserRankManager.getInstance().getLastTimeRankedUp(getSelectedUser());
+        long visitTime  = ScreenDAO.getScreenLastVisitTime(getSelectedUser().getId(), getClass().getName());
+
+        long timeInMs = rankUpTime - visitTime;
+
+        if(timeInMs > 0  && (visitTime == 0 || timeInMs <= MOUSE_RANK_UP_TIMEOUT)) {
+            Log.info(getClass(), "User: " + getSelectedUser().getName() + " has ranked up since the last visit of " + getClass().getSimpleName());
+
+            showMouseDialog(getText(TrophyHelper.MouseTexts.MOUSE_RANKUP_TEXT));
+        }
+    }
+
+    private void showMouseDialog(String text) {
+        final Timer timer = new Timer();
+
+        if(text != null) {
+            float imageWidth = mouseImage.getWidth() * mouseImage.getScaleX();
+            float imageHeight = mouseImage.getHeight() * mouseImage.getScaleY();
+
+            float dialogX = mouseImage.getX() - scrollPane.getScrollX() + imageWidth / 2f;
+            float dialogY = mouseImage.getY() + imageHeight / 2f;
+
+            ArrayList<TablexiaDialogComponentAdapter> components = new ArrayList<TablexiaDialogComponentAdapter>();
+            components.add(new TouchCloseDialogComponent(new TouchCloseDialogComponent.TouchListener() {
+                @Override
+                public boolean dialogTouched(float x, float y, TablexiaComponentDialog dialog) {
+                    hideMouse();
+                    timer.cancel();
+                    return true;
+                }
+            }));
+            components.add(new AdaptiveSizeDialogComponent());
+            components.add(new SpeechDialogComponent(new Point(dialogX, dialogY), MOUSE_DIALOG_OFFSET, SpeechDialogComponent.ArrowType.CLASSIC));
+
+            components.add(new FixedSpaceContentDialogComponent());
+            components.add(new ResizableSpaceContentDialogComponent());
+
+            components.add(new TextContentDialogComponent(text, true));
+
+            components.add(new ResizableSpaceContentDialogComponent());
+            components.add(new FixedSpaceContentDialogComponent());
+
+            ApplicationFontManager.FontType_NEW defaultFontType = TextContentDialogComponent.getDefaultFontType();
+            DistanceFieldFont font = ApplicationFontManager.getInstance().getDistanceFieldFont(defaultFontType);
+            GlyphLayout layout = new GlyphLayout();
+            layout.setText(font, text);
+
+            float padding = ComponentScaleUtil.isUnderThreshold() ? MOUSE_DIALOG_PADDING * MOUSE_DIALOG_PADDING_TRESHOLD_SCALE : MOUSE_DIALOG_PADDING;
+            float dialogWidth = layout.width * defaultFontType.getScale() + 2 * padding;
+            float dialogHeight = layout.height;
+
+            final TablexiaComponentDialog tcd = TablexiaComponentDialogFactory.getInstance().createDialog(
+                    getStage(),
+                    TablexiaComponentDialog.TablexiaDialogType.BUBBLE_ROUNDED,
+                    components.toArray(new TablexiaDialogComponentAdapter[]{}));
+            tcd.show(dialogWidth, dialogHeight);
+
+            timer.schedule(new TimerTask() {
+                @Override
+                public void run() {
+                    hideMouse();
+                    tcd.hide();
+                }
+            }, MOUSE_DIALOG_DURATION);
+
+            showMouse(false);
+        }
+        else {
+            showMouse(true);
+
+            timer.schedule(new TimerTask() {
+                @Override
+                public void run() {
+                    hideMouse();
+                }
+            }, MOUSE_CHEESE_ANIM_DURATION);
+        }
+    }
+
+    private void hideMouse() {
+        final TextureRegion mouseTexture = getScreenTextureRegion(HallOfFameAssets.HALL_OF_FAME_MOUSE_UNPRESSED);
+        mouseImage.setDrawable(new SpriteDrawable(new Sprite(mouseTexture)));
+        mouseImage.setTouchable(Touchable.enabled);
+    }
+
+    private void showMouse(boolean cheese) {
+        TextureRegion mousePressedTexture;
+
+        if(cheese)
+            mousePressedTexture = getScreenTextureRegion(HallOfFameAssets.HALL_OF_FAME_MOUSE_CHEESE);
+        else
+            mousePressedTexture = getScreenTextureRegion(HallOfFameAssets.HALL_OF_FAME_MOUSE_PRESSED);
+
+        mouseImage.setDrawable(new SpriteDrawable(new Sprite(mousePressedTexture)));
+        mouseImage.setTouchable(Touchable.disabled);
+    }
+
     private void prepareCarpet() {
         final TextureRegion carpetTexture = getScreenTextureRegion(HallOfFameAssets.HALL_OF_FAME_CARPET);
         final Image carpetImage = new Image(carpetTexture);
diff --git a/core/src/cz/nic/tablexia/screen/halloffame/assets/HallOfFameAssets.java b/core/src/cz/nic/tablexia/screen/halloffame/assets/HallOfFameAssets.java
index 72c7cf5a53890a6e071376860befa82f35be5904..bdd8779d204064a3d91614824c230fea8d2fbcee 100644
--- a/core/src/cz/nic/tablexia/screen/halloffame/assets/HallOfFameAssets.java
+++ b/core/src/cz/nic/tablexia/screen/halloffame/assets/HallOfFameAssets.java
@@ -16,10 +16,12 @@ public final class HallOfFameAssets {
     public static final String HALL_OF_FAME_DOOR_BUTTON_UNPRESSED   = HALL_OF_FAME_ASSET_PREFIX + "background_door_unpressed";
     public static final String HALL_OF_FAME_WALL                    = HALL_OF_FAME_ASSET_PREFIX + "wall";
 
+    public static final String HALL_OF_FAME_MOUSE_CHEESE        = HALL_OF_FAME_ASSET_PREFIX + "mouse_cheese_pressed";
     public static final String HALL_OF_FAME_MOUSE_PRESSED       = HALL_OF_FAME_ASSET_PREFIX + "mouse_pressed";
     public static final String HALL_OF_FAME_MOUSE_UNPRESSED     = HALL_OF_FAME_ASSET_PREFIX + "mouse_unpressed";
     public static final String HALL_OF_FAME_CARPET              = HALL_OF_FAME_ASSET_PREFIX + "background_carpet";
     public static final String HALL_OF_FAME_DIALOG_BANNER       = HALL_OF_FAME_ASSET_PREFIX + "dialog_banner";
+    public static final String HALL_OF_FAME_BADGE_BOARD         = HALL_OF_FAME_ASSET_PREFIX + "badgeboard";
 
     public static final String HALL_OF_FAME_TROPHY_HEAP_00 = HALL_OF_FAME_TROPHY_PATH + HALL_OF_FAME_ASSET_PREFIX + HALL_OF_FAME_ASSET_TROPHYHEAP + "00";
     public static final String HALL_OF_FAME_TROPHY_HEAP_01 = HALL_OF_FAME_TROPHY_PATH + HALL_OF_FAME_ASSET_PREFIX + HALL_OF_FAME_ASSET_TROPHYHEAP + "01";
@@ -39,4 +41,7 @@ public final class HallOfFameAssets {
     public static final String HALL_OF_FAME_TROPHY_HEAP_40 = HALL_OF_FAME_TROPHY_PATH + HALL_OF_FAME_ASSET_PREFIX + HALL_OF_FAME_ASSET_TROPHYHEAP + "40";
     public static final String HALL_OF_FAME_TROPHY_HEAP_50 = HALL_OF_FAME_TROPHY_PATH + HALL_OF_FAME_ASSET_PREFIX + HALL_OF_FAME_ASSET_TROPHYHEAP + "50";
     public static final String HALL_OF_FAME_TROPHY_HEAP_60 = HALL_OF_FAME_TROPHY_PATH + HALL_OF_FAME_ASSET_PREFIX + HALL_OF_FAME_ASSET_TROPHYHEAP + "60";
+
+    public static final String TEXT_BADGE_CABINET_LIST     = "badge_cabinet_list";
+    public static final String TEXT_BADGE_CABINET_LOCKED   = "badge_cabinet_locked";
 }
diff --git a/core/src/cz/nic/tablexia/screen/halloffame/trophy/TrophyHelper.java b/core/src/cz/nic/tablexia/screen/halloffame/trophy/TrophyHelper.java
index efaea13eee6001de73b870779cddfa7da76f7d88..3b4bae741383ec96eac88e3a392fa77cbe1a1e16 100644
--- a/core/src/cz/nic/tablexia/screen/halloffame/trophy/TrophyHelper.java
+++ b/core/src/cz/nic/tablexia/screen/halloffame/trophy/TrophyHelper.java
@@ -191,6 +191,8 @@ public class TrophyHelper {
         MOUSE_TEXTS_20      (9999,  "mouse_20_1", "mouse_20_2", "mouse_20_3", "mouse_20_4");
         //TODO - Integer.MAX_VALUE ???
 
+        public static final String MOUSE_RANKUP_TEXT = "mouse_rankup";
+
         private String[] texts;
         private int numOfStars;
         private int actualIndex = 0;
@@ -201,11 +203,14 @@ public class TrophyHelper {
         }
 
         public String getNextText() {
-            String text = texts[actualIndex];
-            if (actualIndex < texts.length - 1) {
+            String result = null;
+
+            if (actualIndex < texts.length) {
+                result = texts[actualIndex];
                 actualIndex++;
             }
-            return text;
+
+            return result;
         }
 
         public int getNumOfStars() {
diff --git a/core/src/cz/nic/tablexia/screen/loader/LoaderScreen.java b/core/src/cz/nic/tablexia/screen/loader/LoaderScreen.java
index e1f3699f98c2e6f21a6ee2852dfc44047a4d3996..a14b93d583b8d4f26ceed8ba76d62e5fb4e77f65 100644
--- a/core/src/cz/nic/tablexia/screen/loader/LoaderScreen.java
+++ b/core/src/cz/nic/tablexia/screen/loader/LoaderScreen.java
@@ -375,6 +375,11 @@ public class LoaderScreen extends AbstractTablexiaScreen<Void> {
         loadingStatusText.addAction(new SequenceAction(Actions.fadeOut(time), Actions.visible(false)));
     }
 
+    @Override
+    public boolean hasSoftBackButton() {
+        return false;
+    }
+
     @Override
     protected void screenDisposed() {
         super.screenDisposed();
diff --git a/core/src/cz/nic/tablexia/screen/profile/ProfileScreen.java b/core/src/cz/nic/tablexia/screen/profile/ProfileScreen.java
index bf9202c612551d49d9cfe7b14616d74e6d0972c2..62f4cc8c3716df29aa358f8abdf94015b1f2ca80 100644
--- a/core/src/cz/nic/tablexia/screen/profile/ProfileScreen.java
+++ b/core/src/cz/nic/tablexia/screen/profile/ProfileScreen.java
@@ -2,33 +2,50 @@ package cz.nic.tablexia.screen.profile;
 
 import com.badlogic.gdx.graphics.Color;
 import com.badlogic.gdx.graphics.g2d.TextureRegion;
-import com.badlogic.gdx.scenes.scene2d.InputEvent;
-import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
+import com.badlogic.gdx.scenes.scene2d.Actor;
+import com.badlogic.gdx.scenes.scene2d.Group;
+import com.badlogic.gdx.scenes.scene2d.ui.Image;
 import com.badlogic.gdx.scenes.scene2d.utils.Drawable;
 import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
 import com.badlogic.gdx.utils.Align;
 
 import java.util.Map;
 
+import cz.nic.tablexia.game.ranksystem.UserRankManager;
+import cz.nic.tablexia.loader.application.ApplicationAtlasManager;
 import cz.nic.tablexia.loader.application.ApplicationFontManager;
+import cz.nic.tablexia.loader.application.ApplicationTextManager;
 import cz.nic.tablexia.menu.user.UserAvatarDefinition;
 import cz.nic.tablexia.screen.createuser.FormScreen;
 import cz.nic.tablexia.shared.model.User;
+import cz.nic.tablexia.util.ScaleUtil;
 import cz.nic.tablexia.util.ui.TablexiaLabel;
-import cz.nic.tablexia.util.ui.button.CloseTablexiaButton;
-import cz.nic.tablexia.util.ui.button.TablexiaButton;
+import cz.nic.tablexia.util.ui.TablexiaProgressBar;
 
 public class ProfileScreen extends FormScreen {
-    private static final String USER_UUID_ERROR            = "user_uuid_error";
-    private static final String USER_UUID_DESCRIPTION_TEXT = "user_uuid_description";
+    private static final String PROGRESS_BAR_FILL             = "gfx/progressbar_fill";
+    private static final float  PROGRESS_BAR_WIDTH            = 0.8f;
+    private static final float  PROGRESS_BAR_BOTTOM_OFFSET    = 0.28f;
+    private static final float  PROGRESS_BAR_SPEED            = 3.0f;
 
-    private static final float  BADGE_POSITON_Y_SCALE = 0.35f;
-    private static final float  USER_UUID_DESCRIPTION_POSITION_Y_SCALE = 0.135f;
-    private static final float  USER_UUID_POSITION_Y_SCALE = 0.1f;
-    private static final float  USER_UUID_PADDING = 0.055f; //Percent from page width
-    private static final int    CLOSE_BUTTON_PADDING = 20;
+    private static final ApplicationFontManager.FontType_NEW RANK_NAME_FONT_TYPE = ApplicationFontManager.FontType_NEW.BOLD_20;
 
-    private TablexiaButton      closeButton;
+    private static final String PROGRESS_STATUS_ARROW         = "gfx/progress_arrow";
+    private static final float  PROGRESS_STATUS_WIDTH         = 0.8f;
+    private static final float  PROGRESS_STATUS_ARROWS_WIDTH  = 0.45f;
+    private static final float  PROGRESS_STATUS_BADGE_HEIGHT   = 0.2f;
+    private static final float  PROGRESS_STATUS_BOTTOM_OFFSET = 0.33f;
+
+    private static final String USER_UUID_ERROR               = "user_uuid_error";
+    private static final String USER_UUID_DESCRIPTION_TEXT    = "user_uuid_description";
+
+    private static final float  BADGE_HEIGHT                            = 0.4f;
+    private static final float  BADGE_POSITON_Y_SCALE                   = 0.52f;
+    private static final float  USER_UUID_DESCRIPTION_POSITION_Y_SCALE  = 0.08f;
+    private static final float  USER_UUID_POSITION_Y_SCALE              = 0.05f;
+    private static final float  USER_UUID_PADDING                       = 0.055f; //Percent from page width
+
+    private TablexiaProgressBar progressBar;
 
     @Override
     protected void screenLoaded(Map<String, String> screenState) {
@@ -45,6 +62,8 @@ public class ProfileScreen extends FormScreen {
         switchGender.setVisible(false);
         clearName.setVisible(false);
 
+        badge.setY(getSceneInnerBottomY() + getSceneInnerHeight() * BADGE_POSITON_Y_SCALE);
+
         Drawable d = new TextureRegionDrawable(new TextureRegion(getApplicationTextureRegion(UserAvatarDefinition.getAvatar(getSelectedUser().getAvatar()))));
         mugshotImage.setDrawable(d);
         nameField.setText(getSelectedUser().getName());
@@ -58,11 +77,9 @@ public class ProfileScreen extends FormScreen {
         signaturePane.setSignature(getSelectedUser().getSignature());
         stampIt();
 
-        closeButton = createCloseButton();
-        getStage().addActor(closeButton);
-        positionCloseButton();
+        prepareProgressBar();
+        prepareProgressStatus();
 
-        badge.setY(getViewportHeight() * BADGE_POSITON_Y_SCALE);
         getStage().addActor(createUserUuidDescription());
 
         TablexiaLabel userUuidLabel = createUserUuidLabel();
@@ -70,10 +87,14 @@ public class ProfileScreen extends FormScreen {
             getStage().addActor(createUserUuidLabel());
     }
 
+    @Override
+    public boolean hasSoftBackButton() {
+        return true;
+    }
+
     @Override
     protected void screenResized(int width, int height) {
         super.screenResized(width, height);
-        positionCloseButton();
     }
 
     @Override
@@ -86,22 +107,6 @@ public class ProfileScreen extends FormScreen {
         return "form";
     }
 
-    private TablexiaButton createCloseButton() {
-        return new CloseTablexiaButton()
-                .setInputListener(new ClickListener() {
-
-                    @Override
-                    public void clicked(InputEvent event, float x, float y) {
-                        super.clicked(event, x, y);
-                        backToInitialScreen();
-                    }
-                });
-    }
-
-    private void positionCloseButton() {
-        closeButton.setButtonPosition(getViewportLeftX() + CLOSE_BUTTON_PADDING, getViewportBottomY() + CLOSE_BUTTON_PADDING);
-    }
-
     private TablexiaLabel createUserUuidDescription() {
         TablexiaLabel resultLabel;
 
@@ -136,8 +141,71 @@ public class ProfileScreen extends FormScreen {
         return label;
     }
 
-    private float getCenterXOfPageForLabel(float labelWidth) {
-        return ((book.getWidth() / 2) - labelWidth) / 2 + book.getX();
+    @Override
+    protected Actor prepareBadge() {
+        UserRankManager.UserRank rank = UserRankManager.getInstance().getRank(getSelectedUser());
+        badge = ScaleUtil.createImageToHeight(ApplicationAtlasManager.getInstance().getTextureRegion(rank.getBadgeImageKey()), BADGE_HEIGHT * getSceneInnerHeight());
+        float pageWidth = (book.getWidth()/2);
+        badge.setPosition(book.getX() + pageWidth/2 - badge.getWidth()/2, badge.getY());
+        return badge;
+    }
+
+    private void prepareProgressBar() {
+        this.progressBar = new TablexiaProgressBar(
+                ApplicationAtlasManager.getInstance().getTextureRegion(ApplicationAtlasManager.PROGRESS_BAR),
+                getScreenTextureRegion(PROGRESS_BAR_FILL)
+        );
+
+        float pageWidth = book.getWidth() / 2f;
+
+        this.progressBar.setWidth(pageWidth * PROGRESS_BAR_WIDTH);
+        this.progressBar.setPosition(
+                book.getX() + (pageWidth / 2f) - (progressBar.getWidth() / 2),
+                book.getY() + book.getHeight() * PROGRESS_BAR_BOTTOM_OFFSET
+        );
+
+        UserRankManager.RankProgress resultRankProgress = UserRankManager.getInstance().getTotalUserRankProgress(getSelectedUser());
+
+        this.progressBar.setSmooth(false);
+        this.progressBar.setPercent(0);
+        this.progressBar.setSmooth(true);
+        this.progressBar.setSpeed(PROGRESS_BAR_SPEED);
+        this.progressBar.setPercent(resultRankProgress.getPercentDone());
+
+        getStage().addActor(progressBar);
+    }
+
+    private void prepareProgressStatus () {
+        final float pageWidth = book.getWidth()/2f;
+        final float groupWidth = pageWidth * PROGRESS_STATUS_WIDTH;
+
+        Group group = new Group();
+        group.setWidth(groupWidth);
+        group.setPosition(book.getX() + pageWidth/2f - group.getWidth()/2f, book.getY() + book.getHeight() * PROGRESS_STATUS_BOTTOM_OFFSET);
+
+        UserRankManager.UserRank currRank = UserRankManager.getInstance().getRank(getSelectedUser());
+        UserRankManager.UserRank nextRank = UserRankManager.UserRank.getNextRank(currRank);
+
+        Image currBadge = ScaleUtil.createImageToHeight(ApplicationAtlasManager.getInstance().getTextureRegion(currRank.getBadgeIconKey()), PROGRESS_STATUS_BADGE_HEIGHT * groupWidth);
+        group.addActor(currBadge);
+
+        Image progress = ScaleUtil.createImageToWidth(getScreenTextureRegion(PROGRESS_STATUS_ARROW), PROGRESS_STATUS_ARROWS_WIDTH * groupWidth);
+        progress.setPosition(group.getWidth()/2 - progress.getWidth()/2, currBadge.getY() + currBadge.getHeight()/2 - progress.getHeight()/2);
+        group.addActor(progress);
+
+        Image nextBadge = ScaleUtil.createGreyScaleImageToHeight(ApplicationAtlasManager.getInstance().getTextureRegion(nextRank.getBadgeIconKey()), PROGRESS_STATUS_BADGE_HEIGHT * groupWidth);
+        nextBadge.setX(group.getWidth() - nextBadge.getWidth());
+        group.addActor(nextBadge);
+
+        if(currRank.hasBadgeName()) {
+            TablexiaLabel rankName = new TablexiaLabel(ApplicationTextManager.getInstance().getText(currRank.getNameKey()), new TablexiaLabel.TablexiaLabelStyle(RANK_NAME_FONT_TYPE, Color.BLACK));
+            rankName.setSize(group.getWidth(), rankName.getHeight());
+            rankName.setAlignment(Align.center);
+            rankName.setY(progress.getY() + progress.getHeight());
+            group.addActor(rankName);
+        }
+
+        getStage().addActor(group);
     }
 
 	@Override
diff --git a/core/src/cz/nic/tablexia/screen/statistics/StatisticsScreen.java b/core/src/cz/nic/tablexia/screen/statistics/StatisticsScreen.java
index c8059c9ddabf13f85aa97b7ba8d98d7cda1fd8b5..595202620bd162613a4290e0050696b756ff07fe 100644
--- a/core/src/cz/nic/tablexia/screen/statistics/StatisticsScreen.java
+++ b/core/src/cz/nic/tablexia/screen/statistics/StatisticsScreen.java
@@ -48,7 +48,6 @@ import cz.nic.tablexia.util.ui.ClickListenerWithSound;
 import cz.nic.tablexia.util.ui.Switch;
 import cz.nic.tablexia.util.ui.TablexiaLabel;
 import cz.nic.tablexia.util.ui.TablexiaNoBlendingImage;
-import cz.nic.tablexia.util.ui.button.CloseTablexiaButton;
 import cz.nic.tablexia.util.ui.button.TablexiaButton;
 import cz.nic.tablexia.util.ui.dialog.TablexiaComponentDialog;
 import cz.nic.tablexia.util.ui.dialog.TablexiaComponentDialogFactory;
@@ -69,7 +68,6 @@ public class StatisticsScreen extends AbstractTablexiaScreen<Void> {
     private static final float      GRAPH_DIALOG_HEIGHT = 180;
 
     private static final float COMPONENTS_PADDING = 10f, COMPONENTS_THRESHOLD_PADDING = 52f, TITLE_PADDING = 50f;
-    private static final float CLOSE_BUTTON_POSITION = 25f;
     private static final float DRAWER_SCALE = 0.6f;
     private static final float SWITCH_GRAPH_POSITION_X_SCALE = 0.30f, SWITCH_GRAPH_POSITION_Y_SCALE = 0.88f, SWITCH_GRAPH_PADDING_X = 52f, SWITCH_GRAPH_PADDING_Y = 5f;
     private static final float DIFFICULTIES_SCALE = 0.8f, DIFFICULTIES_POSITION_X_SCALE = 0.63f, DIFFICULTIES_POSITION_Y_SCALE = 0.9f;
@@ -87,7 +85,6 @@ public class StatisticsScreen extends AbstractTablexiaScreen<Void> {
     private Group content;
     private Image background;
     private TablexiaLabel titleLabel;
-    private TablexiaButton buttonClose;
     private Image imageDrawer;
     private WidgetGroup switchGraphType;
     private Container<Group> notebook;
@@ -105,6 +102,11 @@ public class StatisticsScreen extends AbstractTablexiaScreen<Void> {
     private Map<GameDifficulty, TablexiaButton> difficultyButtons;
     private TablexiaComponentDialog dialog;
 
+    @Override
+    public boolean hasSoftBackButton() {
+        return true;
+    }
+
     @Override
     protected void screenPaused(Map<String, String> screenState) {
         screenState.put(DIFFICULTY_EASY_KEY, String.valueOf(selectedGameDifficulties.contains(GameDifficulty.EASY)));
@@ -121,7 +123,6 @@ public class StatisticsScreen extends AbstractTablexiaScreen<Void> {
 
         content.addActor(background = new TablexiaNoBlendingImage(getApplicationTextureRegion(ApplicationAtlasManager.BACKGROUND_WOODEN)));
         content.addActor(titleLabel = new TablexiaLabel(getText("statistics_label"), new TablexiaLabel.TablexiaLabelStyle(TITLE_FONT_TYPE, Color.BLACK)));
-        content.addActor(buttonClose = new CloseTablexiaButton().setInputListener(closeClickListener));
 
         content.addActor(imageDrawer = new Image(getScreenTextureRegion(GFX_PATH + "cardfile")));
         // TODO move in action??
@@ -335,15 +336,6 @@ public class StatisticsScreen extends AbstractTablexiaScreen<Void> {
         }
     };
 
-    private InputListener closeClickListener = new ClickListener() {
-
-        @Override
-        public void clicked(InputEvent event, float x, float y) {
-            super.clicked(event, x, y);
-            backToInitialScreen();
-        }
-    };
-
     private InputListener difficultyClickListener = new ClickListener() {
 
         @Override
@@ -620,7 +612,6 @@ public class StatisticsScreen extends AbstractTablexiaScreen<Void> {
     public void position() {
         titleLabel.setPosition(TITLE_PADDING, getStage().getHeight() - TITLE_PADDING);
         background.setBounds(0, 0, getStage().getWidth(), getStage().getHeight());
-        buttonClose.setPosition(CLOSE_BUTTON_POSITION, CLOSE_BUTTON_POSITION);
         ScaleUtil.setImageHeight(imageDrawer, getStage().getHeight() * DRAWER_SCALE);
         imageDrawer.setPosition(0, (getStage().getHeight() / 2) - (imageDrawer.getHeight() / 2));
         switchGraphType.setPosition(getStage().getWidth() * SWITCH_GRAPH_POSITION_X_SCALE, getStage().getHeight() * SWITCH_GRAPH_POSITION_Y_SCALE);
diff --git a/core/src/cz/nic/tablexia/sync/work/DownloadUser.java b/core/src/cz/nic/tablexia/sync/work/DownloadUser.java
index c98b35b2069d94487d155102b894ba310f866d93..4b2155ceacb61d973ada8371c86dd66d89142b2c 100644
--- a/core/src/cz/nic/tablexia/sync/work/DownloadUser.java
+++ b/core/src/cz/nic/tablexia/sync/work/DownloadUser.java
@@ -5,6 +5,7 @@ import com.badlogic.gdx.net.HttpRequestHeader;
 import com.badlogic.gdx.net.HttpStatus;
 import com.badlogic.gdx.utils.Json;
 
+import cz.nic.tablexia.game.ranksystem.UserRankManager;
 import cz.nic.tablexia.model.UserDAO;
 import cz.nic.tablexia.shared.model.User;
 import cz.nic.tablexia.sync.RestSynchronizationService;
@@ -50,6 +51,8 @@ public class DownloadUser extends SyncWork {
 
         setUser(user);
 
+        UserRankManager.getInstance().forceRefreshUserRank(user);
+
         Log.debug(this.getClass(), "Duration: " + getTime(start, finish));
     }
 
diff --git a/core/src/cz/nic/tablexia/util/MusicUtil.java b/core/src/cz/nic/tablexia/util/MusicUtil.java
index c9e381e0cadba3b9cac2d3022802d9df2253738c..2a8df99c5b453d0f21eae68396da935f4ac9f25d 100644
--- a/core/src/cz/nic/tablexia/util/MusicUtil.java
+++ b/core/src/cz/nic/tablexia/util/MusicUtil.java
@@ -13,9 +13,17 @@ public class MusicUtil {
     public static final float MAX_EFFECT_DURATION     =   5;
 
 	public static void fadeOut(final Music music, float time) {
-		fadeOut(music, time, true);
+		fadeOut(music, time, null, true);
 	}
 
+    public static void fadeOut(final Music music, float time, boolean dispose) {
+        fadeOut(music, time, null, dispose);
+    }
+
+    public static void fadeOut(final Music music, float time, Music.OnCompletionListener completionListener) {
+        fadeOut(music, time, completionListener, true);
+    }
+
 	public static void fadeIn(final Music music, float time) {
 		fadeIn(music, time, true);
 	}
@@ -26,7 +34,7 @@ public class MusicUtil {
      * @param music Music you want to apply the effect to
      * @param time Duration of the effect in seconds
      */
-    public static void fadeOut(final Music music, float time, final boolean dispose) {
+    public static void fadeOut(final Music music, float time, final Music.OnCompletionListener completionListener, final boolean dispose) {
         //Wrong arguments ? return...
         if(music == null || music.getVolume() <= 0 || !music.isPlaying()) return;
 
@@ -53,7 +61,8 @@ public class MusicUtil {
                     float volume = MathUtils.clamp(currentVolume - volumeStep, 0, 1);
 
                     if(volume <= endVolume) {
-						music.stop();
+                        music.stop();
+                        if(completionListener != null) completionListener.onCompletion(music);
 						if(dispose) music.dispose();
 						cancel();
 					}
@@ -113,4 +122,4 @@ public class MusicUtil {
             }
         }, 0, SOUND_EFFECT_INTERVAL, repeatCount);
     }
-}
+}
\ No newline at end of file
diff --git a/core/src/cz/nic/tablexia/util/ScaleUtil.java b/core/src/cz/nic/tablexia/util/ScaleUtil.java
index 9a7ba19128aba1544a815fdf1f1df6af1a2036c2..5bde2b7b733940f804a957c5374549871ecb08d4 100644
--- a/core/src/cz/nic/tablexia/util/ScaleUtil.java
+++ b/core/src/cz/nic/tablexia/util/ScaleUtil.java
@@ -7,6 +7,7 @@ import com.badlogic.gdx.scenes.scene2d.Stage;
 import com.badlogic.gdx.scenes.scene2d.ui.Image;
 
 import cz.nic.tablexia.TablexiaSettings;
+import cz.nic.tablexia.util.ui.TablexiaGreyScaleImage;
 import cz.nic.tablexia.util.ui.TablexiaNoBlendingImage;
 
 /**
@@ -120,6 +121,12 @@ public class ScaleUtil {
         return image;
     }
 
+    public static TablexiaGreyScaleImage createGreyScaleImageToWidth(TextureRegion textureRegion, float width) {
+        TablexiaGreyScaleImage image = new TablexiaGreyScaleImage(textureRegion);
+        image.setSize(width, getHeight(textureRegion.getRegionWidth(), textureRegion.getRegionHeight(), width));
+        return image;
+    }
+
     public static Image createImageToWidthWithPosition(TextureRegion textureRegion, float width, float positionX, float positionY) {
         Image image = createImageToWidth(textureRegion, width);
         image.setPosition(positionX, positionY);
@@ -138,6 +145,12 @@ public class ScaleUtil {
         return image;
     }
 
+    public static TablexiaGreyScaleImage createGreyScaleImageToHeight(TextureRegion textureRegion, float height) {
+        TablexiaGreyScaleImage image = new TablexiaGreyScaleImage(textureRegion);
+        image.setSize(getWidth(textureRegion.getRegionWidth(), textureRegion.getRegionHeight(), height), height);
+        return image;
+    }
+
     public static TablexiaNoBlendingImage createNoBlendingImageToHeight(TextureRegion textureRegion, float height) {
         TablexiaNoBlendingImage image = new TablexiaNoBlendingImage(textureRegion);
         setImageHeight(image, height);
diff --git a/core/src/cz/nic/tablexia/util/actions/MoveAlongAction.java b/core/src/cz/nic/tablexia/util/actions/MoveAlongAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..e8e34373ddbac98980e757c600c218a5ccb347d2
--- /dev/null
+++ b/core/src/cz/nic/tablexia/util/actions/MoveAlongAction.java
@@ -0,0 +1,56 @@
+package cz.nic.tablexia.util.actions;
+
+import com.badlogic.gdx.math.Path;
+import com.badlogic.gdx.math.Vector2;
+import com.badlogic.gdx.scenes.scene2d.actions.TemporalAction;
+
+/** Moves an actor along a path.
+ * @author Justin Shapcott */
+public class MoveAlongAction extends TemporalAction {
+    private float x, y;
+    private boolean rotate;
+    private Path<Vector2> path;
+    private Vector2 value = new Vector2();
+
+    public MoveAlongAction(Path<Vector2> path, float duration) {
+        setPath(path);
+        setDuration(duration);
+    }
+
+    public Path<Vector2> getPath () {
+        return path;
+    }
+
+    public void setPath (Path<Vector2> path) {
+        this.path = path;
+    }
+
+    public boolean isRotate() {
+        return rotate;
+    }
+
+    public void setRotate (boolean rotate) {
+        this.rotate = rotate;
+    }
+
+    @Override
+    protected void begin () {
+        x = actor.getX();
+        y = actor.getY();
+    }
+
+    @Override
+    protected void update (float percent) {
+        path.valueAt(value, percent);
+        actor.setPosition(x + value.x, y + value.y);
+        if (rotate) {
+            actor.setRotation(path.derivativeAt(value, percent).angle());
+        }
+    }
+
+    @Override
+    public void reset () {
+        super.reset();
+        path = null;
+    }
+}
\ No newline at end of file
diff --git a/core/src/cz/nic/tablexia/util/ui/TablexiaGreyScaleImage.java b/core/src/cz/nic/tablexia/util/ui/TablexiaGreyScaleImage.java
new file mode 100644
index 0000000000000000000000000000000000000000..f446499e4e5bebbd096eec2a98e20897371acf44
--- /dev/null
+++ b/core/src/cz/nic/tablexia/util/ui/TablexiaGreyScaleImage.java
@@ -0,0 +1,67 @@
+package cz.nic.tablexia.util.ui;
+
+import com.badlogic.gdx.graphics.g2d.Batch;
+import com.badlogic.gdx.graphics.g2d.TextureRegion;
+import com.badlogic.gdx.graphics.glutils.ShaderProgram;
+import com.badlogic.gdx.scenes.scene2d.ui.Image;
+
+/**
+ * Created by drahomir on 5/13/16.
+ */
+public class TablexiaGreyScaleImage extends Image {
+    //Default vertex shader which can be found in SpriteBatch.createDefaultShader() method
+    private static String vertexShader =
+            "attribute vec4 " + ShaderProgram.POSITION_ATTRIBUTE + ";\n" //
+            + "attribute vec4 " + ShaderProgram.COLOR_ATTRIBUTE + ";\n" //
+            + "attribute vec2 " + ShaderProgram.TEXCOORD_ATTRIBUTE + "0;\n" //
+            + "uniform mat4 u_projTrans;\n" //
+            + "varying vec4 v_color;\n" //
+            + "varying vec2 v_texCoords;\n" //
+            + "\n" //
+            + "void main()\n" //
+            + "{\n" //
+            + "   v_color = " + ShaderProgram.COLOR_ATTRIBUTE + ";\n" //
+            + "   v_color.a = v_color.a * (255.0/254.0);\n" //
+            + "   v_texCoords = " + ShaderProgram.TEXCOORD_ATTRIBUTE + "0;\n" //
+            + "   gl_Position =  u_projTrans * " + ShaderProgram.POSITION_ATTRIBUTE + ";\n" //
+            + "}\n";
+
+    //Edited fragment shader from SpriteBatch.createDefaultShader() method
+    private static String fragmentShader =
+            "#ifdef GL_ES\n" //
+            + "#define LOWP lowp\n" //
+            + "precision mediump float;\n" //
+            + "#else\n" //
+            + "#define LOWP \n" //
+            + "#endif\n" //
+            + "varying LOWP vec4 v_color;\n" //
+            + "varying vec2 v_texCoords;\n" //
+            + "uniform sampler2D u_texture;\n" //
+            + "void main()\n"//
+            + "{\n" //
+            + "  vec4 color = v_color * texture2D(u_texture, v_texCoords);\n" //gets actual color
+            + "  float grey = dot(color.rgb, vec3(0.299, 0.587, 0.114));\n"   //computes grey value
+            + "  gl_FragColor = vec4(grey, grey, grey, color.w);\n"           //outputs grey color (color.w is original transparency)
+            + "}";
+
+    private static ShaderProgram greyScaleShader;
+
+    public TablexiaGreyScaleImage(TextureRegion textureRegion) {
+        super(textureRegion);
+
+        if(greyScaleShader == null)
+            initializeShader();
+    }
+
+    private static void initializeShader() {
+        greyScaleShader = new ShaderProgram(vertexShader, fragmentShader);
+        if(!greyScaleShader.isCompiled()) throw new RuntimeException("Couldn't compile GreyScale shader! Compile log: " + greyScaleShader.getLog());
+    }
+
+    @Override
+    public void draw(Batch batch, float parentAlpha) {
+        batch.setShader(greyScaleShader);
+            super.draw(batch, parentAlpha);
+        batch.setShader(null); //use default shader
+    }
+}
diff --git a/core/src/cz/nic/tablexia/util/ui/TablexiaProgressBar.java b/core/src/cz/nic/tablexia/util/ui/TablexiaProgressBar.java
new file mode 100644
index 0000000000000000000000000000000000000000..1ff0f61d1096db4470c45252815036953e2d78a2
--- /dev/null
+++ b/core/src/cz/nic/tablexia/util/ui/TablexiaProgressBar.java
@@ -0,0 +1,118 @@
+package cz.nic.tablexia.util.ui;
+
+import com.badlogic.gdx.graphics.g2d.Batch;
+import com.badlogic.gdx.graphics.g2d.TextureRegion;
+import com.badlogic.gdx.math.MathUtils;
+import com.badlogic.gdx.scenes.scene2d.Actor;
+
+public class TablexiaProgressBar extends Actor {
+    private float fillOffsetX;
+    private float fillOffsetY;
+
+    private float percent;
+    private float visualPercent;
+    private float speed;
+    private boolean smooth;
+
+    private TextureRegion progressbar;
+    private TextureRegion fill;
+
+    public TablexiaProgressBar(TextureRegion progressbar, TextureRegion fill) {
+        this.progressbar = progressbar;
+        this.fill = fill;
+
+        setWidth(progressbar.getRegionWidth());
+    }
+
+    @Override
+    public void setWidth(float width) {
+        float height = width * (progressbar.getRegionHeight() / (float) progressbar.getRegionWidth());
+
+        super.setSize(width, height);
+
+        float scale_x = width / progressbar.getRegionWidth();
+        float scale_y = height / progressbar.getRegionHeight();
+
+        fillOffsetX = (this.progressbar.getRegionWidth()  - this.fill.getRegionWidth()) / 2 * scale_x;
+        fillOffsetY = (this.progressbar.getRegionHeight() - this.fill.getRegionHeight()) / 2 * scale_y;
+    }
+
+    @Override
+    public void setHeight(float height) {}
+
+    @Override
+    public void setBounds(float x, float y, float width, float height) {
+        setPosition(x, y);
+        setWidth(width);
+    }
+
+    @Override
+    @Deprecated
+    public void setSize(float width, float height) {
+        setWidth(width);
+    }
+
+    @Override
+    public void act(float delta) {
+        super.act(delta);
+
+        if(smooth) {
+            if (visualPercent < percent) {
+                visualPercent += 1/speed * delta;
+
+                if (visualPercent > percent) visualPercent = percent;
+            } else if (visualPercent > percent) {
+                visualPercent -= 1/speed * delta;
+
+                if (visualPercent < percent) visualPercent = percent;
+            }
+        }
+    }
+
+    public void setPercent(float percent) {
+        this.percent = MathUtils.clamp(percent, 0, 1);
+
+        if(!smooth)
+            visualPercent = this.percent;
+    }
+
+    public void setSmooth(boolean smooth) {
+        this.smooth = smooth;
+    }
+
+    public void setSpeed(float speed) {
+        this.speed = speed;
+    }
+
+    @Override
+    public void draw(Batch batch, float parentAlpha) {
+        float origAlpha = batch.getColor().a;
+
+        batch.setColor(batch.getColor().r, batch.getColor().g, batch.getColor().b, parentAlpha);
+
+        if(visualPercent != 0) {
+            int origRegionWidth = fill.getRegionWidth();
+            fill.setRegionWidth((int) (fill.getRegionWidth() * visualPercent));
+            batch.draw(
+                    fill,
+                    getX() + fillOffsetX,
+                    getY() + fillOffsetY,
+                    (getWidth() - 2 * fillOffsetX) * visualPercent,
+                    getHeight() - 2 * fillOffsetY
+            );
+            fill.setRegionWidth(origRegionWidth);
+        }
+
+        batch.draw(progressbar, getX(), getY(), getWidth(), getHeight());
+
+        batch.setColor(batch.getColor().r, batch.getColor().g, batch.getColor().b, origAlpha);
+    }
+
+    public float getFillOffsetX() {
+        return fillOffsetX;
+    }
+
+    public float getFillOffsetY() {
+        return fillOffsetY;
+    }
+}
\ No newline at end of file
diff --git a/core/src/cz/nic/tablexia/util/ui/button/CloseTablexiaButton.java b/core/src/cz/nic/tablexia/util/ui/button/CloseTablexiaButton.java
deleted file mode 100644
index 358e07e3514b3db904d7a596123f23cae59a25cd..0000000000000000000000000000000000000000
--- a/core/src/cz/nic/tablexia/util/ui/button/CloseTablexiaButton.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package cz.nic.tablexia.util.ui.button;
-
-import cz.nic.tablexia.loader.application.ApplicationInternalTextureManager;
-
-/**
- * Created by Matyáš Latner.
- */
-public class CloseTablexiaButton extends TablexiaButton {
-
-    private static final String     UNPRESSED                   = ApplicationInternalTextureManager.BUTTON_CLOSE_UNPRESSED;
-    private static final String     PRESSED                     = ApplicationInternalTextureManager.BUTTON_CLOSE_PRESSED;
-
-    private static final boolean    USE_ONCE                    = true;
-    private static final float      ADAPTIVE_SIZE_RATIO         = 1.8f;
-    private static final boolean    ADAPTIVE_SIZE_POSITION_FIX  = false;
-    private static final int        SIZE                        = 40;
-
-    public CloseTablexiaButton() {
-        super(null, false,
-                ApplicationInternalTextureManager.getInstance().getTexture(UNPRESSED),
-                ApplicationInternalTextureManager.getInstance().getTexture(PRESSED),
-                null,
-                null);
-
-        useOnce(USE_ONCE);
-        setButtonSize(SIZE, SIZE);
-        adaptiveSizeRatio(ADAPTIVE_SIZE_RATIO);
-        adaptiveSizePositionFix(ADAPTIVE_SIZE_POSITION_FIX);
-    }
-}
diff --git a/core/src/cz/nic/tablexia/util/ui/dialog/TablexiaComponentDialog.java b/core/src/cz/nic/tablexia/util/ui/dialog/TablexiaComponentDialog.java
index d984db4676d9ea1fca491eb08ed18ef6ebe07395..6e6a9bf3e7b41acc258835b886b3e525293d7e0f 100644
--- a/core/src/cz/nic/tablexia/util/ui/dialog/TablexiaComponentDialog.java
+++ b/core/src/cz/nic/tablexia/util/ui/dialog/TablexiaComponentDialog.java
@@ -37,6 +37,7 @@ public class TablexiaComponentDialog extends Stack {
         DIALOG_SQUARE(ApplicationAtlasManager.DIALOG_SQUARE, false, 0, 0, 0, 0),
         DIALOG_SQUARE_BORDERS(Tablexia.ERROR_DIALOG_BACKGROUND_INTERNAL, true, 23, 26, 18, 28),
         DIALOG_RECTANGLE(ApplicationAtlasManager.DIALOG_RECTANGLE, false, 0, 0, 0, 0),
+        DIALOG_BADGE_BOARD(ApplicationAtlasManager.DIALOG_BADGE_BOARD, false, 0, 0, 0, 0),
         DIALOG_SQUARE_SHADOW(ApplicationAtlasManager.DIALOG_BUBBLE_CLASSIC_SQUARE_SHADOW, false, 0, 0, 0 ,0);
 
         private String backgroundPath;
@@ -243,7 +244,6 @@ public class TablexiaComponentDialog extends Stack {
             tablexiaDialogComponentAdapter.beforeDraw();
         }
 
-
         //Draw components themselves
         super.draw(batch, parentAlpha);
 
diff --git a/core/src/cz/nic/tablexia/util/ui/dialog/TablexiaComponentDialogFactory.java b/core/src/cz/nic/tablexia/util/ui/dialog/TablexiaComponentDialogFactory.java
index 809bb22d6cc4cf0a1b13c910f1243cc5cd608117..3113e4b0460dfcdcaff674217985b667c89d68a8 100644
--- a/core/src/cz/nic/tablexia/util/ui/dialog/TablexiaComponentDialogFactory.java
+++ b/core/src/cz/nic/tablexia/util/ui/dialog/TablexiaComponentDialogFactory.java
@@ -68,6 +68,10 @@ public class TablexiaComponentDialogFactory implements Disposable {
         instance = new TablexiaComponentDialogFactory(stage);
     }
 
+    public static Stage getDialogStage() {
+        return getInstance().stage;
+    }
+
     @Override
     public void dispose() {
         instance = null;
diff --git a/core/src/cz/nic/tablexia/util/ui/dialog/components/CenterPositionDialogComponent.java b/core/src/cz/nic/tablexia/util/ui/dialog/components/CenterPositionDialogComponent.java
index f46663ee811d212c787cc5cd2898613912aaf6bf..3379d33cd72d0c14d5a8e3a7ff48ca390056f9cf 100644
--- a/core/src/cz/nic/tablexia/util/ui/dialog/components/CenterPositionDialogComponent.java
+++ b/core/src/cz/nic/tablexia/util/ui/dialog/components/CenterPositionDialogComponent.java
@@ -53,6 +53,6 @@ public class CenterPositionDialogComponent extends TablexiaDialogComponentAdapte
     }
 
     private void centerDialog() {
-        getDialog().setPosition(getViewportLeftX() + (screenWidth / 2) - (getDialog().getWidth() / 2), getViewportBottomY() + (screenHeight / 2) - (getDialog().getHeight() / 2));
+		getDialog().setPosition(getViewportLeftX() + (screenWidth / 2) - (getDialog().getWidth() / 2), getViewportBottomY() + (screenHeight / 2) - (getDialog().getHeight() / 2));
     }
 }
diff --git a/core/src/cz/nic/tablexia/util/ui/dialog/components/DividerContentDialogComponent.java b/core/src/cz/nic/tablexia/util/ui/dialog/components/DividerContentDialogComponent.java
index f80d6270c13d3996cacee1709b2790d37c6b0b96..3cc426aa5806ab52cc57637597323b55aaa70f72 100644
--- a/core/src/cz/nic/tablexia/util/ui/dialog/components/DividerContentDialogComponent.java
+++ b/core/src/cz/nic/tablexia/util/ui/dialog/components/DividerContentDialogComponent.java
@@ -14,20 +14,31 @@ public class DividerContentDialogComponent extends ImageContentDialogComponent {
 
     private static final float  DEFAULT_PADDING     = 1 / 20f;
     private static final float  DEFAULT_CELL_HEIGHT = 1f;
+    private static final Color  DEFAULT_COLOR       = Color.BLACK;
 
     private Float   width;
     private Float   height;
 
+    private Color   color;
+
     public DividerContentDialogComponent() {
         this(DEFAULT_CELL_HEIGHT);
     }
 
+    public DividerContentDialogComponent(Color color) {
+        this(DEFAULT_CELL_HEIGHT, null, color);
+    }
+
     public DividerContentDialogComponent(Float height) {
-        this(height, null);
+        this(height, null, DEFAULT_COLOR);
     }
 
     public DividerContentDialogComponent(Float height, Float width) {
-        super(new Image(ApplicationAtlasManager.getInstance().getColorTextureRegion(Color.BLACK)),
+        this(height, width, DEFAULT_COLOR);
+    }
+
+    public DividerContentDialogComponent(Float height, Float width, Color color) {
+        super(new Image(ApplicationAtlasManager.getInstance().getColorTextureRegion(color)),
                 Scaling.stretch,
                 1f);
 
diff --git a/core/src/cz/nic/tablexia/util/ui/dialog/components/TextContentDialogComponent.java b/core/src/cz/nic/tablexia/util/ui/dialog/components/TextContentDialogComponent.java
index fcc04268815869bbd940b0c29866e6b0b39cb576..04a22c1be6f638e2eaf3e6b1e748a3fb1ab6ac70 100644
--- a/core/src/cz/nic/tablexia/util/ui/dialog/components/TextContentDialogComponent.java
+++ b/core/src/cz/nic/tablexia/util/ui/dialog/components/TextContentDialogComponent.java
@@ -47,6 +47,10 @@ public class TextContentDialogComponent extends TablexiaDialogComponentAdapter {
         this(text, fontType, DEFAULT_FONT_COLOR, DEFAULT_ALIGN, DEFAULT_PADDING, wrap, false);
     }
 
+    public TextContentDialogComponent(String text, ApplicationFontManager.FontType_NEW fontType, Color color, boolean wrap) {
+        this(text, fontType, color, DEFAULT_ALIGN, DEFAULT_PADDING, wrap, false);
+    }
+
     public TextContentDialogComponent(String text, boolean wrap, boolean fullDialogWidth) {
         this(text, DEFAULT_FONT_TYPE, DEFAULT_FONT_COLOR, DEFAULT_ALIGN, DEFAULT_PADDING, wrap, fullDialogWidth);
     }
diff --git a/desktop/src/cz/nic/tablexia/desktop/DesktopLauncher.java b/desktop/src/cz/nic/tablexia/desktop/DesktopLauncher.java
index 7cdfdcb24110448191e2d04a672e738307131547..2c10ac6529ab8738f0fd9d5abbeeced04223a356 100644
--- a/desktop/src/cz/nic/tablexia/desktop/DesktopLauncher.java
+++ b/desktop/src/cz/nic/tablexia/desktop/DesktopLauncher.java
@@ -14,7 +14,8 @@ import cz.nic.tablexia.screen.loader.IConnectionManager;
 
 public class DesktopLauncher {
 
-    private static final String BUILD_VARIANT_MANIFEST_ATTRIBUTE     = "Build-Type";
+    private static final String     BUILD_VARIANT_MANIFEST_ATTRIBUTE    = "Build-Type";
+    private static final boolean    HAS_SOFT_BACK_BUTTON                = true;
 
     private static final String DESKTOP_ICON_PATH                    = "icon/";
     private static final String DESKTOP_ICON_16                      = DESKTOP_ICON_PATH + "desktop_icon_16.png";
@@ -55,7 +56,7 @@ public class DesktopLauncher {
             config.addIcon(DESKTOP_ICON_128, Files.FileType.Internal);
         }
 
-	    new LwjglApplication(new Tablexia(buildType, Locale.getDefault(), SQL_CONNECTION_TYPE, new DesktopConnectionManager(), true), config);
+	    new LwjglApplication(new Tablexia(buildType, Locale.getDefault(), SQL_CONNECTION_TYPE, new DesktopConnectionManager(), HAS_SOFT_BACK_BUTTON, true), config);
     }
 
     private static String loadAttributeFromManifest(String attributeName, String defaultValue) {
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index b5166dad4d90021f6a0b45268c0755719f1d5cd4..13372aef5e24af05341d49695ee84e5f9b594659 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 6a53aa049c9dd36a8940c9077293633a4439ddcc..904cd73c6a975c13857a6cba3c26082ee725bd32 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,4 +1,4 @@
-#Tue Apr 12 14:42:29 CEST 2016
+#Mon Apr 18 18:31:45 CEST 2016
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
diff --git a/gradlew b/gradlew
index 91a7e269e19dfc62e27137a0b57ef3e430cee4fd..9d82f78915133e1c35a6ea51252590fb38efac2f 100755
--- a/gradlew
+++ b/gradlew
@@ -42,11 +42,6 @@ case "`uname`" in
     ;;
 esac
 
-# For Cygwin, ensure paths are in UNIX format before anything is touched.
-if $cygwin ; then
-    [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
-fi
-
 # Attempt to set APP_HOME
 # Resolve links: $0 may be a link
 PRG="$0"
@@ -61,9 +56,9 @@ while [ -h "$PRG" ] ; do
     fi
 done
 SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >&-
+cd "`dirname \"$PRG\"`/" >/dev/null
 APP_HOME="`pwd -P`"
-cd "$SAVED" >&-
+cd "$SAVED" >/dev/null
 
 CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
 
@@ -114,6 +109,7 @@ fi
 if $cygwin ; then
     APP_HOME=`cygpath --path --mixed "$APP_HOME"`
     CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+    JAVACMD=`cygpath --unix "$JAVACMD"`
 
     # We build the pattern for arguments to be converted via cygpath
     ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
diff --git a/ios/src/cz/nic/tablexia/IOSLauncher.java b/ios/src/cz/nic/tablexia/IOSLauncher.java
index 145799b120e8836ca3d08100a96836dab3e4fcd8..276730aca4e2246284e10d34beb406d967ac0114 100644
--- a/ios/src/cz/nic/tablexia/IOSLauncher.java
+++ b/ios/src/cz/nic/tablexia/IOSLauncher.java
@@ -22,7 +22,8 @@ import cz.nic.tablexia.screen.loader.IConnectionManager;
 
 public class IOSLauncher extends IOSApplication.Delegate {
 
-    public static final Tablexia.SQLConnectionType  SQL_CONNECTION_TYPE                 = new Tablexia.SQLConnectionType("SQLite.JDBCDriver", "jdbc:sqlite:");
+    public static final     Tablexia.SQLConnectionType  SQL_CONNECTION_TYPE                 = new Tablexia.SQLConnectionType("SQLite.JDBCDriver", "jdbc:sqlite:");
+    private static final    boolean                     HAS_SOFT_BACK_BUTTON                = true;
 
     private static final String                     FALLBACK_CONNECTION_CHECK_HOST      = "nic.cz";
     private static final Integer                    FALLBACK_CONNECTION_CHECK_PORT      = 80;
@@ -45,6 +46,7 @@ public class IOSLauncher extends IOSApplication.Delegate {
                 Locale.getDefault(),
                 SQL_CONNECTION_TYPE,
                 new IOSConnectionManager(),
+                HAS_SOFT_BACK_BUTTON,
                 false), config) {
 
             @Override