diff --git a/frontend-js/src/main/js/gui/AbstractGuiElement.js b/frontend-js/src/main/js/gui/AbstractGuiElement.js
new file mode 100644
index 0000000000000000000000000000000000000000..fe83a4a46fa505dd659cc1df17c50f9a3ef9fc50
--- /dev/null
+++ b/frontend-js/src/main/js/gui/AbstractGuiElement.js
@@ -0,0 +1,42 @@
+"use strict";
+
+/* exported logger */
+
+var ObjectWithListeners = require('../ObjectWithListeners');
+
+var logger = require('../logger');
+
+function AbstractGuiElement(params) {
+  ObjectWithListeners.call(this, params);
+
+  var self = this;
+
+  self.setElement(params.element);
+  self.setMap(params.customMap);
+}
+
+AbstractGuiElement.prototype = Object.create(ObjectWithListeners.prototype);
+AbstractGuiElement.prototype.constructor = AbstractGuiElement;
+
+AbstractGuiElement.prototype.setMap = function(map) {
+  if (map===undefined || map===null) {
+    throw new Error("map must be defined");
+  }
+  this._map = map;
+};
+
+AbstractGuiElement.prototype.getMap = function() {
+  return this._map;
+};
+
+AbstractGuiElement.prototype.setElement = function(element) {
+  if (element === undefined || element === null) {
+    throw new Error("DOM Element must be defined");
+  }
+  this._element = element;
+};
+
+AbstractGuiElement.prototype.getElement = function() {
+  return this._element;
+};
+module.exports = AbstractGuiElement;
diff --git a/frontend-js/src/main/js/gui/OverviewDialog.js b/frontend-js/src/main/js/gui/OverviewDialog.js
new file mode 100644
index 0000000000000000000000000000000000000000..20245945ebf58196dabe0024e24f1eaf32feb071
--- /dev/null
+++ b/frontend-js/src/main/js/gui/OverviewDialog.js
@@ -0,0 +1,221 @@
+"use strict";
+
+/* exported logger */
+
+var AbstractGuiElement = require('./AbstractGuiElement');
+var GuiConnector = require('../GuiConnector');
+
+var functions = require('../functions');
+var logger = require('../logger');
+
+function OverviewDialog(params) {
+  AbstractGuiElement.call(this, params);
+  var self = this;
+  $(self.getElement()).dialog({
+    autoOpen : false,
+    resizable : false,
+  });
+}
+
+OverviewDialog.prototype = Object.create(AbstractGuiElement.prototype);
+OverviewDialog.prototype.constructor = OverviewDialog;
+
+OverviewDialog.prototype.showOverview = function(overviewImageId) {
+  var self = this;
+  var map = self.getMap();
+
+  var project = map.getProject();
+
+  // resize dialog
+  var htmlTag = self.getElement();
+
+  var width = Math.floor(window.innerWidth * 2 / 3);
+  var height = Math.floor(window.innerHeight * 2 / 3);
+
+  $(self.getElement()).dialog("option", "width", width + 60);
+  $(self.getElement()).dialog("option", "height", height + 60);
+
+  // remove all child nodes from overview div
+  while (htmlTag.hasChildNodes()) {
+    htmlTag.removeChild(htmlTag.lastChild);
+  }
+
+  var content = document.createElement("div");
+  htmlTag.appendChild(content);
+
+  var canvasDebug = document.createElement("canvas");
+  canvasDebug.className = "canvasDebugClass";
+  canvasDebug.style.display = "none";
+  htmlTag.appendChild(canvasDebug);
+
+  if (overviewImageId === undefined) {
+    this.overviewImage = project.getTopOverviewImage();
+  } else {
+    this.overviewImage = null;
+    var images = project.getOverviewImages();
+    for (var i = 0; i < images.length; i++) {
+      if (images[i].idObject === overviewImageId) {
+        this.overviewImage = images[i];
+      }
+    }
+
+    if (this.overviewImage === null) {
+      logger.warn("Unknown overview image with id = " + overviewImageId);
+      this.overviewImage = project.getTopOverviewImage();
+    }
+  }
+
+  // add image to overview div
+  this.overviewImageTag = document.createElement("IMG");
+  this.overviewImageTag.src = "../map_images/" + this.overviewImage.filename;
+  content.appendChild(this.overviewImageTag);
+
+  var ratio = 1.0;
+
+  // check how image should be resized to fit dialog and resize it manually!!!
+  if (width / this.overviewImage.width > height / this.overviewImage.height) {
+    this.overviewImageTag.style.height = height + "px";
+    ratio = height / this.overviewImage.height;
+    width = this.overviewImage.width * ratio;
+    $(self.getElement()).dialog("option", "width", width + 60);
+  } else {
+    this.overviewImageTag.style.width = width + "px";
+    ratio = width / this.overviewImage.width;
+    height = this.overviewImage.height * ratio;
+    $(self.getElement()).dialog("option", "height", height + 60);
+  }
+
+  // on click event (what should happen when we click on the image)
+  var onclickevent = function getClickPosition(e) {
+    var parentPosition = functions.getPosition(e.currentTarget);
+    var xPosition = e.clientX - parentPosition.x;
+    var yPosition = e.clientY - parentPosition.y;
+
+    var imgWidth = self.overviewImageTag.offsetWidth;
+
+    var currentRatio = imgWidth / self.overviewImage.width;
+
+    var xNormal = xPosition / currentRatio;
+    var yNormal = yPosition / currentRatio;
+    var point = {
+      x : xNormal,
+      y : yNormal
+    };
+
+    var link = null;
+    for (var i = 0; i < self.overviewImage.links.length; i++) {
+      if (functions.pointInsidePolygon(point, self.overviewImage.links[i].polygon)) {
+        if (link === null) {
+          link = self.overviewImage.links[i];
+        } else {
+          logger.warn("More than one link found. Skipping");
+        }
+      }
+    }
+    if (link !== null) {
+      if (link.type === "OverviewModelLink") {
+        logger.debug("Opening model from overview. ModelId: " + link.modelLinkId);
+        logger.debug("link coordinates [" + link.idObject + "]: " + link.latLng);
+        // TODO min zoom value can be different for every map, it should be
+        // changed in the future
+        map.showModel(link.modelLinkId, link.latLng, link.zoomLevel + map.getMinZoom());
+        overviewDialog.hide();
+      } else if (link.type === "OverviewImageLink") {
+        logger.debug("Opening image from overview. ImageId: " + link.imageLinkId);
+        self.showOverview(link.imageLinkId);
+      } else if (link.type === "OverviewSearchLink") {
+        logger.debug("Sending search query. Query: " + link.query);
+        GuiConnector.search(link.query);
+        overviewDialog.hide();
+      } else {
+        logger.warn("Unknown type of link: " + link.type + ". Don't know what to do... LinkId: " + link.idObject);
+      }
+    }
+  };
+
+  this.overviewImageTag.onclick = onclickevent;
+
+  // resize canvas where on mouse over highligh will appear
+
+  // in debug mode draw clickable shapes
+  if (map.isDebug()) {
+    canvasDebug.style.display = "";
+    canvasDebug.width = width;
+    canvasDebug.height = height;
+    canvasDebug.onclick = onclickevent;
+    this.drawClickableShapes(canvasDebug, ratio);
+  }
+
+  this.overviewImage.mousePos = {
+    x : 0,
+    y : 0
+  };
+
+  // this listener should be called when mouse moves over image, it purpose is
+  // to change coursor to pointer when mouse enters clickable polygon and back
+  // to normal when mouse leaves such region
+  var onmousemove = function getMouseOverPosition(e) {
+    var position = functions.getPosition(e.currentTarget);
+    position.x = e.clientX - position.x;
+    position.y = e.clientY - position.y;
+
+    var imgWidth = self.overviewImageTag.offsetWidth;
+
+    var currentRatio = imgWidth / self.overviewImage.width;
+
+    var xNormal = position.x / currentRatio;
+    var yNormal = position.y / currentRatio;
+    var point = {
+      x : xNormal,
+      y : yNormal
+    };
+
+    if (self.overviewImage.mousePos.x !== position.x || self.overviewImage.mousePos.y !== position.y) {
+      self.overviewImage.mousePos = position;
+      var link = null;
+      for (var i = 0; i < self.overviewImage.links.length; i++) {
+        if (functions.pointInsidePolygon(point, self.overviewImage.links[i].polygon)) {
+          link = self.overviewImage.links[i];
+        }
+      }
+      if (link === null) {
+        e.currentTarget.style.cursor = "auto";
+      } else {
+        e.currentTarget.style.cursor = "pointer";
+      }
+    }
+  };
+
+  // onmousemove listener should be assigned to canvas (which is on top of the
+  // image) and overviewimage (just in case something went wrong with resizing
+  // canvas)
+  canvasDebug.onmousemove = onmousemove;
+  this.overviewImageTag.onmousemove = onmousemove;
+
+  $(self.getElement()).dialog("open");
+};
+
+OverviewDialog.prototype.drawClickableShapes = function(canvas, ratio) {
+  var ctx = canvas.getContext("2d");
+  // clear canvas
+  ctx.clearRect(0, 0, canvas.width, canvas.height);
+  for (var i = 0; i < this.overviewImage.links.length; i++) {
+    ctx.beginPath();
+    var polygon = this.overviewImage.links[i].polygon;
+    for (var j = 0; j < polygon.length; j++) {
+      var x = polygon[j].x * ratio;
+      var y = polygon[j].y * ratio;
+      ctx.moveTo(x, y);
+      x = polygon[(j + 1) % polygon.length].x * ratio;
+      y = polygon[(j + 1) % polygon.length].y * ratio;
+      ctx.lineTo(x, y);
+    }
+    ctx.stroke();
+  }
+};
+
+OverviewDialog.prototype.destroy = function() {
+  $(this.getElement()).dialog("destroy");
+};
+
+module.exports = OverviewDialog;
diff --git a/frontend-js/src/main/js/gui/Panel.js b/frontend-js/src/main/js/gui/Panel.js
index 4d0f5e111d5c536f048be81c4319e7687e964f37..370fcb409630cfddd6d59a3e8684c270717286d2 100644
--- a/frontend-js/src/main/js/gui/Panel.js
+++ b/frontend-js/src/main/js/gui/Panel.js
@@ -3,12 +3,12 @@
 /* exported logger */
 
 var GuiConnector = require('../GuiConnector');
