diff --git a/core/src/cz/nic/tablexia/Tablexia.java b/core/src/cz/nic/tablexia/Tablexia.java
index 35f18a72098e9a60971282b085dffbb3590516e0..fab42651090f597bdb989d520674ad2ac1ac4854 100644
--- a/core/src/cz/nic/tablexia/Tablexia.java
+++ b/core/src/cz/nic/tablexia/Tablexia.java
@@ -89,6 +89,7 @@ public class Tablexia extends TablexiaApplication {
 	
 	@Override
 	public void dispose() {
+		ApplicationBus.getInstance().unsubscribe(this);
 		ApplicationTextureManager.getInstance().dispose();
 		ApplicationFontManager.getInstance().dispose();
 		ApplicationTextManager.getInstance().dispose();
diff --git a/core/src/cz/nic/tablexia/TablexiaApplication.java b/core/src/cz/nic/tablexia/TablexiaApplication.java
index 6e6610f0ae44ad07096451eccf3fe169f3e4909c..0c43f3ea996e8dafa7712bd25fa3276242bbb206 100644
--- a/core/src/cz/nic/tablexia/TablexiaApplication.java
+++ b/core/src/cz/nic/tablexia/TablexiaApplication.java
@@ -18,6 +18,9 @@ import com.badlogic.gdx.math.Interpolation;
 import com.badlogic.gdx.scenes.scene2d.Actor;
 import com.badlogic.gdx.scenes.scene2d.Stage;
 
+import cz.nic.tablexia.bus.ApplicationBus;
+import cz.nic.tablexia.bus.ApplicationBus.ApplicationEvent;
+import cz.nic.tablexia.debug.DebugInfo;
 import cz.nic.tablexia.graphics.ColorTexture;
 import cz.nic.tablexia.screen.AbstractTablexiaScreen;
 import cz.nic.tablexia.screen.AbstractTablexiaScreen.ScreenLoadingListener;
@@ -35,6 +38,7 @@ public abstract class TablexiaApplication implements ApplicationListener {
 	private 				AbstractTablexiaScreen<?>	lastScreen;
 	private 				AbstractTablexiaScreen<?>	screen;
 	private 				InputMultiplexer 			inputMultiplexer;
+	private 				DebugInfo 					debugInfo;
 	private 				Stage						stage;
 
 	
@@ -48,6 +52,9 @@ public abstract class TablexiaApplication implements ApplicationListener {
 	@Override
 	public void dispose () {
 		inputMultiplexer.removeProcessor(stage);
+		if (TablexiaSettings.isDebug()) {			
+			debugInfo.dispose();
+		}
 		stage.dispose();
 		if (lastScreen != null) {
 			lastScreen.hide();
@@ -76,6 +83,7 @@ public abstract class TablexiaApplication implements ApplicationListener {
 		stage = new Stage();
 		inputMultiplexer = new InputMultiplexer(stage);
 		Gdx.input.setInputProcessor(inputMultiplexer);
+		prepareDebugInfo();
 	}
 
 	@Override
@@ -84,6 +92,9 @@ public abstract class TablexiaApplication implements ApplicationListener {
 		Gdx.gl.glClearColor(BACKGROUND_COLOR.r, BACKGROUND_COLOR.g, BACKGROUND_COLOR.b, BACKGROUND_COLOR.a);
 		Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
 		
+		if (TablexiaSettings.isDebug()) {			
+			debugInfo.update();
+		}
 		float deltaTime = Gdx.graphics.getDeltaTime();
 		if (lastScreen != null) lastScreen.render(deltaTime);
 		if (screen != null) screen.render(deltaTime);
@@ -99,9 +110,32 @@ public abstract class TablexiaApplication implements ApplicationListener {
 		stage.getViewport().update(width, height, true);
 	}
 	
+
+//////////////////////////// DEBUG INFO
+	
+	private void prepareDebugInfo() {
+		if (TablexiaSettings.isDebug()) {			
+			debugInfo = new DebugInfo(getStage().getWidth(), getStage().getHeight());
+			getStage().addActor(debugInfo);
+		}
+	}
+	
 	
 //////////////////////////// SCREEN HANDLING
 	
+	public static class ScreenChangedEvent implements ApplicationEvent {
+		
+		private Class<? extends AbstractTablexiaScreen<?>> 	screenClass;
+
+		public ScreenChangedEvent(Class<? extends AbstractTablexiaScreen<?>> screenClass) {
+			this.screenClass = screenClass;
+		}
+		
+		public Class<? extends AbstractTablexiaScreen<?>> getScreenClass() {
+			return screenClass;
+		}
+	}
+	
 	/**
 	 * Change current screen if is different from actual screen.
 	 * 
@@ -186,11 +220,13 @@ public abstract class TablexiaApplication implements ApplicationListener {
 		return screen;
 	}
 	
+	@SuppressWarnings("unchecked")
 	private void processNewScreen(AbstractTablexiaScreen<?> newScreen) {
 		if (newScreen != null) {
 			inputMultiplexer.addProcessor(newScreen.getInputProcessor());
 			newScreen.show();
 			newScreen.resize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
+			ApplicationBus.getInstance().post(new ScreenChangedEvent((Class<? extends AbstractTablexiaScreen<?>>) newScreen.getClass())).asynchronously();
 		}
 	}
 	
@@ -200,6 +236,7 @@ public abstract class TablexiaApplication implements ApplicationListener {
 			lastScreen.hide();
 			lastScreen.dispose();
 			lastScreen = null;
+			System.gc();
 		}
 	}
 	
diff --git a/core/src/cz/nic/tablexia/debug/DebugInfo.java b/core/src/cz/nic/tablexia/debug/DebugInfo.java
new file mode 100644
index 0000000000000000000000000000000000000000..519fa375e5e5f7654606b633012dc3569e2723ae
--- /dev/null
+++ b/core/src/cz/nic/tablexia/debug/DebugInfo.java
@@ -0,0 +1,151 @@
+package cz.nic.tablexia.debug;
+
+import static com.badlogic.gdx.scenes.scene2d.actions.Actions.alpha;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+import net.engio.mbassy.listener.Handler;
+
+import com.badlogic.gdx.Gdx;
+import com.badlogic.gdx.graphics.Color;
+import com.badlogic.gdx.graphics.g2d.BitmapFont;
+import com.badlogic.gdx.graphics.g2d.TextureRegion;
+import com.badlogic.gdx.scenes.scene2d.Actor;
+import com.badlogic.gdx.scenes.scene2d.ui.Cell;
+import com.badlogic.gdx.scenes.scene2d.ui.Container;
+import com.badlogic.gdx.scenes.scene2d.ui.Label;
+import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle;
+import com.badlogic.gdx.scenes.scene2d.ui.Table;
+import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
+import com.badlogic.gdx.utils.Disposable;
+
+import cz.nic.tablexia.TablexiaApplication.ScreenChangedEvent;
+import cz.nic.tablexia.bus.ApplicationBus;
+import cz.nic.tablexia.graphics.ColorTexture;
+import cz.nic.tablexia.screen.AbstractTablexiaScreen.ScreenInfoEvent;
+
+/**
+ * Debug info container
+ * 
+ * @author Matyáš Latner
+ *
+ */
+public class DebugInfo extends Table implements Disposable {
+
+	private static class DebugInfoComponent extends Table {
+		
+		private Map<String, Cell<Label>>	infoCellMap;
+		private LabelStyle 					labelStyle;
+
+		public DebugInfoComponent(float width, float height) {
+			infoCellMap = new HashMap<String, Cell<Label>>();
+			setBounds(0, 0, width, height);
+			setBackground(new TextureRegionDrawable(new TextureRegion(new ColorTexture(1, 1, BACKGROUND_COLOR))));
+			addAction(alpha(BACKGROUND_ALPHA));
+			
+			labelStyle = new LabelStyle(new BitmapFont(), FONT_COLOR);
+		}
+		
+		public synchronized void setInfoValue(String infoKey, String infoValue) {
+			Cell<Label> cell = infoCellMap.get(infoKey);
+			if (cell == null) {
+				createInfoCell(infoKey, infoValue);
+			} else {
+				cell.getActor().setText(infoKey + KEY_COLON + infoValue);
+			}
+		}
+		
+		private void clean() {
+			clearChildren();
+			infoCellMap.clear();
+		}
+		
+		private void createInfoCell(String infoKey, String infoValue) {
+			Cell<Label> cell = add(new Label(infoKey + KEY_COLON + infoValue, labelStyle));
+			infoCellMap.put(infoKey, cell);
+			if (getCells().size > 1) {
+				cell.pad(0, INFO_PADDING, 0, 0);
+			}
+		}
+		
+		@Override
+		public void setSize(float width, float height) {
+			super.setSize(width, height);
+		}
+		
+	}
+	
+	
+	private static final String NATIVE_HEAP 	= "Native Heap";
+	private static final String JAVA_HEAP 		= "Java Heap";
+	private static final String FPS 			= "FPS";
+	
+	private static final String SCREEN_NAME 	= "Screen Name";
+	
+	private static final int 	INFO_PADDING	= 20;
+	private static final int 	MB_SIZE 		= 1000000;
+	private static final String UNIT_MB 		= " MB";
+	private static final String KEY_COLON 		= ": ";
+	
+	private static final Color FONT_COLOR 		= Color.WHITE;
+	private static final Color BACKGROUND_COLOR	= Color.BLACK;
+	private static final float BACKGROUND_ALPHA = 0.5f;
+	
+	private DebugInfoComponent applicationDebugInfo;
+	private DebugInfoComponent screenNameInfo;
+	private DebugInfoComponent screenDebugInfo;
+	
+	private ConcurrentLinkedQueue<ScreenInfoEvent> screenDebugInfoQueue = new ConcurrentLinkedQueue<ScreenInfoEvent>();
+	private ConcurrentLinkedQueue<ScreenChangedEvent> screenNameInfoQueue = new ConcurrentLinkedQueue<ScreenChangedEvent>();
+
+	public DebugInfo(float width, float height) {
+		setBounds(0, 0, width, height);
+		ApplicationBus.getInstance().subscribe(this);
+		
+		applicationDebugInfo = new DebugInfoComponent(width, height);
+		screenNameInfo = new DebugInfoComponent(width, height);
+		screenDebugInfo = new DebugInfoComponent(width, height);
+		
+		Table topTable = new Table();
+		topTable.add(screenNameInfo).expandX();
+		topTable.add(screenDebugInfo).pad(0, INFO_PADDING, 0, 0).expandX();
+		add(topTable);
+		row();
+		add(new Container<Actor>()).expand();
+		row();
+		add(applicationDebugInfo).expandX();
+	}
+	
+	public void update() {
+		applicationDebugInfo.setInfoValue(FPS, "" + Gdx.graphics.getFramesPerSecond());
+		applicationDebugInfo.setInfoValue(JAVA_HEAP, ("" + Gdx.app.getJavaHeap() / MB_SIZE) + UNIT_MB);
+		applicationDebugInfo.setInfoValue(NATIVE_HEAP, ("" + Gdx.app.getNativeHeap() / MB_SIZE) + UNIT_MB);
+		
+		while (!screenDebugInfoQueue.isEmpty()) {
+			ScreenInfoEvent screenInfoEvent = screenDebugInfoQueue.poll();
+			screenDebugInfo.setInfoValue(screenInfoEvent.getInfoKey(), screenInfoEvent.getInfoValue());
+		}
+		
+		while (!screenNameInfoQueue.isEmpty()) {
+			screenNameInfo.setInfoValue(SCREEN_NAME, "" + screenNameInfoQueue.poll().getClass().getSimpleName());
+		}
+	}
+	
+	@Handler
+	public void handleScreenChangedEvent(ScreenChangedEvent screenChangedEvent) {
+		screenDebugInfo.clean();
+		screenNameInfoQueue.add(screenChangedEvent);
+	}
+	
+	@Handler
+	public void handleScreenInfoEvent(ScreenInfoEvent screenInfoEvent) {
+		screenDebugInfoQueue.add(screenInfoEvent);
+	}
+
+	@Override
+	public void dispose() {
+		ApplicationBus.getInstance().unsubscribe(this);
+	}
+}
diff --git a/core/src/cz/nic/tablexia/screen/AbstractTablexiaScreen.java b/core/src/cz/nic/tablexia/screen/AbstractTablexiaScreen.java
index f4aa0ec6cbc9f382f615d1280d66506cad243c96..9fc9f448a9c30e6374c4c817c040a3be659653fa 100644
--- a/core/src/cz/nic/tablexia/screen/AbstractTablexiaScreen.java
+++ b/core/src/cz/nic/tablexia/screen/AbstractTablexiaScreen.java
@@ -20,6 +20,8 @@ import com.badlogic.gdx.utils.I18NBundle;
 import com.badlogic.gdx.utils.async.AsyncTask;
 import com.badlogic.gdx.utils.viewport.ScreenViewport;
 
+import cz.nic.tablexia.bus.ApplicationBus;
+import cz.nic.tablexia.bus.ApplicationBus.ApplicationEvent;
 import cz.nic.tablexia.game.loader.AbstractDataManager;
 import cz.nic.tablexia.loader.IApplicationLoader;
 import cz.nic.tablexia.util.Log;
@@ -71,6 +73,25 @@ public abstract class AbstractTablexiaScreen<T> extends ScreenAdapter {
 		void loadingComplete();
 	}
 	
+	public static class ScreenInfoEvent implements ApplicationEvent {
+
+		private String infoKey;
+		private String infoValue;
+
+		public ScreenInfoEvent(String infoKey, String infoValue) {
+			this.infoKey = infoKey;
+			this.infoValue = infoValue;
+		}
+		
+		public String getInfoKey() {
+			return infoKey;
+		}
+		
+		public String getInfoValue() {
+			return infoValue;
+		}
+	}
+	
 	private Stage 					stage;
 	private AssetManager 			textureManager;
 	private AssetManager 			soundManager;
@@ -225,6 +246,10 @@ public abstract class AbstractTablexiaScreen<T> extends ScreenAdapter {
 		return null;
 	}
 	
+	protected void 			printScreenInfo(String infoKey, String infoValue) {
+		ApplicationBus.getInstance().post(new ScreenInfoEvent(infoKey, infoValue)).asynchronously();
+	}
+	
 	
 //////////////////////////// LOADERS