diff --git a/src/main/java/cz/vsb/fei/efrei/lab04/Fighter.java b/src/main/java/cz/vsb/fei/efrei/lab04/Fighter.java
index f5b13d2cd0bfc2191d8b9eca9059b9321985a2b0..b7f93037e43c75c8b3b98951ac2d8955cbbad005 100644
--- a/src/main/java/cz/vsb/fei/efrei/lab04/Fighter.java
+++ b/src/main/java/cz/vsb/fei/efrei/lab04/Fighter.java
@@ -1,6 +1,6 @@
 package cz.vsb.fei.efrei.lab04;
 
-public interface Fighter {
+public interface Fighter extends Comparable<Fighter> {
 
 	int getLives();
 
diff --git a/src/main/java/cz/vsb/fei/efrei/lab04/Hero.java b/src/main/java/cz/vsb/fei/efrei/lab04/Hero.java
index 31f40a2e2462ca3a489d5e24a2fbcd5c8aa0a2e0..6062aa5942f7f90cd8648153b8f2c74d07142f60 100644
--- a/src/main/java/cz/vsb/fei/efrei/lab04/Hero.java
+++ b/src/main/java/cz/vsb/fei/efrei/lab04/Hero.java
@@ -20,7 +20,7 @@ public class Hero implements Fighter {
 	}
 
 	public Hero(String name) {
-		this(name, RANDOM.nextInt(5000) + 50);
+		this(name, RANDOM.nextInt(60) + 50);
 	}
 
 	@Override
@@ -53,7 +53,12 @@ public class Hero implements Fighter {
 
 	@Override
 	public String toString() {
-		return "Hero " + name + "(" + strenght + ")";
+		return String.format("Hero    %20s (%4d) - has %4d lives.", name, strenght, lives);
+	}
+
+	@Override
+	public int compareTo(Fighter o) {
+		return this.getName().compareTo(o.getName());
 	}
 
 }
diff --git a/src/main/java/cz/vsb/fei/efrei/lab04/Monster.java b/src/main/java/cz/vsb/fei/efrei/lab04/Monster.java
index 7b2edf0cfdd96f089a95538f6b73eeaf1844628e..dff9ce454063161f1373074a7f23bfb56c0479fa 100644
--- a/src/main/java/cz/vsb/fei/efrei/lab04/Monster.java
+++ b/src/main/java/cz/vsb/fei/efrei/lab04/Monster.java
@@ -11,13 +11,11 @@ public class Monster implements Fighter {
 	private int lives;
 
 	public Monster(String name, int strenght) {
-		if(name == null || name.length() < 2 ) {
-			throw new IllegalArgumentException(
-					"Too short name");
+		if (name == null || name.length() < 2) {
+			throw new IllegalArgumentException("Too short name");
 		}
-		if(strenght < 10) {
-			throw new IllegalArgumentException(
-					"Monster is too weak!!");
+		if (strenght < 10) {
+			throw new IllegalArgumentException("Monster is too weak!!");
 		}
 		this.name = name;
 		this.strenght = strenght;
@@ -33,7 +31,7 @@ public class Monster implements Fighter {
 		System.out.println(fighter.getName() + " attack " + getName() + "!");
 		lives -= fighter.getStrenght();
 	}
-	
+
 	@Override
 	public String getName() {
 		return name;
@@ -51,7 +49,12 @@ public class Monster implements Fighter {
 
 	@Override
 	public String toString() {
-		return "Monster " + name + "(" + strenght + ") - has " + lives + " lives.";
+		return String.format("Monster %20s (%4d) - has %4d lives.", name, strenght, lives);
+	}
+
+	@Override
+	public int compareTo(Fighter o) {
+		return this.getName().compareTo(o.getName());
 	}
 
 }
diff --git a/src/main/java/cz/vsb/fei/efrei/lab04/StrenghtComparator.java b/src/main/java/cz/vsb/fei/efrei/lab04/StrenghtComparator.java
new file mode 100644
index 0000000000000000000000000000000000000000..65aee854c3bffe384f9efa75c5e8285c4f6a95f8
--- /dev/null
+++ b/src/main/java/cz/vsb/fei/efrei/lab04/StrenghtComparator.java
@@ -0,0 +1,12 @@
+package cz.vsb.fei.efrei.lab04;
+
+import java.util.Comparator;
+
+public class StrenghtComparator implements Comparator<Fighter> {
+
+	@Override
+	public int compare(Fighter o1, Fighter o2) {
+		return o1.getStrenght() - o2.getStrenght();
+	}
+
+}
diff --git a/src/main/java/cz/vsb/fei/efrei/lab04/Utils.java b/src/main/java/cz/vsb/fei/efrei/lab04/Utils.java
index 3ab90ed3ceb4418143338c2a235641363a345299..7033d48f8d108ee3ec1208c7668821ad21abda3a 100644
--- a/src/main/java/cz/vsb/fei/efrei/lab04/Utils.java
+++ b/src/main/java/cz/vsb/fei/efrei/lab04/Utils.java
@@ -8,13 +8,13 @@ public class Utils {
 
 	public static final Random RANDOM = new Random();
 	private static List<String> heroNames = Arrays.asList("Captain Freedom", "Iron Blade", "Shadow Hunter",
-			"Silver Hawk", "Mighty Thunder", "Lunar Knight", "Phoenix Blaze", "Stormbreaker", "Star Guardian",
-			"Solar Sentinel", "Dark Raven", "Blaze Falcon", "Crystal Viper", "Lightning Strike", "Firestorm",
+			"ČSilver Hawk", "ŽMighty Thunder", "ĚLunar Knight", "Phoenix Blaze", "Stormbreaker", "Star Guardian",
+			"ŇSolar Sentinel", "Dark Raven", "Blaze Falcon", "Crystal Viper", "Lightning Strike", "Firestorm",
 			"Eagle Eye", "Nightshade", "Frostbite", "Wind Whisperer", "Shadow Blaze");
 
 	private static List<String> monsterNames = Arrays.asList("Nightmare Reaper", "Shadow Fiend", "Bonecrusher",
-			"Venomous Hydra", "Doomfang", "Blightbringer", "Void Stalker", "Inferno Drake", "Ghoul King", "Frost Wyrm",
-			"Terrorclaw", "Bloodfeast", "Ravenous Maw", "Storm Serpent", "Hellhound", "Dark Overlord", "Necroshade",
+			"ÁVenomous Hydra", "ÉDoomfang", "Blightbringer", "Void Stalker", "Inferno Drake", "Ghoul King", "Frost Wyrm",
+			"Terrorclaw", "ĂŤBloodfeast", "Ravenous Maw", "Storm Serpent", "Hellhound", "Dark Overlord", "Necroshade",
 			"Plaguebeast", "Stone Golem", "Fire Leviathan");
 
 	public static String generateHeroName() {
diff --git a/src/main/java/cz/vsb/fei/efrei/lab04/WorldOfStrongestFighter.java b/src/main/java/cz/vsb/fei/efrei/lab04/WorldOfStrongestFighter.java
new file mode 100644
index 0000000000000000000000000000000000000000..89b2a62ebee266801a71212946bb8ae1acbead49
--- /dev/null
+++ b/src/main/java/cz/vsb/fei/efrei/lab04/WorldOfStrongestFighter.java
@@ -0,0 +1,194 @@
+package cz.vsb.fei.efrei.lab04;
+
+import java.text.Collator;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Random;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+
+public class WorldOfStrongestFighter {
+	public static void main(String[] args) {
+		int countOfHeros = 10;
+		int countOfMonsters = 10;
+		List<Fighter> fighters = generateFighters(countOfHeros, countOfMonsters);
+
+		printOutListOfFighters(fighters, "Generated fighters");
+
+		shuffleAndSortFighters(new ArrayList<Fighter>(fighters));
+
+		compareTimeForIndexOfandBinarySearch(generateFighters(10000, 10000));
+
+		sortUsingNormalClass(new ArrayList<Fighter>(fighters));
+		sortUsingInnerClass(new ArrayList<Fighter>(fighters));
+
+		sortUsingAnonymousInnerClass(new ArrayList<Fighter>(fighters));
+
+		sortByNameAndThenByStrenght(new ArrayList<Fighter>(fighters));
+
+		createNullSafeComparator(new ArrayList<Fighter>(fighters));
+
+		sortBaseOnLives(new ArrayList<Fighter>(fighters));
+
+		sortBaseOnNativeLanguageRules(fighters);
+
+		String[] streetNames = new String[] {"Broadway", "Abbey_Road", "Champs-Élysées"};
+		List<String> streetAddresses = new ArrayList<>();
+		for (int i = 0; i < 20; i++) {
+			streetAddresses.add(String.format("%s %s", 
+					streetNames[Utils.RANDOM.nextInt(streetNames.length)],
+					Utils.RANDOM.nextInt(1, 200)));
+		}
+		sortStringsAsNumberAware(streetAddresses);
+	}
+
+	private static void sortStringsAsNumberAware(List<String> streetAddresses) {
+		Collections.shuffle(streetAddresses);
+		Collections.sort(streetAddresses);
+		printOutListOfFighters(streetAddresses, "Sort street address using strings");
+		Collections.shuffle(streetAddresses);
+		Collections.sort(streetAddresses, new Comparator<String>() {
+			@Override
+			public int compare(String s1, String s2) {
+				String[] parts1 = s1.split(" ");
+				String[] parts2 = s2.split(" ");
+				int result = parts1[0].compareTo(parts2[0]);
+				if(result != 0) {
+					return result;
+				}
+				return Integer.compare(
+						Integer.parseInt(parts1[1]), 
+						Integer.parseInt(parts2[1]));
+			}
+		});
+		printOutListOfFighters(streetAddresses, "Sort street address using numbers");
+	}
+	private static void sortBaseOnNativeLanguageRules(List<Fighter> fighters) {
+		Collator czCollator = Collator.getInstance(Locale.of("cs"));
+		Collections.sort(fighters, new Comparator<Fighter>() {
+			@Override
+			public int compare(Fighter o1, Fighter o2) {
+				return czCollator.compare(o1.getName(), o2.getName());
+			}
+		});
+		printOutListOfFighters(fighters, "Sort base on czech language native rules");
+	}
+
+	private static void sortBaseOnLives(List<Fighter> fighters) {
+		for (int i = 0; i < 20; i++) {
+			Fighter f1 =  fighters.get(Utils.RANDOM.nextInt(fighters.size()));
+			Fighter f2 =  fighters.get(Utils.RANDOM.nextInt(fighters.size()));
+			try {
+				f1.attackedBy(f2);
+			} catch (AlreadyDeadException e) {
+				System.out.println("Some one attack dead fighter");
+			}
+		}
+		Collections.sort(fighters, Comparator.comparing(new Function<Fighter, Integer>() {
+			@Override
+			public Integer apply(Fighter t) {
+				return t.getLives();
+			}
+		}));
+		printOutListOfFighters(fighters, "Sort base on lives");
+	}
+
+	private static void createNullSafeComparator(List<Fighter> fighters) {
+		for (int i = 0; i < 10; i++) {
+			fighters.add(null);
+		}
+		Collections.shuffle(fighters);
+		Collections.sort(fighters, Comparator.nullsFirst(new StrenghtInnerClassComparator()));
+		printOutListOfFighters(fighters, "Null safe comparator");
+	}
+
+	private static void sortByNameAndThenByStrenght(List<Fighter> fighters) {
+		Collections.sort(fighters, new Comparator<Fighter>() {
+
+			@Override
+			public int compare(Fighter o1, Fighter o2) {
+				int result = o1.getName().compareTo(o2.getName());
+				if (result != 0) {
+					return result;
+				}
+				return Integer.compare(o1.getStrenght(), o2.getStrenght());
+			}
+		});
+		printOutListOfFighters(fighters, "Sorted fighters by name and by strenght");
+	}
+
+	private static void sortUsingAnonymousInnerClass(List<Fighter> fighters) {
+		Collections.sort(fighters, new Comparator<Fighter>() {
+
+			@Override
+			public int compare(Fighter o1, Fighter o2) {
+				return Integer.compare(o1.getStrenght(), o2.getStrenght());
+			}
+		});
+		printOutListOfFighters(fighters, "Sorted fighters using anonymous inner class");
+	}
+
+	private static void sortUsingInnerClass(List<Fighter> fighters) {
+		Collections.sort(fighters, new StrenghtInnerClassComparator());
+		printOutListOfFighters(fighters, "Sorted fighters using Comparator implemented by inner class");
+	}
+
+	private static void sortUsingNormalClass(List<Fighter> fighters) {
+		Collections.sort(fighters, new StrenghtComparator());
+		printOutListOfFighters(fighters, "Sorted fighters using Comparator implemented by normal class");
+	}
+
+	private static void compareTimeForIndexOfandBinarySearch(List<Fighter> fighters) {
+		Fighter heroToSearch = new Hero(Utils.generateHeroName());
+		Stopwatch stopwatch = new Stopwatch();
+		stopwatch.start();
+		fighters.indexOf(heroToSearch);
+		stopwatch.stop();
+		System.out.println("Not sorted collection search duration: " + stopwatch.formatDuration());
+		Collections.sort(fighters);
+		stopwatch.start();
+		Collections.binarySearch(fighters, heroToSearch);
+		stopwatch.stop();
+		System.out.println("Sorted collection binary search duration: " + stopwatch.formatDuration());
+	}
+
+	private static void printOutListOfFighters(List<?> listOfObjects, String title) {
+		System.out.println("=========" + title + "============================================");
+		for (Object element : listOfObjects) {
+			System.out.println(element);
+		}
+		System.out.println("=============================================================================");
+	}
+
+	private static List<Fighter> generateFighters(int countOfHeros, int countOfMonsters) {
+		List<Fighter> fighters = new ArrayList<>(countOfHeros + countOfMonsters);
+		for (int i = 0; i < countOfHeros; i++) {
+			fighters.add(new Hero(Utils.generateHeroName()));
+		}
+
+		for (int i = 0; i < countOfMonsters; i++) {
+			fighters.add(new Monster(Utils.generateMonsterName()));
+		}
+		return fighters;
+	}
+
+	private static void shuffleAndSortFighters(List<Fighter> fighters) {
+		Collections.shuffle(fighters);
+		printOutListOfFighters(fighters, "Shuffled fighters");
+		Collections.sort(fighters);
+		printOutListOfFighters(fighters, "Sorted fighters");
+	}
+
+	private static class StrenghtInnerClassComparator implements Comparator<Fighter> {
+
+		@Override
+		public int compare(Fighter o1, Fighter o2) {
+			return Integer.compare(o1.getStrenght(), o2.getStrenght());
+		}
+
+	}
+}