-var ObjectWithListeners = require('../ObjectWithListeners');
+var AbstractGuiElement = require('./AbstractGuiElement');
 
 var logger = require('../logger');
 
 function Panel(params) {
-  ObjectWithListeners.call(this, params);
+  AbstractGuiElement.call(this, params);
 
   var self = this;
 
@@ -18,7 +18,7 @@ function Panel(params) {
 
 }
 
-Panel.prototype = Object.create(ObjectWithListeners.prototype);
+Panel.prototype = Object.create(AbstractGuiElement.prototype);
 Panel.prototype.constructor = Panel;
 
 Panel.prototype.disablePanel = function(message) {
diff --git a/frontend-js/src/main/js/map/AbstractCustomMap.js b/frontend-js/src/main/js/map/AbstractCustomMap.js
index fda3320aa419b179b7e5703294a442810a0636c1..e91fee19c9ceb95dba3c39b26c279acea9b24bf4 100644
--- a/frontend-js/src/main/js/map/AbstractCustomMap.js
+++ b/frontend-js/src/main/js/map/AbstractCustomMap.js
@@ -963,7 +963,7 @@ AbstractCustomMap.prototype.setDebug = function(debug) {
 };
 
 AbstractCustomMap.prototype.isDebug = function() {
-  return this.debug === true;
+  return this._debug === true;
 };
 
 AbstractCustomMap.prototype.getTopLeftLatLng = function() {
diff --git a/frontend-js/src/main/js/map/ControlType.js b/frontend-js/src/main/js/map/ControlType.js
index 2612e7d1b81119a1edcd6051a918e1291db986c1..a6b80995c12afff5f1335c6f027a29870814d807 100644
--- a/frontend-js/src/main/js/map/ControlType.js
+++ b/frontend-js/src/main/js/map/ControlType.js
@@ -1,7 +1,6 @@
 "use strict";
 
 var ControlType = {
-  COMMENT_CHECKBOX : "COMMENT_CHECKBOX",
   SUBMAP_DIALOGS : "SUBMAP_DIALOGS",
   LOGO_IMG : "LOGO_IMG",
   LOGO_2_IMG : "LOGO_2_IMG",
diff --git a/frontend-js/src/main/js/map/CustomMap.js b/frontend-js/src/main/js/map/CustomMap.js
index 322dee81b14a7b31aa6149c17cdc94b888e00027..1bbcea3e86a59ef41036e4311b042da1488163e4 100644
--- a/frontend-js/src/main/js/map/CustomMap.js
+++ b/frontend-js/src/main/js/map/CustomMap.js
@@ -45,10 +45,6 @@ function CustomMap(options) {
 
   this.customizeGoogleMapView(options.getMapDiv());
 
-  this.createBelt();
-  
-  this.createMapMenu();
-  
   this.createMapChangedCallbacks();
 
   this.overlayCollections = [];
@@ -127,15 +123,6 @@ CustomMap.prototype.createLogo = function() {
   this.getGoogleMap().controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(logoControlDiv);
 };
 
-CustomMap.prototype.createBelt = function() {
-  var self = this;
-
-  this.divBelt = document.createElement('DIV');
-  this.divBelt.className = "headerBelt";
-
-  this.getGoogleMap().controls[google.maps.ControlPosition.TOP_LEFT].push(this.divBelt);
-};
-
 CustomMap.prototype.clearOverlays = function() {
   for ( var overlayName in this.overlayCollections) {
     if (this.overlayCollections.hasOwnProperty(overlayName)) {
@@ -271,25 +258,6 @@ CustomMap.prototype.openLayoutByName = function(name) {
   }
 };
 
-CustomMap.prototype.createMapMenu = function() {
-  var selfMap = this;
-
-  // create a button for overview images when the image is available
-  if (this.getTopOverviewImage() !== undefined && this.getTopOverviewImage() !== null) {
-    var submenuButtonDiv2 = document.createElement('button');
-    submenuButtonDiv2.id = "overview_button";
-    submenuButtonDiv2.innerHTML = "<i class='fa fa-sitemap' style='font-size:18px; font-weight:400; padding-right:10px;'></i> SHOW OVERVIEW";
-    submenuButtonDiv2.className = "overview_button";
-    submenuButtonDiv2.onclick = (function() {
-      return function() {
-        selfMap.showOverview();
-        return false;
-      };
-    })();
-    this.divBelt.appendChild(submenuButtonDiv2);
-  }
-};
-
 CustomMap.prototype.registerSource = function(overlayCollection) {
   var self = this;
 
@@ -569,209 +537,6 @@ CustomMap.prototype.removeSelection = function() {
   }
 };
 
-/**
- * This method will hide google map view and will present single image overview
- * of the data.
- */
-CustomMap.prototype.showOverview = function(overviewImageId) {
-  var overviewDialog = GuiConnector.getOverviewDialog();
-  overviewDialog.syncWindowResize();
-  if (this.getOverviewDiv() === undefined) {
-    logger.warn("Cannot show overview, because overview div is  undefined");
-  } else {
-    logger.debug("Show overview");
-    overviewDialog.show();
-
-    // resize dialog
-    var htmlTag = GuiConnector.getOverviewHtmlTag();
-
-    var width = Math.floor(window.innerWidth * 2 / 3);
-    var height = Math.floor(window.innerHeight * 2 / 3);
-
-    htmlTag.style.height = (height + 50) + "px";
-    htmlTag.style.width = (width + 20) + "px";
-
-    var self = this;
-
-    // remove all child nodes from overview div
-    while (this.getOverviewDiv().hasChildNodes()) {
-      this.getOverviewDiv().removeChild(this.getOverviewDiv().lastChild);
-    }
-
-    if (overviewImageId === undefined || overviewImageId === null) {
-      this.overviewImage = this.getConfiguration().TOP_OVERVIEW_IMAGE;
-    } else {
-      this.overviewImage = null;
-      for (var i = 0; i < this.getConfiguration().OVERVIEW_IMAGES.length; i++) {
-        if (this.getConfiguration().OVERVIEW_IMAGES[i].idObject === overviewImageId) {
-          this.overviewImage = this.getConfiguration().OVERVIEW_IMAGES[i];
-        }
-      }
-
-      if (this.overviewImage === null) {
-        logger.warn("Unknown overview image with id = " + overviewImageId);
-        this.overviewImage = this.getConfiguration().TOP_OVERVIEW_IMAGE;
-      }
-    }
-
-    // add image to overview div
-    this.overviewImageTag = document.createElement("IMG");
-    this.overviewImageTag.src = "../map_images/" + this.overviewImage.filename;
-    this.getOverviewDiv().appendChild(this.overviewImageTag);
-
-    var ratio = 1.0;
-
-    // check how image should be resized to fit dialog and resize it manually!!!
-    if (width / this.overviewImage.width > height / this.overviewImage.height) {
-      this.overviewImageTag.style.height = height + "px";
-      ratio = height / this.overviewImage.height;
-      width = this.overviewImage.width * ratio;
-
-      htmlTag.style.width = (width + 20) + "px";
-    } else {
-      this.overviewImageTag.style.width = width + "px";
-      ratio = width / this.overviewImage.width;
-      height = this.overviewImage.height * ratio;
-
-      htmlTag.style.height = (height + 50) + "px";
-    }
-
-    // center dialog
-    overviewDialog.jq.css("top", Math.max(0, (($(window).height() - overviewDialog.jq.outerHeight()) / 2)
-        + $(window).scrollTop())
-        + "px");
-    overviewDialog.jq.css("left", Math.max(0, (($(window).width() - overviewDialog.jq.outerWidth()) / 2)
-        + $(window).scrollLeft())
-        + "px");
-
-    // on click event (what should happen when we click on the image)
-    var onclickevent = function getClickPosition(e) {
-      var parentPosition = functions.getPosition(e.currentTarget);
-      var xPosition = e.clientX - parentPosition.x;
-      var yPosition = e.clientY - parentPosition.y;
-
-      var imgWidth = self.overviewImageTag.offsetWidth;
-
-      var currentRatio = imgWidth / self.overviewImage.width;
-
-      var xNormal = xPosition / currentRatio;
-      var yNormal = yPosition / currentRatio;
-      var point = {
-        x : xNormal,
-        y : yNormal
-      };
-
-      var link = null;
-      for (var i = 0; i < self.overviewImage.links.length; i++) {
-        if (functions.pointInsidePolygon(point, self.overviewImage.links[i].polygon)) {
-          if (link === null) {
-            link = self.overviewImage.links[i];
-          } else {
-            logger.warn("More than one link found. Skipping");
-          }
-        }
-      }
-      if (link !== null) {
-        if (link.type === "OverviewModelLink") {
-          logger.debug("Opening model from overview. ModelId: " + link.modelLinkId);
-          logger.debug("link coordinates [" + link.idObject + "]: " + link.latLng);
-          // TODO min zoom value can be different for every map, it should be
-          // changed in the future
-          self.showModel(link.modelLinkId, link.latLng, link.zoomLevel + self.getConfiguration().MIN_ZOOM);
-          overviewDialog.hide();
-        } else if (link.type === "OverviewImageLink") {
-          logger.debug("Opening image from overview. ImageId: " + link.imageLinkId);
-          self.showOverview(link.imageLinkId);
-        } else if (link.type === "OverviewSearchLink") {
-          logger.debug("Sending search query. Query: " + link.query);
-          GuiConnector.search(link.query);
-          overviewDialog.hide();
-        } else {
-          logger.warn("Unknown type of link: " + link.type + ". Don't know what to do... LinkId: " + link.idObject);
-        }
-      }
-    };
-
-    this.overviewImageTag.onclick = onclickevent;
-
-    // resize canvas where on mouse over highligh will appear
-    var canvas = document.getElementById("canvasDebug");
-    canvas.width = width;
-    canvas.height = height;
-    canvas.onclick = onclickevent;
-
-    // in debug mode draw clickable shapes
-    if (this.isDebug()) {
-      this.drawClickableShapes(canvas, ratio);
-    }
-
-    this.overviewImage.mousePos = {
-      x : 0,
-      y : 0
-    };
-
-    // this listener should be called when mouse moves over image, it purpose is
-    // to change coursor to pointer when mouse enters clickable polygon and back
-    // to normal when mouse leaves such region
-    var onmousemove = function getMouseOverPosition(e) {
-      var position = functions.getPosition(e.currentTarget);
-      position.x = e.clientX - position.x;
-      position.y = e.clientY - position.y;
-
-      var imgWidth = self.overviewImageTag.offsetWidth;
-
-      var currentRatio = imgWidth / self.overviewImage.width;
-
-      var xNormal = position.x / currentRatio;
-      var yNormal = position.y / currentRatio;
-      var point = {
-        x : xNormal,
-        y : yNormal
-      };
-
-      if (self.overviewImage.mousePos.x !== position.x || self.overviewImage.mousePos.y !== position.y) {
-        self.overviewImage.mousePos = position;
-        var link = null;
-        for (var i = 0; i < self.overviewImage.links.length; i++) {
-          if (functions.pointInsidePolygon(point, self.overviewImage.links[i].polygon)) {
-            link = self.overviewImage.links[i];
-          }
-        }
-        if (link === null) {
-          e.currentTarget.style.cursor = "auto";
-        } else {
-          e.currentTarget.style.cursor = "pointer";
-        }
-      }
-    };
-
-    // onmousemove listener should be assigned to canvas (which is on top of the
-    // image) and overviewimage (just in case something went wrong with resizing
-    // canvas)
-    canvas.onmousemove = onmousemove;
-    this.overviewImageTag.onmousemove = onmousemove;
-  }
-};
-
-CustomMap.prototype.drawClickableShapes = function(canvas, ratio) {
-  var ctx = canvas.getContext("2d");
-  // clear canvas
-  ctx.clearRect(0, 0, canvas.width, canvas.height);
-  for (var i = 0; i < this.overviewImage.links.length; i++) {
-    ctx.beginPath();
-    var polygon = this.overviewImage.links[i].polygon;
-    for (var j = 0; j < polygon.length; j++) {
-      var x = polygon[j].x * ratio;
-      var y = polygon[j].y * ratio;
-      ctx.moveTo(x, y);
-      x = polygon[(j + 1) % polygon.length].x * ratio;
-      y = polygon[(j + 1) % polygon.length].y * ratio;
-      ctx.lineTo(x, y);
-    }
-    ctx.stroke();
-  }
-};
-
 CustomMap.prototype.showModel = function(id, point, zoomLevel) {
   if (point !== undefined) {
     this.setCenter(id, point);
diff --git a/frontend-js/src/main/js/map/CustomMapOptions.js b/frontend-js/src/main/js/map/CustomMapOptions.js
index 6a16eb0a6a9b335fc2ac42eff82ef687f8d55e5a..262e7748ad7ce3b4bb343d6f93b2d2aeff71e170 100644
--- a/frontend-js/src/main/js/map/CustomMapOptions.js
+++ b/frontend-js/src/main/js/map/CustomMapOptions.js
@@ -110,7 +110,7 @@ CustomMapOptions.prototype.setMapDiv = function(mapDiv) {
 };
 
 CustomMapOptions.prototype.isDebug = function() {
-  return this.debug === true;
+  return this._debug === true;
 };
 
 module.exports = CustomMapOptions;
diff --git a/frontend-js/src/main/js/map/Submap.js b/frontend-js/src/main/js/map/Submap.js
index f24f4a01e3d1f91d0646b5172bfa78baf32741dc..18c3b3e7d6f76d98f33db7051f668b2d46a205c8 100644
--- a/frontend-js/src/main/js/map/Submap.js
+++ b/frontend-js/src/main/js/map/Submap.js
@@ -24,7 +24,8 @@ function Submap(customMap, model) {
     markerOptimization : customMap.isMarkerOptimization(),
     bigLogo : customMap.isBigLogo(),
     customTouchInterface : customMap.isCustomTouchInterface(),
-    project : null
+    project : null,
+    debug: customMap.isDebug()
   }));
 
   this.initialized = false;
diff --git a/frontend-js/src/main/js/minerva.js b/frontend-js/src/main/js/minerva.js
index 1c463a5d8d36e36edf7177d0e2edf707943fcaad..5bdc7b08a3d5d5d5e277839a18f894288e0d94c8 100644
--- a/frontend-js/src/main/js/minerva.js
+++ b/frontend-js/src/main/js/minerva.js
@@ -14,6 +14,7 @@ var DrugPanel = require('./gui/DrugPanel');
 var MiRnaDbOverlay = require('./map/overlay/MiRnaDbOverlay');
 var MiRnaPanel = require('./gui/MiRnaPanel');
 var OverlayPanel = require('./gui/OverlayPanel');
+var OverviewDialog = require('./gui/OverviewDialog');
 var SearchDbOverlay = require('./map/overlay/SearchDbOverlay');
 var SearchPanel = require('./gui/SearchPanel');
 var SubmapPanel = require('./gui/SubmapPanel');
@@ -292,6 +293,20 @@ function create(params) {
         };
       })();
       
+      if (project.getTopOverviewImage()!== undefined && project.getTopOverviewImage()!== null) {
+        var overviewDialog = new OverviewDialog({
+          customMap: result,
+          element: document.getElementsByName("overviewDialog")[0]
+        });
+        var showOverviewButton = document.getElementsByName("showOverviewButton")[0];
+        showOverviewButton.onclick = (function() {
+          return function() {
+            overviewDialog.showOverview();
+            return false;
+          };
+        })();
+        showOverviewButton.style.display="";
+      }
 
       if (ServerConnector.getSessionData().getShowComments()) {
         result.getControl(ControlType.COMMENT_CHECKBOX).checked=true;
diff --git a/frontend-js/src/test/js/gui/OverviewDialog-test.js b/frontend-js/src/test/js/gui/OverviewDialog-test.js
new file mode 100644
index 0000000000000000000000000000000000000000..3168c9727582f1968750b425bbe063b1077b8047
--- /dev/null
+++ b/frontend-js/src/test/js/gui/OverviewDialog-test.js
@@ -0,0 +1,54 @@
+"use strict";
+
+var Helper = require('../helper');
+
+require("../mocha-config.js");
+
+var CustomMap = require('../../../main/js/map/CustomMap');
+var OverviewDialog = require('../../../main/js/gui/OverviewDialog');
+var Project = require('../../../main/js/map/data/Project');
+
+var chai = require('chai');
+var assert = chai.assert;
+var logger = require('../logger');
+
+describe('OverviewDialog', function() {
+
+  var helper;
+  before(function() {
+    helper = new Helper();
+  });
+
+  it('open image', function() {
+    return ServerConnector.readFile("testFiles/projectWithImages.json").then(function(fileContent) {
+      var project = new Project(JSON.parse(fileContent));
+      var options = helper.createOptions(project);
+      var map = new CustomMap(options);
+
+      var dialog = new OverviewDialog({
+        element : testDiv,
+        customMap : map
+      });
+
+      dialog.showOverview(project.getOverviewImages()[1].idObject);
+      dialog.destroy();
+    });
+  });
+
+  it('open invalid image', function() {
+    return ServerConnector.readFile("testFiles/projectWithImages.json").then(function(fileContent) {
+      var project = new Project(JSON.parse(fileContent));
+      var options = helper.createOptions(project);
+      var map = new CustomMap(options);
+
+      var dialog = new OverviewDialog({
+        element : testDiv,
+        customMap : map
+      });
+
+      dialog.showOverview(-1123);
+      dialog.destroy();
+    });
+  });
+
+});
diff --git a/frontend-js/src/test/js/helper.js b/frontend-js/src/test/js/helper.js
index 18d101d871f9cf42084b0d1b0c613e170a23d30b..9990242cb10609427081dad6ecef028612477c18 100644
--- a/frontend-js/src/test/js/helper.js
+++ b/frontend-js/src/test/js/helper.js
@@ -65,6 +65,24 @@ Helper.prototype.createMenuDiv = function() {
   clearButton.setAttribute("name", "clearButton");
   result.appendChild(clearButton);
 
+  var showOverviewButton = document.createElement("button");
+  showOverviewButton.setAttribute("name", "showOverviewButton");
+  result.appendChild(showOverviewButton);
+
+  
+  return result;
+};
+
+Helper.prototype.createDialogsDiv = function() {
+  var result = document.createElement("div");
+  result.setAttribute("name", "dialogs");
+  result.appendChild(this.createOverviewDialogDiv());
+  return result;
+};
+
+Helper.prototype.createOverviewDialogDiv = function() {
+  var result = document.createElement("div");
+  result.setAttribute("name", "overviewDialog");
   return result;
 };
 
diff --git a/frontend-js/src/test/js/map/AbstractCustomMap-test.js b/frontend-js/src/test/js/map/AbstractCustomMap-test.js
index 50bfabb18ba67cfedd9a2cb1fa7c25673a72c751..47e295e032e2d0e154ef858c10a1a3700cec9e1c 100644
--- a/frontend-js/src/test/js/map/AbstractCustomMap-test.js
+++ b/frontend-js/src/test/js/map/AbstractCustomMap-test.js
@@ -368,4 +368,11 @@ describe('AbstractCustomMap', function() {
     });
 
   });
+
+  it("getDebug", function() {
+    var map = helper.createAbstractCustomMap();
+    map.setDebug(true);
+    assert.ok(map.isDebug());
+  });
+
 });
diff --git a/frontend-js/src/test/js/map/CustomMapOptions-test.js b/frontend-js/src/test/js/map/CustomMapOptions-test.js
index 42060a7a44e36631fc111176f01d16e09d59e02c..e5e6a1243ee2774d82d8ccfa20820c8e183f48a1 100644
--- a/frontend-js/src/test/js/map/CustomMapOptions-test.js
+++ b/frontend-js/src/test/js/map/CustomMapOptions-test.js
@@ -48,4 +48,15 @@ describe('CustomMapOptions', function() {
     assert.equal(0, logger.getErrors().length);
     assert.equal(0, logger.getWarnings().length);
   });
+  
+  it("getDebug", function() {
+    var project = helper.createProject();
+    var options = new CustomMapOptions({
+      mapDiv : testDiv,
+      project : project,
+      debug : true,
+    });
+
+    assert.ok(options.isDebug());
+  });
 });
diff --git a/frontend-js/src/test/js/minerva-test.js b/frontend-js/src/test/js/minerva-test.js
index 43ee593d931527a3c5efed12d74747bbc05ddac5..8a3499805c2df0b38d0b61420a9012a84105024d 100644
--- a/frontend-js/src/test/js/minerva-test.js
+++ b/frontend-js/src/test/js/minerva-test.js
@@ -5,6 +5,7 @@ var Helper = require('./helper');
 require("./mocha-config.js");
 
 var minerva = require('../../main/js/minerva');
+var Project = require('../../main/js/map/data/Project');
 
 var chai = require('chai');
 var assert = chai.assert;
@@ -23,11 +24,15 @@ describe('minerva global', function() {
 
     global.menuDiv = helper.createMenuDiv();
     document.body.appendChild(global.menuDiv);
+    
+    global.dialogsDiv = helper.createDialogsDiv();
+    document.body.appendChild(global.dialogsDiv);
   });
 
   afterEach(function() {
     document.body.removeChild(global.leftPanelTab);
     document.body.removeChild(global.menuDiv);
+    document.body.removeChild(global.dialogsDiv);
   });
 
   it('create', function() {
@@ -39,6 +44,20 @@ describe('minerva global', function() {
     });
   });
 
+  it('create with overview', function() {
+    return ServerConnector.readFile("testFiles/projectWithImages.json").then(function(fileContent) {
+      var project = new Project(JSON.parse(fileContent));
+      var options = helper.createOptions(project);
+
+      return minerva.create(options);
+    }).then(function(result) {
+      assert.ok(result);
+      assert.equal(logger.getWarnings().length, 1);
+      var showOverviewButton = document.getElementsByName("showOverviewButton")[0];
+      showOverviewButton.onclick();
+    });
+  });
+
   it("showComments", function() {
     var options = helper.createCustomMapOptions();
     return minerva.create(options).then(function() {
diff --git a/frontend-js/testFiles/projectWithImages.json b/frontend-js/testFiles/projectWithImages.json
new file mode 100644
index 0000000000000000000000000000000000000000..b989ec48df62f47ce57be130dd7028861f6240a5
--- /dev/null
+++ b/frontend-js/testFiles/projectWithImages.json
@@ -0,0 +1 @@
+{"version":"0","idObject":18115,"name":"UNKNOWN DISEASE MAP","projectId":"complex_model_with_images","description":"","map":{"name":"main","idObject":19397,"tileSize":256,"width":495,"height":357,"minZoom":2,"maxZoom":3,"layouts":[{"modelId":19397,"name":"Pathways and compartments","status":"Not available","progress":"0.00","directory":"fbdbe43de73fe38f62889b89cb863adb/_nested0","creator":"","inputDataAvailable":"false","idObject":17987},{"modelId":19397,"name":"Network","status":"Not available","progress":"0.00","directory":"fbdbe43de73fe38f62889b89cb863adb/_normal0","creator":"","inputDataAvailable":"false","idObject":17988},{"modelId":19397,"name":"Empty","status":"Not available","progress":"0.00","directory":"fbdbe43de73fe38f62889b89cb863adb/_empty0","creator":"","inputDataAvailable":"false","idObject":17989}],"submodels":[{"name":"s2","idObject":19400,"tileSize":256,"width":451,"height":253,"minZoom":2,"maxZoom":3,"layouts":[{"modelId":19400,"name":"Pathways and compartments","status":"Not available","progress":"0.00","directory":"fbdbe43de73fe38f62889b89cb863adb/_nested2","creator":"","inputDataAvailable":"false","idObject":17984},{"modelId":19400,"name":"Network","status":"Not available","progress":"0.00","directory":"fbdbe43de73fe38f62889b89cb863adb/_normal2","creator":"","inputDataAvailable":"false","idObject":17985},{"modelId":19400,"name":"Empty","status":"Not available","progress":"0.00","directory":"fbdbe43de73fe38f62889b89cb863adb/_empty2","creator":"","inputDataAvailable":"false","idObject":17986}],"submodels":[],"centerLatLng":{"lat":79.19006423440219,"lng":-135.09977827050997},"topLeftLatLng":{"lat":85.05112877980659,"lng":-180.0},"bottomRightLatLng":{"lat":78.0903352323621,"lng":-90.0}},{"name":"s3","idObject":19399,"tileSize":256,"width":421,"height":315,"minZoom":2,"maxZoom":3,"layouts":[{"modelId":19399,"name":"Pathways and compartments","status":"Not available","progress":"0.00","directory":"fbdbe43de73fe38f62889b89cb863adb/_nested3","creator":"","inputDataAvailable":"false","idObject":17978},{"modelId":19399,"name":"Network","status":"Not available","progress":"0.00","directory":"fbdbe43de73fe38f62889b89cb863adb/_normal3","creator":"","inputDataAvailable":"false","idObject":17979},{"modelId":19399,"name":"Empty","status":"Not available","progress":"0.00","directory":"fbdbe43de73fe38f62889b89cb863adb/_empty3","creator":"","inputDataAvailable":"false","idObject":17980}],"submodels":[],"centerLatLng":{"lat":79.19139766235872,"lng":-135.10688836104512},"topLeftLatLng":{"lat":85.05112877980659,"lng":-180.0},"bottomRightLatLng":{"lat":74.06362505154212,"lng":-90.0}},{"name":"s1","idObject":19398,"tileSize":256,"width":571,"height":276,"minZoom":2,"maxZoom":4,"layouts":[{"modelId":19398,"name":"Pathways and compartments","status":"Not available","progress":"0.00","directory":"fbdbe43de73fe38f62889b89cb863adb/_nested1","creator":"","inputDataAvailable":"false","idObject":17981},{"modelId":19398,"name":"Network","status":"Not available","progress":"0.00","directory":"fbdbe43de73fe38f62889b89cb863adb/_normal1","creator":"","inputDataAvailable":"false","idObject":17982},{"modelId":19398,"name":"Empty","status":"Not available","progress":"0.00","directory":"fbdbe43de73fe38f62889b89cb863adb/_empty1","creator":"","inputDataAvailable":"false","idObject":17983}],"submodels":[],"centerLatLng":{"lat":79.18613072613702,"lng":-135.07880910683014},"topLeftLatLng":{"lat":85.05112877980659,"lng":-180.0},"bottomRightLatLng":{"lat":79.44906929997262,"lng":-90.0}}],"centerLatLng":{"lat":79.18840067864828,"lng":-135.0909090909091},"topLeftLatLng":{"lat":85.05112877980659,"lng":-180.0},"bottomRightLatLng":{"lat":74.71754541589858,"lng":-90.0}},"overviewImageViews":[{"filename":"fbdbe43de73fe38f62889b89cb863adb/sub_image.png","width":963,"height":639,"links":[{"polygon":[{"x":200.0,"y":200.0},{"x":200.0,"y":400.0},{"x":400.0,"y":400.0},{"x":400.0,"y":200.0}],"zoomLevel":1,"latLng":{"lat":84.89177465079632,"lng":-161.8181818181818},"modelLinkId":19397,"type":"OverviewModelLink","idObject":2369}],"idObject":1261},{"filename":"fbdbe43de73fe38f62889b89cb863adb/test.png","width":963,"height":639,"links":[{"polygon":[{"x":10.0,"y":10.0},{"x":100.0,"y":10.0},{"x":100.0,"y":100.0},{"x":10.0,"y":100.0}],"imageLinkId":1261,"type":"OverviewImageLink","idObject":2370},{"polygon":[{"x":200.0,"y":200.0},{"x":200.0,"y":400.0},{"x":400.0,"y":400.0},{"x":400.0,"y":200.0}],"zoomLevel":0,"latLng":{"lat":84.89177465079632,"lng":-178.1818181818182},"modelLinkId":19397,"type":"OverviewModelLink","idObject":2371}],"idObject":1262}],"topOverviewImage":{"filename":"fbdbe43de73fe38f62889b89cb863adb/test.png","width":963,"height":639,"links":[{"polygon":[{"x":10.0,"y":10.0},{"x":100.0,"y":10.0},{"x":100.0,"y":100.0},{"x":10.0,"y":100.0}],"imageLinkId":1261,"type":"OverviewImageLink","idObject":2370},{"polygon":[{"x":200.0,"y":200.0},{"x":200.0,"y":400.0},{"x":400.0,"y":400.0},{"x":400.0,"y":200.0}],"zoomLevel":0,"latLng":{"lat":84.89177465079632,"lng":-178.1818181818182},"modelLinkId":19397,"type":"OverviewModelLink","idObject":2371}],"idObject":1262}}
\ No newline at end of file
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/OverviewModelLink.java b/model/src/main/java/lcsb/mapviewer/model/map/OverviewModelLink.java
index 60589e09f138629a4e943b1edf8a1f4e87a2e025..b3ecb4f6428892a2144431c6d4d6ae713c3989d4 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/OverviewModelLink.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/OverviewModelLink.java
@@ -71,12 +71,8 @@ public class OverviewModelLink extends OverviewLink {
 	 * @return the model
 	 * @see #linkedModel
 	 */
-	public Model getLinkedModel() {
-		if (linkedModel != null) {
-			return linkedModel.getModel();
-		} else {
-			return null;
-		}
+	public ModelData getLinkedModel() {
+		return linkedModel;
 	}
 
 	/**
diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/project/ProjectMetaData.java b/rest-api/src/main/java/lcsb/mapviewer/api/project/ProjectMetaData.java
index 6f8f5fcc44d609b57ba02c3b2932f8cd839734c4..090b6d0dc13c2a43c7005fc4a70001697d7d5272 100644
--- a/rest-api/src/main/java/lcsb/mapviewer/api/project/ProjectMetaData.java
+++ b/rest-api/src/main/java/lcsb/mapviewer/api/project/ProjectMetaData.java
@@ -69,41 +69,6 @@ public class ProjectMetaData implements Serializable {
 	protected ProjectMetaData() {
 	}
 
-	public ProjectMetaData(Project project) {
-		OverviewImageViewFactory factory = new OverviewImageViewFactory();
-		ModelData model = null;
-		if (project.getModels().size() > 0) {
-			model = project.getModels().iterator().next();
-		}
-
-		this.setName(project.getName());
-		this.setProjectId(project.getProjectId());
-		this.setIdObject(project.getId());
-
-		if (model != null) {
-			this.setOverviewImageViews(factory.createList(model.getOverviewImages()));
-			this.setVersion(model.getMapVersion());
-			this.setDescription(model.getNotes());
-
-			Set<OverviewImage> set = new HashSet<OverviewImage>();
-			set.addAll(model.getOverviewImages());
-			for (OverviewImage image : model.getOverviewImages()) {
-				for (OverviewLink ol : image.getLinks()) {
-					if (ol instanceof OverviewImageLink) {
-						set.remove(((OverviewImageLink) ol).getLinkedOverviewImage());
-					}
-				}
-			}
-			if (set.size() > 0) {
-				this.setTopOverviewImage(factory.create(set.iterator().next()));
-			} else if (model.getOverviewImages().size() > 0) {
-				logger.warn("Cannot determine top level image. Taking first one. " + model.getOverviewImages().get(0).getFilename());
-				this.setTopOverviewImage(factory.create(model.getOverviewImages().get(0)));
-			}
-			this.setMap(new ModelMetaData(model));
-
-		}
-	}
 
 	/**
 	 * @return the version
diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/project/ProjectRestImpl.java b/rest-api/src/main/java/lcsb/mapviewer/api/project/ProjectRestImpl.java
index 0588b6d4cef169988978cde0c4d0baac0e58b7bf..27157aa2be15a0e8e93e71ae6a7a61583954955c 100644
--- a/rest-api/src/main/java/lcsb/mapviewer/api/project/ProjectRestImpl.java
+++ b/rest-api/src/main/java/lcsb/mapviewer/api/project/ProjectRestImpl.java
@@ -17,7 +17,11 @@ import org.springframework.web.bind.annotation.RequestParam;
 
 import lcsb.mapviewer.common.exception.InvalidStateException;
 import lcsb.mapviewer.model.Project;
+import lcsb.mapviewer.model.map.OverviewImage;
+import lcsb.mapviewer.model.map.OverviewImageLink;
+import lcsb.mapviewer.model.map.OverviewLink;
 import lcsb.mapviewer.model.map.model.Model;
+import lcsb.mapviewer.model.map.model.ModelData;
 import lcsb.mapviewer.model.map.reaction.Modifier;
 import lcsb.mapviewer.model.map.reaction.Product;
 import lcsb.mapviewer.model.map.reaction.Reactant;
@@ -32,31 +36,35 @@ import lcsb.mapviewer.services.interfaces.IUserService;
 import lcsb.mapviewer.services.search.data.ElementIdentifier.ElementIdentifierType;
 import lcsb.mapviewer.services.search.data.LightReactionView;
 import lcsb.mapviewer.services.view.AnnotationViewFactory;
+import lcsb.mapviewer.services.view.OverviewImageViewFactory;
 
 @Transactional(value = "txManager")
 public class ProjectRestImpl {
-	Logger									logger = Logger.getLogger(ProjectRestImpl.class);
+	Logger													 logger	= Logger.getLogger(ProjectRestImpl.class);
 
 	@Autowired
-	private IUserService		userService;
+	private IUserService						 userService;
 
 	@Autowired
-	private IProjectService	projectService;
+	private IProjectService					 projectService;
 
 	@Autowired
-	private IModelService		modelService;
+	private IModelService						 modelService;
 
 	@Autowired
-	private ISearchService	searchService;
+	private ISearchService					 searchService;
 
 	@Autowired
-	AnnotationViewFactory		annotationViewFactory;
+	AnnotationViewFactory						 annotationViewFactory;
+
+	@Autowired
+	private OverviewImageViewFactory factory;
 
 	public ProjectMetaData getMetaData(@RequestParam(value = "projectId") String projectId, @RequestParam(value = "token") String token)
 			throws SecurityException {
 
 		Project project = projectService.getProjectByProjectId(projectId, userService.getToken(token));
-		ProjectMetaData result = new ProjectMetaData(project);
+		ProjectMetaData result = createData(project);
 		if (project.getOrganism() != null) {
 			result.setOrganism(annotationViewFactory.create(project.getOrganism()));
 		}
@@ -66,6 +74,43 @@ public class ProjectRestImpl {
 		return result;
 	}
 
+	private ProjectMetaData createData(Project project) {
+		ProjectMetaData result = new ProjectMetaData();
+		ModelData model = null;
+		if (project.getModels().size() > 0) {
+			model = project.getModels().iterator().next();
+		}
+
+		result.setName(project.getName());
+		result.setProjectId(project.getProjectId());
+		result.setIdObject(project.getId());
+
+		if (model != null) {
+			result.setOverviewImageViews(factory.createList(model.getOverviewImages()));
+			result.setVersion(model.getMapVersion());
+			result.setDescription(model.getNotes());
+
+			Set<OverviewImage> set = new HashSet<OverviewImage>();
+			set.addAll(model.getOverviewImages());
+			for (OverviewImage image : model.getOverviewImages()) {
+				for (OverviewLink ol : image.getLinks()) {
+					if (ol instanceof OverviewImageLink) {
+						set.remove(((OverviewImageLink) ol).getLinkedOverviewImage());
+					}
+				}
+			}
+			if (set.size() > 0) {
+				result.setTopOverviewImage(factory.create(set.iterator().next()));
+			} else if (model.getOverviewImages().size() > 0) {
+				logger.warn("Cannot determine top level image. Taking first one. " + model.getOverviewImages().get(0).getFilename());
+				result.setTopOverviewImage(factory.create(model.getOverviewImages().get(0)));
+			}
+			result.setMap(new ModelMetaData(model));
+		}
+		
+		return result;
+	}
+
 	/**
 	 * @return the userService
 	 * @see #userService
@@ -355,4 +400,21 @@ public class ProjectRestImpl {
 		return searchService.getSuggestedQueryList(model);
 	}
 
+	/**
+	 * @return the factory
+	 * @see #factory
+	 */
+	public OverviewImageViewFactory getFactory() {
+		return factory;
+	}
+
+	/**
+	 * @param factory
+	 *          the factory to set
+	 * @see #factory
+	 */
+	public void setFactory(OverviewImageViewFactory factory) {
+		this.factory = factory;
+	}
+
 }
diff --git a/rest-api/src/test/java/lcsb/mapviewer/api/RestTestFunctions.java b/rest-api/src/test/java/lcsb/mapviewer/api/RestTestFunctions.java
index 336cd7a914496ea050327c148503df5a27dc71f7..52f66532ff47c7eb78d7af1ad879fd29b8dc1954 100644
--- a/rest-api/src/test/java/lcsb/mapviewer/api/RestTestFunctions.java
+++ b/rest-api/src/test/java/lcsb/mapviewer/api/RestTestFunctions.java
@@ -46,11 +46,18 @@ import org.xml.sax.SAXException;
 
 import lcsb.mapviewer.common.Configuration;
 import lcsb.mapviewer.common.exception.InvalidXmlSchemaException;
+import lcsb.mapviewer.converter.ComplexZipConverter;
+import lcsb.mapviewer.converter.ComplexZipConverterParams;
 import lcsb.mapviewer.converter.ConverterParams;
+import lcsb.mapviewer.converter.InvalidInputDataExecption;
 import lcsb.mapviewer.converter.model.celldesigner.CellDesignerXmlParser;
+import lcsb.mapviewer.converter.zip.ModelZipEntryFile;
+import lcsb.mapviewer.converter.zip.ZipEntryFile;
 import lcsb.mapviewer.model.map.model.Model;
+import lcsb.mapviewer.model.map.model.SubmodelType;
 import lcsb.mapviewer.persist.DbUtils;
 import lcsb.mapviewer.services.interfaces.IUserService;
+import lcsb.mapviewer.services.utils.CreateProjectParams;
 import lcsb.mapviewer.services.view.AuthenticationToken;
 
 @Transactional(value = "txManager")
@@ -160,19 +167,43 @@ public abstract class RestTestFunctions {
 	private static Map<String, Model> models = new HashMap<String, Model>();
 
 	protected Model getModelForFile(String fileName, boolean fromCache) throws Exception {
+		Model result = null;
 		if (!fromCache) {
 			logger.debug("File without cache: " + fileName);
-			return new CellDesignerXmlParser().createModel(new ConverterParams().filename(fileName));
+			result = getModelForFile(fileName);
+		} else {
+			result = RestTestFunctions.models.get(fileName);
+			if (result == null) {
+				logger.debug("File to cache: " + fileName);
+
+				result = getModelForFile(fileName);
+				RestTestFunctions.models.put(fileName, result);
+			}
 		}
-		Model result = RestTestFunctions.models.get(fileName);
-		if (result == null) {
-			logger.debug("File to cache: " + fileName);
+		return result;
+	}
 
-			CellDesignerXmlParser parser = new CellDesignerXmlParser();
-			result = parser.createModel(new ConverterParams().filename(fileName).sizeAutoAdjust(false));
-			RestTestFunctions.models.put(fileName, result);
+	private Model getModelForFile(String fileName) throws InvalidInputDataExecption, IOException {
+		if (fileName.endsWith("zip")) {
+			ComplexZipConverter<CellDesignerXmlParser> parser = new ComplexZipConverter<CellDesignerXmlParser>(CellDesignerXmlParser.class);
+			ComplexZipConverterParams complexParams;
+			complexParams = new ComplexZipConverterParams().zipFile(fileName);
+			ZipEntryFile entry1 = new ModelZipEntryFile("main.xml", "main", true, false, SubmodelType.UNKNOWN);
+			ZipEntryFile entry2 = new ModelZipEntryFile("submaps/s1.xml", "s1", false, false, SubmodelType.UNKNOWN);
+			ZipEntryFile entry3 = new ModelZipEntryFile("submaps/s2.xml", "s2", false, false, SubmodelType.UNKNOWN);
+			ZipEntryFile entry4 = new ModelZipEntryFile("submaps/s3.xml", "s3", false, false, SubmodelType.UNKNOWN);
+			ZipEntryFile entry5 = new ModelZipEntryFile("submaps/mapping.xml", "mapping", false, true, SubmodelType.UNKNOWN);
+			complexParams.entry(entry1);
+			complexParams.entry(entry2);
+			complexParams.entry(entry3);
+			complexParams.entry(entry4);
+			complexParams.entry(entry5);
+
+			return parser.createModel(complexParams);
+
+		} else {
+			return new CellDesignerXmlParser().createModel(new ConverterParams().filename(fileName));
 		}
-		return result;
 	}
 
 	protected String createTmpFileName() {
diff --git a/rest-api/src/test/java/lcsb/mapviewer/api/project/AllProjectTests.java b/rest-api/src/test/java/lcsb/mapviewer/api/project/AllProjectTests.java
index befbc9585493716e716ed955aa67ed14c9cba576..0453ff0272fbe24a3bb6757ceb917126556ea02c 100644
--- a/rest-api/src/test/java/lcsb/mapviewer/api/project/AllProjectTests.java
+++ b/rest-api/src/test/java/lcsb/mapviewer/api/project/AllProjectTests.java
@@ -6,7 +6,6 @@ import org.junit.runners.Suite.SuiteClasses;
 
 @RunWith(Suite.class)
 @SuiteClasses({ ModelMetaDataTest.class,// 
-	ProjectMetaDataTest.class,// 
 	ProjectRestImplTest.class })
 public class AllProjectTests {
 
diff --git a/rest-api/src/test/java/lcsb/mapviewer/api/project/ProjectMetaDataTest.java b/rest-api/src/test/java/lcsb/mapviewer/api/project/ProjectMetaDataTest.java
deleted file mode 100644
index 706e7db2f95a2b6fc05f53943f32494f3af11d00..0000000000000000000000000000000000000000
--- a/rest-api/src/test/java/lcsb/mapviewer/api/project/ProjectMetaDataTest.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package lcsb.mapviewer.api.project;
-
-import static org.junit.Assert.assertNotNull;
-
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.Test;
-
-import com.google.gson.Gson;
-
-import lcsb.mapviewer.model.Project;
-
-public class ProjectMetaDataTest {
-
-	@AfterClass
-	public static void tearDownAfterClass() throws Exception {
-	}
-
-	@Before
-	public void setUp() throws Exception {
-	}
-
-	@After
-	public void tearDown() throws Exception {
-	}
-
-	@Test
-	public void testToGson() {
-		try {
-			Project project = new Project();
-			ProjectMetaData data = new ProjectMetaData(project);
-			Gson gson = new Gson();
-			assertNotNull(gson.toJson(data));
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-}
diff --git a/rest-api/src/test/java/lcsb/mapviewer/api/project/ProjectRestImplTest.java b/rest-api/src/test/java/lcsb/mapviewer/api/project/ProjectRestImplTest.java
index f3ffe752fd34822f4d89bd2f9e69af0afc49304e..6155d0b7a0ea33727fcad7811839d282456e854d 100644
--- a/rest-api/src/test/java/lcsb/mapviewer/api/project/ProjectRestImplTest.java
+++ b/rest-api/src/test/java/lcsb/mapviewer/api/project/ProjectRestImplTest.java
@@ -2,6 +2,7 @@ package lcsb.mapviewer.api.project;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyString;
 
@@ -17,6 +18,8 @@ import org.junit.Test;
 import org.mockito.Mockito;
 import org.springframework.beans.factory.annotation.Autowired;
 
+import com.google.gson.Gson;
+
 import lcsb.mapviewer.api.RestTestFunctions;
 import lcsb.mapviewer.model.map.model.Model;
 import lcsb.mapviewer.services.interfaces.IModelService;
@@ -75,6 +78,32 @@ public class ProjectRestImplTest extends RestTestFunctions {
 		}
 	}
 
+	@Test
+	public void testGetMetaData() throws Exception {
+		try {
+			ProjectRestImpl projectRest = createMockProjectRest("testFiles/model/sample.xml");
+			ProjectMetaData result = projectRest.getMetaData("sample", token.getId());
+			Gson gson = new Gson();
+			assertNotNull(gson.toJson(result));
+		} catch (Exception e) {
+			e.printStackTrace();
+			throw e;
+		}
+	}
+
+	@Test
+	public void testGetMetaDataForComplexWithImages() throws Exception {
+		try {
+			ProjectRestImpl projectRest = createMockProjectRest("testFiles/model/complex_model_with_submaps.zip");
+			ProjectMetaData result = projectRest.getMetaData("sample", token.getId());
+			Gson gson = new Gson();
+			assertNotNull(gson.toJson(result));
+		} catch (Exception e) {
+			e.printStackTrace();
+			throw e;
+		}
+	}
+
 	private ProjectRestImpl createMockProjectRest(String string) throws Exception {
 		Model model = super.getModelForFile(string, true);
 		IModelService mockModelService = Mockito.mock(IModelService.class);
diff --git a/rest-api/testFiles/model/complex_model_with_submaps.zip b/rest-api/testFiles/model/complex_model_with_submaps.zip
new file mode 100644
index 0000000000000000000000000000000000000000..5985c849bbeff096451d99b43a430ec6c266cf5b
Binary files /dev/null and b/rest-api/testFiles/model/complex_model_with_submaps.zip differ
diff --git a/service/src/main/java/lcsb/mapviewer/services/view/OverviewLinkViewFactory.java b/service/src/main/java/lcsb/mapviewer/services/view/OverviewLinkViewFactory.java
index 40d88478e46a0246d242db6d34425eeaf56cfe4e..c602505e0cf3bd8e9284724bcfb8254e6ab13a9d 100644
--- a/service/src/main/java/lcsb/mapviewer/services/view/OverviewLinkViewFactory.java
+++ b/service/src/main/java/lcsb/mapviewer/services/view/OverviewLinkViewFactory.java
@@ -25,7 +25,7 @@ public class OverviewLinkViewFactory extends AbstractViewFactory<OverviewLink, O
 	/**
 	 * Default class logger.
 	 */
-	private static Logger	logger	= Logger.getLogger(OverviewLinkViewFactory.class);
+	private static Logger logger = Logger.getLogger(OverviewLinkViewFactory.class);
 
 	@Override
 	public OverviewLinkView create(OverviewLink object) {
@@ -37,10 +37,11 @@ public class OverviewLinkViewFactory extends AbstractViewFactory<OverviewLink, O
 		result.setPolygon(object.getPolygon());
 
 		if (object instanceof OverviewModelLink) {
-			result.setModelLinkId(((OverviewModelLink) object).getLinkedModel().getId());
-			CoordinationConverter cc = new CoordinationConverter(((OverviewModelLink) object).getLinkedModel());
-			result.setLatLng(cc.toLatLng(new Point2D.Double(((OverviewModelLink) object).getxCoord(), ((OverviewModelLink) object).getyCoord())));
-			result.setZoomLevel(((OverviewModelLink) object).getZoomLevel());
+			OverviewModelLink modelLink = (OverviewModelLink) object;
+			result.setModelLinkId(modelLink.getLinkedModel().getId());
+			CoordinationConverter cc = new CoordinationConverter(modelLink.getLinkedModel());
+			result.setLatLng(cc.toLatLng(new Point2D.Double(modelLink.getxCoord(), modelLink.getyCoord())));
+			result.setZoomLevel(modelLink.getZoomLevel());
 
 		} else if (object instanceof OverviewImageLink) {
 			result.setImageLinkId(((OverviewImageLink) object).getLinkedOverviewImage().getId());
diff --git a/web/src/main/webapp/index.xhtml b/web/src/main/webapp/index.xhtml
index f7208909b305aaca2e3ced22a29043b906917b69..6e0199f6adeaab667694c5c091608918b200fa91 100644
--- a/web/src/main/webapp/index.xhtml
+++ b/web/src/main/webapp/index.xhtml
@@ -47,7 +47,7 @@ function initMap(){
 		    bigLogo : windowsTouchInterface, 
 		    overviewDiv : overviewDiv,
 		    customTouchInterface: windowsTouchInterface,
-		    debug:true,
+		    debug:minerva.GuiConnector.getParams['debug']!==undefined,
 
 				dataCollections: [
 								{name: "search"},
@@ -122,6 +122,14 @@ function initMap(){
 					</button>
 				</div>
 				<div name="versionDiv" class="headerTextBold"/>
+
+				<div style="float: left;">
+					<button name="showOverviewButton" class="overview_button" style="display:none" >
+						<i class='fa fa-sitemap' style='font-size:18px; font-weight:400; padding-right:10px;'></i> 
+						SHOW OVERVIEW
+					</button>
+				</div>
+
 				<div class="rightHeaderMenu">
 					<div class="div4checkboxes">
 						<input type="checkbox" name ="legendCheckbox" />
@@ -130,7 +138,7 @@ function initMap(){
 						<input type="checkbox" name="commentCheckbox"/>
 						<label for ="commentCheckbox" >COMMENTS</label>
 
-						<button class="overview_button" name="refreshCommentButton" style="display:none">
+						<button name="refreshCommentButton" class="overview_button" style="display:none">
 							<i class='fa fa-refresh' style='font-size:21px; font-weight:400;'></i>
 						</button>
 					</div>
@@ -172,6 +180,11 @@ function initMap(){
 	<ui:include src="/WEB-INF/components/map/feedbackDialog.xhtml" />
 	<ui:include src="/WEB-INF/components/map/missingConnectionDialog.xhtml" />
 
+
+<div name="dialogs">
+	<div name="overviewDialog"/>
+</div>
+
 </h:body>
 </f:view>
 </html>
diff --git a/web/src/main/webapp/resources/css/global.css b/web/src/main/webapp/resources/css/global.css
index 64a70301ce3be7e8aaf3a6a05f0fbfc2abe36329..e66f255d45a83f2c96f73b0c4a0e4338933014cf 100644
--- a/web/src/main/webapp/resources/css/global.css
+++ b/web/src/main/webapp/resources/css/global.css
@@ -1,3 +1,10 @@
+.canvasDebugClass {
+	border: 0;
+	position: absolute;
+	top: 0;
+	left: 0
+}
+
 .menuBelt {
 	width: 100%;
 	min-height: 36px;
diff --git a/web/src/main/webapp/resources/css/style.css b/web/src/main/webapp/resources/css/style.css
index 432256d04398c5c354bca25a13df2d4abcdc03b0..f58853b33638d7efd4f516307f09213eff5c6232 100644
--- a/web/src/main/webapp/resources/css/style.css
+++ b/web/src/main/webapp/resources/css/style.css
@@ -1113,9 +1113,6 @@ input[type=file] {width:280px !important; top:15px !important;}
 
 #content p span {font-weight:400}
 
-.overviewContainerClass {width:100%; height:100%;}
-.overviewDivClass {background-color: #ffffff;border:0; margin-left:10px; position: absolute; top:2; left:0}
-.canvasDebugClass {border:0; position: absolute; top:2; left:0}
 
 .labelTextBold {font-size: 13px; font-weight: 900;}
 .labelText {font-size: 13px;}