diff --git a/frontend-js/src/main/js/ConfigurationOption.js b/frontend-js/src/main/js/ConfigurationOption.js
index 53841aa0dc6b8dd5d4963324477207ef48648bd6..d7ce2f8fd3c94d4c958dd1e01144e45a79551f3d 100644
--- a/frontend-js/src/main/js/ConfigurationOption.js
+++ b/frontend-js/src/main/js/ConfigurationOption.js
@@ -1,71 +1,71 @@
-"use strict";
-
-var ObjectWithListeners = require('./ObjectWithListeners');
-
-var logger = require('./logger');
-
-function ConfigurationOption(data) {
-  // call super constructor
-  ObjectWithListeners.call(this);
-
-  var self = this;
-  if (data instanceof ConfigurationOption) {
-    self.setType(data.getType());
-    self.setCommonName(data.getCommonName());
-    self.setValue(data.getValue());
-    self.setGroup(data.getGroup());
-    self.setValueType(data.getValueType());
-  } else {
-    self.setType(data.type);
-    self.setCommonName(data.commonName);
-    self.setGroup(data.group);
-    self.setValue(data.value);
-    self.setValueType(data.valueType);
-  }
-}
-
-ConfigurationOption.prototype = Object.create(ObjectWithListeners.prototype);
-ConfigurationOption.prototype.constructor = ConfigurationOption;
-
-ConfigurationOption.prototype.setType = function (type) {
-  this._type = type;
-};
-
-ConfigurationOption.prototype.getType = function () {
-  return this._type;
-};
-
-ConfigurationOption.prototype.setValue = function (value) {
-  this._value = value;
-};
-
-ConfigurationOption.prototype.getValue = function () {
-  return this._value;
-};
-
-ConfigurationOption.prototype.setValueType = function (valueType) {
-  this._valueType = valueType;
-};
-
-ConfigurationOption.prototype.getValueType = function () {
-  return this._valueType;
-};
-
-ConfigurationOption.prototype.setCommonName = function (commonName) {
-  this._commonName = commonName;
-};
-
-ConfigurationOption.prototype.getCommonName = function () {
-  return this._commonName;
-};
-
-ConfigurationOption.prototype.setGroup = function (group) {
-  this._group = group;
-};
-
-ConfigurationOption.prototype.getGroup = function () {
-  return this._group;
-};
-
-
-module.exports = ConfigurationOption;
+"use strict";
+
+var ObjectWithListeners = require('./ObjectWithListeners');
+
+var logger = require('./logger');
+
+function ConfigurationOption(data) {
+  // call super constructor
+  ObjectWithListeners.call(this);
+
+  var self = this;
+  if (data instanceof ConfigurationOption) {
+    self.setType(data.getType());
+    self.setCommonName(data.getCommonName());
+    self.setValue(data.getValue());
+    self.setGroup(data.getGroup());
+    self.setValueType(data.getValueType());
+  } else {
+    self.setType(data.type);
+    self.setCommonName(data.commonName);
+    self.setGroup(data.group);
+    self.setValue(data.value);
+    self.setValueType(data.valueType);
+  }
+}
+
+ConfigurationOption.prototype = Object.create(ObjectWithListeners.prototype);
+ConfigurationOption.prototype.constructor = ConfigurationOption;
+
+ConfigurationOption.prototype.setType = function (type) {
+  this._type = type;
+};
+
+ConfigurationOption.prototype.getType = function () {
+  return this._type;
+};
+
+ConfigurationOption.prototype.setValue = function (value) {
+  this._value = value;
+};
+
+ConfigurationOption.prototype.getValue = function () {
+  return this._value;
+};
+
+ConfigurationOption.prototype.setValueType = function (valueType) {
+  this._valueType = valueType;
+};
+
+ConfigurationOption.prototype.getValueType = function () {
+  return this._valueType;
+};
+
+ConfigurationOption.prototype.setCommonName = function (commonName) {
+  this._commonName = commonName;
+};
+
+ConfigurationOption.prototype.getCommonName = function () {
+  return this._commonName;
+};
+
+ConfigurationOption.prototype.setGroup = function (group) {
+  this._group = group;
+};
+
+ConfigurationOption.prototype.getGroup = function () {
+  return this._group;
+};
+
+
+module.exports = ConfigurationOption;
diff --git a/frontend-js/src/main/js/ConfigurationType.js b/frontend-js/src/main/js/ConfigurationType.js
index 5ebf5f1e7d5148b7b7a0fd321f1a4ff3032fe41b..33e11d3ba6e4080eb7d18869a9c466ad7bc6030e 100644
--- a/frontend-js/src/main/js/ConfigurationType.js
+++ b/frontend-js/src/main/js/ConfigurationType.js
@@ -1,25 +1,25 @@
-"use strict";
-
-var ConfigurationType = {
-  DEFAULT_MAP: "DEFAULT_MAP",
-  GOOGLE_ANALYTICS_IDENTIFIER: "GOOGLE_ANALYTICS_IDENTIFIER",
-  GOOGLE_MAPS_API_KEY: "GOOGLE_MAPS_API_KEY",
-  LOGO_IMG: "LOGO_IMG",
-  LOGO_LINK: "LOGO_LINK",
-  LOGO_TEXT: "LOGO_TEXT",
-  LEGEND_FILES: "LEGEND_FILES",
-  MIN_COLOR_VAL: "MIN_COLOR_VAL",
-  MAX_COLOR_VAL: "MAX_COLOR_VAL",
-  NEUTRAL_COLOR_VAL: "NEUTRAL_COLOR_VAL",
-  OVERLAY_OPACITY: "OVERLAY_OPACITY",
-  REQUEST_ACCOUNT_EMAIL: "REQUEST_ACCOUNT_EMAIL",
-  REQUEST_ACCOUNT_DEFAULT_CONTENT: "REQUEST_ACCOUNT_DEFAULT_CONTENT",
-  SIMPLE_COLOR_VAL: "SIMPLE_COLOR_VAL",
-  SHOW_REACTION_TYPE: "SHOW_REACTION_TYPE",
-  SEARCH_DISTANCE: "SEARCH_DISTANCE",
-  SEARCH_RESULT_NUMBER: "SEARCH_RESULT_NUMBER",
-  TERMS_OF_USE: "TERMS_OF_USE",
-  USER_MANUAL_FILE: "USER_MANUAL_FILE"
-};
-
-module.exports = ConfigurationType;
+"use strict";
+
+var ConfigurationType = {
+  DEFAULT_MAP: "DEFAULT_MAP",
+  GOOGLE_ANALYTICS_IDENTIFIER: "GOOGLE_ANALYTICS_IDENTIFIER",
+  GOOGLE_MAPS_API_KEY: "GOOGLE_MAPS_API_KEY",
+  LOGO_IMG: "LOGO_IMG",
+  LOGO_LINK: "LOGO_LINK",
+  LOGO_TEXT: "LOGO_TEXT",
+  LEGEND_FILES: "LEGEND_FILES",
+  MIN_COLOR_VAL: "MIN_COLOR_VAL",
+  MAX_COLOR_VAL: "MAX_COLOR_VAL",
+  NEUTRAL_COLOR_VAL: "NEUTRAL_COLOR_VAL",
+  OVERLAY_OPACITY: "OVERLAY_OPACITY",
+  REQUEST_ACCOUNT_EMAIL: "REQUEST_ACCOUNT_EMAIL",
+  REQUEST_ACCOUNT_DEFAULT_CONTENT: "REQUEST_ACCOUNT_DEFAULT_CONTENT",
+  SIMPLE_COLOR_VAL: "SIMPLE_COLOR_VAL",
+  SHOW_REACTION_TYPE: "SHOW_REACTION_TYPE",
+  SEARCH_DISTANCE: "SEARCH_DISTANCE",
+  SEARCH_RESULT_NUMBER: "SEARCH_RESULT_NUMBER",
+  TERMS_OF_USE: "TERMS_OF_USE",
+  USER_MANUAL_FILE: "USER_MANUAL_FILE"
+};
+
+module.exports = ConfigurationType;
diff --git a/frontend-js/src/main/js/Export.js b/frontend-js/src/main/js/Export.js
index ee603b203e1665952909c620dd890a61ed4d6bd4..1c15300edfe892e8aa5db2ea2a45a822aecc45a9 100644
--- a/frontend-js/src/main/js/Export.js
+++ b/frontend-js/src/main/js/Export.js
@@ -1,168 +1,168 @@
-"use strict";
-
-/* exported logger */
-
-var Promise = require("bluebird");
-
-var CustomMapOptions = require('./map/CustomMapOptions');
-var ElementExportPanel = require('./gui/export/ElementExportPanel');
-var GraphicsExportPanel = require('./gui/export/GraphicsExportPanel');
-var NetworkExportPanel = require('./gui/export/NetworkExportPanel');
-var Header = require('./gui/Header');
-var ObjectWithListeners = require('./ObjectWithListeners');
-
-var logger = require('./logger');
-var Functions = require('./Functions');
-
-/**
- * Default constructor.
- * 
- * @param options
- *          CustomMapOptions object representing all parameters needed for map
- *          creation
- */
-function Export(options) {
-  var self = this;
-  self._panels = [];
-  self._tabIdCount = 0;
-  if (!(options instanceof CustomMapOptions)) {
-    options = new CustomMapOptions(options);
-  }
-  self.setProject(options.getProject());
-  self.setElement(options.getElement());
-
-  self.setConfiguration(options.getConfiguration());
-  self._createGui();
-}
-
-Export.prototype = Object.create(ObjectWithListeners.prototype);
-Export.prototype.constructor = ObjectWithListeners;
-
-Export.prototype._createGui = function() {
-  var self = this;
-  self.getElement().innerHTML = "";
-  var headerDiv = Functions.createElement({
-    type : "div"
-  });
-  new Header({
-    element : headerDiv,
-    customMap : null,
-    project : self.getProject()
-  });
-  self.getElement().appendChild(headerDiv);
-
-  var panels = [ {
-    name : "ELEMENTS",
-    panelClass : ElementExportPanel
-  }, {
-    name : "NETWORK",
-    panelClass : NetworkExportPanel
-  }, {
-    name : "GRAPHICS",
-    panelClass : GraphicsExportPanel
-  } ];
-
-  var tabDiv = Functions.createElement({
-    type : "div",
-    name : "tabView",
-    className : "tabbable boxed parentTabs"
-  });
-  self.getElement().appendChild(tabDiv);
-
-  var tabMenuDiv = Functions.createElement({
-    type : "ul",
-    className : "nav nav-tabs"
-  });
-  tabDiv.appendChild(tabMenuDiv);
-
-  var tabContentDiv = Functions.createElement({
-    type : "div",
-    className : "tab-content"
-  });
-  tabDiv.appendChild(tabContentDiv);
-
-  for (var i = 0; i < panels.length; i++) {
-    self.addTab(panels[i], tabMenuDiv, tabContentDiv);
-  }
-};
-
-Export.prototype.addTab = function(params, navElement, contentElement) {
-  var self = this;
-
-  var name = params.name;
-
-  var tabId = "export_panel_tab_" + this._tabIdCount;
-  self._tabIdCount++;
-
-  var navClass = '';
-  var contentClass = 'tab-pane';
-  if (navElement.children.length === 0) {
-    navClass = "active";
-    contentClass = "tab-pane active";
-  }
-
-  var navLi = document.createElement("li");
-  navLi.className = navClass;
-
-  var navLink = document.createElement("a");
-  navLink.href = "#" + tabId;
-  if (name !== undefined) {
-    if (name.length > 12) {
-      name = name.substring(0, 10) + "...";
-    }
-    navLink.innerHTML = name;
-  }
-  navLink.onclick = function() {
-    $(this).tab('show');
-  };
-  navLi.appendChild(navLink);
-  if (name !== undefined) {
-    navLink.innerHTML = name;
-  }
-  navElement.appendChild(navLi);
-
-  var contentDiv = document.createElement("div");
-  contentDiv.style.height = "100%";
-  contentDiv.className = contentClass;
-  contentDiv.id = tabId;
-
-  contentElement.appendChild(contentDiv);
-
-  this._panels.push(new params.panelClass({
-    element : contentDiv,
-    project : self.getProject(),
-    configuration : self.getConfiguration()
-  }));
-};
-
-Export.prototype.setProject = function(project) {
-  this._project = project;
-};
-Export.prototype.getProject = function() {
-  return this._project;
-};
-
-Export.prototype.setElement = function(element) {
-  this._element = element;
-};
-Export.prototype.getElement = function() {
-  return this._element;
-};
-
-Export.prototype.init = function() {
-  var promises = [];
-  for (var i = 0; i < this._panels.length; i++) {
-    promises.push(this._panels[i].init());
-  }
-  return Promise.all(promises);
-};
-
-Export.prototype.setConfiguration = function(configuration) {
-  this._configuration = configuration;
-};
-
-Export.prototype.getConfiguration = function() {
-  return this._configuration;
-};
-
-module.exports = Export;
+"use strict";
+
+/* exported logger */
+
+var Promise = require("bluebird");
+
+var CustomMapOptions = require('./map/CustomMapOptions');
+var ElementExportPanel = require('./gui/export/ElementExportPanel');
+var GraphicsExportPanel = require('./gui/export/GraphicsExportPanel');
+var NetworkExportPanel = require('./gui/export/NetworkExportPanel');
+var Header = require('./gui/Header');
+var ObjectWithListeners = require('./ObjectWithListeners');
+
+var logger = require('./logger');
+var Functions = require('./Functions');
+
+/**
+ * Default constructor.
+ * 
+ * @param options
+ *          CustomMapOptions object representing all parameters needed for map
+ *          creation
+ */
+function Export(options) {
+  var self = this;
+  self._panels = [];
+  self._tabIdCount = 0;
+  if (!(options instanceof CustomMapOptions)) {
+    options = new CustomMapOptions(options);
+  }
+  self.setProject(options.getProject());
+  self.setElement(options.getElement());
+
+  self.setConfiguration(options.getConfiguration());
+  self._createGui();
+}
+
+Export.prototype = Object.create(ObjectWithListeners.prototype);
+Export.prototype.constructor = ObjectWithListeners;
+
+Export.prototype._createGui = function() {
+  var self = this;
+  self.getElement().innerHTML = "";
+  var headerDiv = Functions.createElement({
+    type : "div"
+  });
+  new Header({
+    element : headerDiv,
+    customMap : null,
+    project : self.getProject()
+  });
+  self.getElement().appendChild(headerDiv);
+
+  var panels = [ {
+    name : "ELEMENTS",
+    panelClass : ElementExportPanel
+  }, {
+    name : "NETWORK",
+    panelClass : NetworkExportPanel
+  }, {
+    name : "GRAPHICS",
+    panelClass : GraphicsExportPanel
+  } ];
+
+  var tabDiv = Functions.createElement({
+    type : "div",
+    name : "tabView",
+    className : "tabbable boxed parentTabs"
+  });
+  self.getElement().appendChild(tabDiv);
+
+  var tabMenuDiv = Functions.createElement({
+    type : "ul",
+    className : "nav nav-tabs"
+  });
+  tabDiv.appendChild(tabMenuDiv);
+
+  var tabContentDiv = Functions.createElement({
+    type : "div",
+    className : "tab-content"
+  });
+  tabDiv.appendChild(tabContentDiv);
+
+  for (var i = 0; i < panels.length; i++) {
+    self.addTab(panels[i], tabMenuDiv, tabContentDiv);
+  }
+};
+
+Export.prototype.addTab = function(params, navElement, contentElement) {
+  var self = this;
+
+  var name = params.name;
+
+  var tabId = "export_panel_tab_" + this._tabIdCount;
+  self._tabIdCount++;
+
+  var navClass = '';
+  var contentClass = 'tab-pane';
+  if (navElement.children.length === 0) {
+    navClass = "active";
+    contentClass = "tab-pane active";
+  }
+
+  var navLi = document.createElement("li");
+  navLi.className = navClass;
+
+  var navLink = document.createElement("a");
+  navLink.href = "#" + tabId;
+  if (name !== undefined) {
+    if (name.length > 12) {
+      name = name.substring(0, 10) + "...";
+    }
+    navLink.innerHTML = name;
+  }
+  navLink.onclick = function() {
+    $(this).tab('show');
+  };
+  navLi.appendChild(navLink);
+  if (name !== undefined) {
+    navLink.innerHTML = name;
+  }
+  navElement.appendChild(navLi);
+
+  var contentDiv = document.createElement("div");
+  contentDiv.style.height = "100%";
+  contentDiv.className = contentClass;
+  contentDiv.id = tabId;
+
+  contentElement.appendChild(contentDiv);
+
+  this._panels.push(new params.panelClass({
+    element : contentDiv,
+    project : self.getProject(),
+    configuration : self.getConfiguration()
+  }));
+};
+
+Export.prototype.setProject = function(project) {
+  this._project = project;
+};
+Export.prototype.getProject = function() {
+  return this._project;
+};
+
+Export.prototype.setElement = function(element) {
+  this._element = element;
+};
+Export.prototype.getElement = function() {
+  return this._element;
+};
+
+Export.prototype.init = function() {
+  var promises = [];
+  for (var i = 0; i < this._panels.length; i++) {
+    promises.push(this._panels[i].init());
+  }
+  return Promise.all(promises);
+};
+
+Export.prototype.setConfiguration = function(configuration) {
+  this._configuration = configuration;
+};
+
+Export.prototype.getConfiguration = function() {
+  return this._configuration;
+};
+
+module.exports = Export;
diff --git a/frontend-js/src/main/js/GuiConnector.js b/frontend-js/src/main/js/GuiConnector.js
index c5e6d90f515b9e5d14bd9b0fce0f2772c4deefd6..137259eee36ccedff2b6025f7d0de55877a02873 100644
--- a/frontend-js/src/main/js/GuiConnector.js
+++ b/frontend-js/src/main/js/GuiConnector.js
@@ -1,340 +1,340 @@
-"use strict";
-
-var Promise = require("bluebird");
-
-var logger = require('./logger');
-
-var Functions = require('./Functions');
-var SecurityError = require('./SecurityError');
-var ValidationError = require('./ValidationError');
-var GuiMessageError = require('./gui/GuiMessageError');
-var NetworkError = require('./NetworkError');
-
-/**
- * This static global object contains set of functions that returns/set data in
- * the Gui (html).
- */
-function GuiConnector() {
-  // X coordinate of the mouse in a browser.
-  //@type {number}
-  this.xPos = 0;
-  // coordinate of the mouse in a browser.
-  //@type {number}
-  this.yPos = 0;
-
-  this.getParams = [];
-}
-
-function returnThisOrSingleton(object) {
-  if (object === undefined || object === null) {
-    return GuiConnector.singleton;
-  } else {
-    return object;
-  }
-}
-
-/**
- * List of GET params passed via url.
- */
-
-GuiConnector.prototype.init = function () {
-  var self = returnThisOrSingleton(this);
-
-  if (!String.prototype.endsWith) {
-    String.prototype.endsWith = function (pattern) {
-      var d = this.length - pattern.length;
-      return d >= 0 && this.lastIndexOf(pattern) === d;
-    };
-  }
-  var isIE = /* @cc_on!@ */false || !!document.documentMode;
-
-  if (isIE) {
-    alert("This web page works well with Chrome, Firefox and Safari.");
-  }
-  // bootstrap tab initialization
-  $("ul.nav-tabs a").click(function (e) {
-    e.preventDefault();
-    $(this).tab('show');
-  });
-
-  self.getParams = [];
-
-  // find GuiConnector.getParams
-  window.location.search.replace(/\??(?:([^=]+)=([^&]*)&?)/g, function () {
-    function decode(s) {
-      return decodeURIComponent(s.split("+").join(" "));
-    }
-
-    self.getParams[decode(arguments[1])] = decode(arguments[2]);
-  });
-
-  self._touchStartEvent = function (e) {
-    if (e.originalEvent !== undefined) {
-      self.updateMouseCoordinates(e.originalEvent.touches[0].pageX, e.originalEvent.touches[0].pageY);
-    }
-  };
-  self._touchMoveEvent = function (e) {
-    if (e.originalEvent !== undefined) {
-      self.updateMouseCoordinates(e.originalEvent.touches[0].pageX, e.originalEvent.touches[0].pageY);
-    }
-  };
-
-  // force browser to update mouse coordinates whenever mouse move
-  jQuery(document).ready(function () {
-    $(document).mousemove(function (e) {
-      self.updateMouseCoordinates(e.pageX, e.pageY);
-    });
-    $(document).on('touchstart', self._touchStartEvent);
-    $(document).on('touchmove', self._touchMoveEvent);
-  });
-
-  if (self._windowResizeEvents === undefined) {
-    self._windowResizeEvents = [];
-
-    if (window.onresize !== null && window.onresize !== undefined) {
-      self.addWindowResizeEvent(window.onresize);
-    }
-
-    window.onresize = function () {
-      for (var i = 0; i < self._windowResizeEvents.length; i++) {
-        self._windowResizeEvents[i]();
-      }
-    };
-  }
-};
-
-GuiConnector.prototype.addWindowResizeEvent = function (handler) {
-  this._windowResizeEvents.push(handler);
-};
-
-GuiConnector.prototype.removeWindowResizeEvent = function (handler) {
-  var events = this._windowResizeEvents;
-  var index = events.indexOf(handler);
-  if (index > -1) {
-    events.splice(index, 1);
-  } else {
-    logger.warn("Cannot find listener", handler);
-  }
-};
-
-/**
- * Returns name of the file with LCSB logo.
- *
- * @param bigLogo
- *          {@link Boolean} value determining if we want to have big logo or
- *          small one
- */
-GuiConnector.prototype.getLcsbLogoImg = function (bigLogo) {
-  if (bigLogo) {
-    return 'lcsb_logo_mid.png';
-  } else {
-    return 'lcsb_logo.png';
-  }
-};
-
-/**
- * Returns name of the file with image that should be presented when we are
- * waiting for data to be loaded.
- */
-GuiConnector.prototype.getLoadingImg = function () {
-  return "icons/ajax-loader.gif";
-};
-
-
-GuiConnector.prototype.getEmptyTileUrl = function () {
-  return "resources/images/empty_tile.png";
-};
-
-/**
- * Returns home directory for images in the application.
- */
-GuiConnector.prototype.getImgPrefix = function () {
-  return "resources/images/";
-};
-
-/**
- * Updates coordinates of the mouse in the browser.
- */
-GuiConnector.prototype.updateMouseCoordinates = function (x, y) {
-  var self = returnThisOrSingleton(this);
-  self.xPos = x;
-  self.yPos = y;
-};
-
-GuiConnector.prototype.showProcessing = function (messageText) {
-  var self = returnThisOrSingleton(this);
-  if (self._processingDialog === undefined) {
-    self._processingDialog = document.createElement("div");
-    self._processingDialogContent = document.createElement("div");
-    self._processingDialog.appendChild(self._processingDialogContent);
-    document.body.appendChild(self._processingDialog);
-    $(self._processingDialog).dialog({
-      modal: true,
-      title: "PROCESSING",
-      width: "150px",
-      closeOnEscape: false,
-      dialogClass: 'minerva-no-close'
-    });
-  }
-  if (messageText === undefined) {
-    messageText = "PROCESSING";
-  }
-  var messageImg = Functions.createElement({
-    type: "img",
-    src: 'resources/images/icons/ajax-loader.gif'
-  });
-  self._processingDialogContent.innerHTML = "";
-  self._processingDialogContent.style.textAlign = "center";
-  self._processingDialogContent.appendChild(messageImg);
-
-  $(self._processingDialog).dialog("option", "title", messageText);
-
-  $(self._processingDialog).dialog("open");
-};
-
-GuiConnector.prototype.hideProcessing = function () {
-  var self = returnThisOrSingleton(this);
-  $(self._processingDialog).dialog("close");
-};
-
-GuiConnector.prototype.alert = function (error, redirectIfSecurityError) {
-  if (redirectIfSecurityError === undefined) {
-    redirectIfSecurityError = false;
-  }
-  if (redirectIfSecurityError && error instanceof SecurityError && ServerConnector.getSessionData().getLogin() === "anonymous") {
-    window.location.href = ServerConnector.getServerBaseUrl() + "login.xhtml?from=" + encodeURI(window.location.href);
-  } else {
-    var self = returnThisOrSingleton(this);
-    logger.error(error);
-    if (self._errorDialog === undefined) {
-      self._errorDialog = document.createElement("div");
-      self._errorDialogContent = document.createElement("div");
-      self._errorDialog.appendChild(self._errorDialogContent);
-      document.body.appendChild(self._errorDialog);
-      $(self._errorDialog).dialog({
-        classes: {
-          "ui-dialog": "ui-state-error"
-        },
-        modal: true,
-        title: "ERROR"
-      }).siblings('.ui-dialog-titlebar').css("background", "red");
-    }
-    self._errorDialogContent.innerHTML = self.getErrorMessageForError(error);
-    $(self._errorDialog).dialog("open");
-  }
-};
-
-GuiConnector.prototype.getErrorMessageForError = function (error) {
-  var message = error;
-  if (message instanceof SecurityError) {
-    if (ServerConnector.getSessionData().getLogin() === "anonymous") {
-      message = error.message + "<p>Please <a href=\"login.xhtml?from=" + encodeURI(window.location.href) + "\">login</a> to access this resource</p>";
-    } else {
-      message = error.message + "<p>Please <a href=\"login.xhtml?from=" + encodeURI(window.location.href) + "\">login</a> " +
-        "as a different user or ask your administrator to change the permissions to access this resource.</p>";
-    }
-  } else if (message instanceof ValidationError) {
-    message = error.message;
-  } else if (message instanceof GuiMessageError) {
-    message = error.message;
-  } else if (message instanceof Error) {
-    message = "Unexpected error occurred:<p>" + error.message + "</p>";
-  }
-  return message;
-};
-
-GuiConnector.prototype.info = function (message) {
-  var self = returnThisOrSingleton(this);
-  if (self._infoDialog === undefined) {
-    self._infoDialog = document.createElement("div");
-    self._infoDialogContent = document.createElement("div");
-    self._infoDialog.appendChild(self._infoDialogContent);
-    document.body.appendChild(self._infoDialog);
-    $(self._infoDialog).dialog({
-      classes: {
-        "ui-dialog": "ui-state-info"
-      },
-      modal: true,
-      title: "INFO"
-    });
-  }
-  self._infoDialogContent.innerHTML = message;
-  $(self._infoDialog).dialog("open");
-
-};
-
-GuiConnector.prototype.showConfirmationDialog = function (params) {
-  var message = params.message;
-  var title = params.title;
-  if (title === undefined) {
-    title = "Confirm";
-  }
-  return new Promise(function (resolve) {
-    $('<div></div>').appendTo('body')
-      .html('<div><h6>' + message + '</h6></div>')
-      .dialog({
-        modal: true, title: title, zIndex: 10000, autoOpen: true,
-        width: 'auto', resizable: false,
-        buttons: {
-          Yes: function () {
-            $(this).dialog("close");
-            resolve(true);
-          },
-          No: function () {
-            $(this).dialog("close");
-            resolve(false);
-          }
-        },
-        close: function (event, ui) {
-          $(this).remove();
-        }
-      });
-  });
-};
-
-GuiConnector.prototype.destroy = function () {
-  var self = returnThisOrSingleton(this);
-
-  if (self._infoDialog !== undefined) {
-    $(self._infoDialog).dialog("destroy").remove();
-  }
-  if (self._warnDialog !== undefined) {
-    $(self._warnDialog).dialog("destroy").remove();
-  }
-  if (self._processingDialog !== undefined) {
-    $(self._processingDialog).dialog("destroy").remove();
-  }
-
-  if (self._errorDialog !== undefined) {
-    $(self._errorDialog).dialog("destroy").remove();
-  }
-
-  self._windowResizeEvents = undefined;
-  $(document).off('touchstart', self._touchStartEvent);
-  $(document).off('touchmove', self._touchMoveEvent);
-
-};
-
-GuiConnector.prototype.warn = function (message) {
-  var self = GuiConnector;
-  logger.warn(message);
-  if (self._warnDialog === undefined) {
-    self._warnDialog = document.createElement("div");
-    self._warnDialogContent = document.createElement("div");
-    self._warnDialog.appendChild(self._warnDialogContent);
-    document.body.appendChild(self._warnDialog);
-    $(self._warnDialog).dialog({
-      classes: {
-        "ui-dialog": "ui-state-highlight"
-      },
-      modal: true,
-      title: "WARNING"
-    });
-  }
-  self._warnDialogContent.innerHTML = message;
-  $(self._warnDialog).dialog("open");
-};
-
-GuiConnector.singleton = new GuiConnector();
-
-module.exports = GuiConnector.singleton;
+"use strict";
+
+var Promise = require("bluebird");
+
+var logger = require('./logger');
+
+var Functions = require('./Functions');
+var SecurityError = require('./SecurityError');
+var ValidationError = require('./ValidationError');
+var GuiMessageError = require('./gui/GuiMessageError');
+var NetworkError = require('./NetworkError');
+
+/**
+ * This static global object contains set of functions that returns/set data in
+ * the Gui (html).
+ */
+function GuiConnector() {
+  // X coordinate of the mouse in a browser.
+  //@type {number}
+  this.xPos = 0;
+  // coordinate of the mouse in a browser.
+  //@type {number}
+  this.yPos = 0;
+
+  this.getParams = [];
+}
+
+function returnThisOrSingleton(object) {
+  if (object === undefined || object === null) {
+    return GuiConnector.singleton;
+  } else {
+    return object;
+  }
+}
+
+/**
+ * List of GET params passed via url.
+ */
+
+GuiConnector.prototype.init = function () {
+  var self = returnThisOrSingleton(this);
+
+  if (!String.prototype.endsWith) {
+    String.prototype.endsWith = function (pattern) {
+      var d = this.length - pattern.length;
+      return d >= 0 && this.lastIndexOf(pattern) === d;
+    };
+  }
+  var isIE = /* @cc_on!@ */false || !!document.documentMode;
+
+  if (isIE) {
+    alert("This web page works well with Chrome, Firefox and Safari.");
+  }
+  // bootstrap tab initialization
+  $("ul.nav-tabs a").click(function (e) {
+    e.preventDefault();
+    $(this).tab('show');
+  });
+
+  self.getParams = [];
+
+  // find GuiConnector.getParams
+  window.location.search.replace(/\??(?:([^=]+)=([^&]*)&?)/g, function () {
+    function decode(s) {
+      return decodeURIComponent(s.split("+").join(" "));
+    }
+
+    self.getParams[decode(arguments[1])] = decode(arguments[2]);
+  });
+
+  self._touchStartEvent = function (e) {
+    if (e.originalEvent !== undefined) {
+      self.updateMouseCoordinates(e.originalEvent.touches[0].pageX, e.originalEvent.touches[0].pageY);
+    }
+  };
+  self._touchMoveEvent = function (e) {
+    if (e.originalEvent !== undefined) {
+      self.updateMouseCoordinates(e.originalEvent.touches[0].pageX, e.originalEvent.touches[0].pageY);
+    }
+  };
+
+  // force browser to update mouse coordinates whenever mouse move
+  jQuery(document).ready(function () {
+    $(document).mousemove(function (e) {
+      self.updateMouseCoordinates(e.pageX, e.pageY);
+    });
+    $(document).on('touchstart', self._touchStartEvent);
+    $(document).on('touchmove', self._touchMoveEvent);
+  });
+
+  if (self._windowResizeEvents === undefined) {
+    self._windowResizeEvents = [];
+
+    if (window.onresize !== null && window.onresize !== undefined) {
+      self.addWindowResizeEvent(window.onresize);
+    }
+
+    window.onresize = function () {
+      for (var i = 0; i < self._windowResizeEvents.length; i++) {
+        self._windowResizeEvents[i]();
+      }
+    };
+  }
+};
+
+GuiConnector.prototype.addWindowResizeEvent = function (handler) {
+  this._windowResizeEvents.push(handler);
+};
+
+GuiConnector.prototype.removeWindowResizeEvent = function (handler) {
+  var events = this._windowResizeEvents;
+  var index = events.indexOf(handler);
+  if (index > -1) {
+    events.splice(index, 1);
+  } else {
+    logger.warn("Cannot find listener", handler);
+  }
+};
+
+/**
+ * Returns name of the file with LCSB logo.
+ *
+ * @param bigLogo
+ *          {@link Boolean} value determining if we want to have big logo or
+ *          small one
+ */
+GuiConnector.prototype.getLcsbLogoImg = function (bigLogo) {
+  if (bigLogo) {
+    return 'lcsb_logo_mid.png';
+  } else {
+    return 'lcsb_logo.png';
+  }
+};
+
+/**
+ * Returns name of the file with image that should be presented when we are
+ * waiting for data to be loaded.
+ */
+GuiConnector.prototype.getLoadingImg = function () {
+  return "icons/ajax-loader.gif";
+};
+
+
+GuiConnector.prototype.getEmptyTileUrl = function () {
+  return "resources/images/empty_tile.png";
+};
+
+/**
+ * Returns home directory for images in the application.
+ */
+GuiConnector.prototype.getImgPrefix = function () {
+  return "resources/images/";
+};
+
+/**
+ * Updates coordinates of the mouse in the browser.
+ */
+GuiConnector.prototype.updateMouseCoordinates = function (x, y) {
+  var self = returnThisOrSingleton(this);
+  self.xPos = x;
+  self.yPos = y;
+};
+
+GuiConnector.prototype.showProcessing = function (messageText) {
+  var self = returnThisOrSingleton(this);
+  if (self._processingDialog === undefined) {
+    self._processingDialog = document.createElement("div");
+    self._processingDialogContent = document.createElement("div");
+    self._processingDialog.appendChild(self._processingDialogContent);
+    document.body.appendChild(self._processingDialog);
+    $(self._processingDialog).dialog({
+      modal: true,
+      title: "PROCESSING",
+      width: "150px",
+      closeOnEscape: false,
+      dialogClass: 'minerva-no-close'
+    });
+  }
+  if (messageText === undefined) {
+    messageText = "PROCESSING";
+  }
+  var messageImg = Functions.createElement({
+    type: "img",
+    src: 'resources/images/icons/ajax-loader.gif'
+  });
+  self._processingDialogContent.innerHTML = "";
+  self._processingDialogContent.style.textAlign = "center";
+  self._processingDialogContent.appendChild(messageImg);
+
+  $(self._processingDialog).dialog("option", "title", messageText);
+
+  $(self._processingDialog).dialog("open");
+};
+
+GuiConnector.prototype.hideProcessing = function () {
+  var self = returnThisOrSingleton(this);
+  $(self._processingDialog).dialog("close");
+};
+
+GuiConnector.prototype.alert = function (error, redirectIfSecurityError) {
+  if (redirectIfSecurityError === undefined) {
+    redirectIfSecurityError = false;
+  }
+  if (redirectIfSecurityError && error instanceof SecurityError && ServerConnector.getSessionData().getLogin() === "anonymous") {
+    window.location.href = ServerConnector.getServerBaseUrl() + "login.xhtml?from=" + encodeURI(window.location.href);
+  } else {
+    var self = returnThisOrSingleton(this);
+    logger.error(error);
+    if (self._errorDialog === undefined) {
+      self._errorDialog = document.createElement("div");
+      self._errorDialogContent = document.createElement("div");
+      self._errorDialog.appendChild(self._errorDialogContent);
+      document.body.appendChild(self._errorDialog);
+      $(self._errorDialog).dialog({
+        classes: {
+          "ui-dialog": "ui-state-error"
+        },
+        modal: true,
+        title: "ERROR"
+      }).siblings('.ui-dialog-titlebar').css("background", "red");
+    }
+    self._errorDialogContent.innerHTML = self.getErrorMessageForError(error);
+    $(self._errorDialog).dialog("open");
+  }
+};
+
+GuiConnector.prototype.getErrorMessageForError = function (error) {
+  var message = error;
+  if (message instanceof SecurityError) {
+    if (ServerConnector.getSessionData().getLogin() === "anonymous") {
+      message = error.message + "<p>Please <a href=\"login.xhtml?from=" + encodeURI(window.location.href) + "\">login</a> to access this resource</p>";
+    } else {
+      message = error.message + "<p>Please <a href=\"login.xhtml?from=" + encodeURI(window.location.href) + "\">login</a> " +
+        "as a different user or ask your administrator to change the permissions to access this resource.</p>";
+    }
+  } else if (message instanceof ValidationError) {
+    message = error.message;
+  } else if (message instanceof GuiMessageError) {
+    message = error.message;
+  } else if (message instanceof Error) {
+    message = "Unexpected error occurred:<p>" + error.message + "</p>";
+  }
+  return message;
+};
+
+GuiConnector.prototype.info = function (message) {
+  var self = returnThisOrSingleton(this);
+  if (self._infoDialog === undefined) {
+    self._infoDialog = document.createElement("div");
+    self._infoDialogContent = document.createElement("div");
+    self._infoDialog.appendChild(self._infoDialogContent);
+    document.body.appendChild(self._infoDialog);
+    $(self._infoDialog).dialog({
+      classes: {
+        "ui-dialog": "ui-state-info"
+      },
+      modal: true,
+      title: "INFO"
+    });
+  }
+  self._infoDialogContent.innerHTML = message;
+  $(self._infoDialog).dialog("open");
+
+};
+
+GuiConnector.prototype.showConfirmationDialog = function (params) {
+  var message = params.message;
+  var title = params.title;
+  if (title === undefined) {
+    title = "Confirm";
+  }
+  return new Promise(function (resolve) {
+    $('<div></div>').appendTo('body')
+      .html('<div><h6>' + message + '</h6></div>')
+      .dialog({
+        modal: true, title: title, zIndex: 10000, autoOpen: true,
+        width: 'auto', resizable: false,
+        buttons: {
+          Yes: function () {
+            $(this).dialog("close");
+            resolve(true);
+          },
+          No: function () {
+            $(this).dialog("close");
+            resolve(false);
+          }
+        },
+        close: function (event, ui) {
+          $(this).remove();
+        }
+      });
+  });
+};
+
+GuiConnector.prototype.destroy = function () {
+  var self = returnThisOrSingleton(this);
+
+  if (self._infoDialog !== undefined) {
+    $(self._infoDialog).dialog("destroy").remove();
+  }
+  if (self._warnDialog !== undefined) {
+    $(self._warnDialog).dialog("destroy").remove();
+  }
+  if (self._processingDialog !== undefined) {
+    $(self._processingDialog).dialog("destroy").remove();
+  }
+
+  if (self._errorDialog !== undefined) {
+    $(self._errorDialog).dialog("destroy").remove();
+  }
+
+  self._windowResizeEvents = undefined;
+  $(document).off('touchstart', self._touchStartEvent);
+  $(document).off('touchmove', self._touchMoveEvent);
+
+};
+
+GuiConnector.prototype.warn = function (message) {
+  var self = GuiConnector;
+  logger.warn(message);
+  if (self._warnDialog === undefined) {
+    self._warnDialog = document.createElement("div");
+    self._warnDialogContent = document.createElement("div");
+    self._warnDialog.appendChild(self._warnDialogContent);
+    document.body.appendChild(self._warnDialog);
+    $(self._warnDialog).dialog({
+      classes: {
+        "ui-dialog": "ui-state-highlight"
+      },
+      modal: true,
+      title: "WARNING"
+    });
+  }
+  self._warnDialogContent.innerHTML = message;
+  $(self._warnDialog).dialog("open");
+};
+
+GuiConnector.singleton = new GuiConnector();
+
+module.exports = GuiConnector.singleton;
diff --git a/frontend-js/src/main/js/InvalidArgumentError.js b/frontend-js/src/main/js/InvalidArgumentError.js
index 2e8fb4c330b614e4710c8022dd2c5867d8be7281..b0166479773294956cd6f3db57b3c202029f4a12 100644
--- a/frontend-js/src/main/js/InvalidArgumentError.js
+++ b/frontend-js/src/main/js/InvalidArgumentError.js
@@ -1,15 +1,15 @@
-"use strict";
-
-/* exported logger */
-
-var logger = require('./logger');
-
-function InvalidArgumentError(message) {
-  this.message = message;
-  this.stack = (new Error()).stack;
-}
-
-InvalidArgumentError.prototype = Object.create(Error.prototype);
-InvalidArgumentError.prototype.constructor = InvalidArgumentError;
-
-module.exports = InvalidArgumentError;
+"use strict";
+
+/* exported logger */
+
+var logger = require('./logger');
+
+function InvalidArgumentError(message) {
+  this.message = message;
+  this.stack = (new Error()).stack;
+}
+
+InvalidArgumentError.prototype = Object.create(Error.prototype);
+InvalidArgumentError.prototype.constructor = InvalidArgumentError;
+
+module.exports = InvalidArgumentError;
diff --git a/frontend-js/src/main/js/InvalidCredentialsError.js b/frontend-js/src/main/js/InvalidCredentialsError.js
index 1cd1e91ec86db950b28e09de87606d397bfe62f5..7e5f85ce4ff2dfb4e206e6b1fe2e41dd2e543620 100644
--- a/frontend-js/src/main/js/InvalidCredentialsError.js
+++ b/frontend-js/src/main/js/InvalidCredentialsError.js
@@ -1,17 +1,17 @@
-"use strict";
-
-/* exported logger */
-
-var logger = require('./logger');
-
-var SecurityError = require("./SecurityError");
-
-function InvalidCredentialsError(message) {
-  this.message = message;
-  this.stack = (new Error()).stack;
-}
-
-InvalidCredentialsError.prototype = Object.create(SecurityError.prototype);
-InvalidCredentialsError.prototype.constructor = InvalidCredentialsError;
-
-module.exports = InvalidCredentialsError;
+"use strict";
+
+/* exported logger */
+
+var logger = require('./logger');
+
+var SecurityError = require("./SecurityError");
+
+function InvalidCredentialsError(message) {
+  this.message = message;
+  this.stack = (new Error()).stack;
+}
+
+InvalidCredentialsError.prototype = Object.create(SecurityError.prototype);
+InvalidCredentialsError.prototype.constructor = InvalidCredentialsError;
+
+module.exports = InvalidCredentialsError;
diff --git a/frontend-js/src/main/js/NetworkError.js b/frontend-js/src/main/js/NetworkError.js
index 109b0ff5e62cf286e464960b45957e0240b41032..0b693ae0ba40dd17cfbf9e223c329caaa93cc907 100644
--- a/frontend-js/src/main/js/NetworkError.js
+++ b/frontend-js/src/main/js/NetworkError.js
@@ -1,25 +1,25 @@
-"use strict";
-
-/* exported logger */
-
-// noinspection JSUnusedLocalSymbols
-var logger = require('./logger');
-
-function NetworkError(message, connectionParams) {
-  this.message = message;
-  this.stack = (new Error()).stack;
-  if (connectionParams === undefined || connectionParams === null) {
-    connectionParams = {};
-  }
-  this.statusCode = connectionParams.statusCode;
-  this.url = connectionParams.url;
-  this.content = connectionParams.content;
-  if (this.content === undefined) {
-    this.content = "";
-  }
-}
-
-NetworkError.prototype = Object.create(Error.prototype);
-NetworkError.prototype.constructor = NetworkError;
-
-module.exports = NetworkError;
+"use strict";
+
+/* exported logger */
+
+// noinspection JSUnusedLocalSymbols
+var logger = require('./logger');
+
+function NetworkError(message, connectionParams) {
+  this.message = message;
+  this.stack = (new Error()).stack;
+  if (connectionParams === undefined || connectionParams === null) {
+    connectionParams = {};
+  }
+  this.statusCode = connectionParams.statusCode;
+  this.url = connectionParams.url;
+  this.content = connectionParams.content;
+  if (this.content === undefined) {
+    this.content = "";
+  }
+}
+
+NetworkError.prototype = Object.create(Error.prototype);
+NetworkError.prototype.constructor = NetworkError;
+
+module.exports = NetworkError;
diff --git a/frontend-js/src/main/js/ObjectWithListeners.js b/frontend-js/src/main/js/ObjectWithListeners.js
index 633390bd4eff7dae5921512606b660f10e4d9083..c930048dd6690ce6f9741d1e1c6eb50f5ea029ba 100644
--- a/frontend-js/src/main/js/ObjectWithListeners.js
+++ b/frontend-js/src/main/js/ObjectWithListeners.js
@@ -1,211 +1,211 @@
-"use strict";
-
-var Promise = require("bluebird");
-
-var logger = require('./logger');
-
-/**
- * An abstract class that allows to register listeners and call them in case of
- * events.
- * @constructor
- */
-function ObjectWithListeners() {
-  this._validListeners = [];
-  this._validPropertyListeners = [];
-}
-
-/**
- * @callback ListenerCallback
- * @param event
- */
-/**
- * Adds a listener function to the object.
- *
- * @param {string} type
- *          string defining type of the listener
- * @param {ListenerCallback} fun
- *          function that should be thrown when type event occurs
- */
-ObjectWithListeners.prototype.addListener = function (type, fun) {
-  if (this._validListeners[type] === undefined) {
-    throw new Error("Unknown listener type: " + type);
-  }
-
-  if (typeof fun !== "function") {
-    throw new Error("Second parameter must be a function but \"" + typeof (fun) + "\" found.");
-  }
-
-  this._validListeners[type].push(fun);
-};
-
-/**
- * Adds a property change listener function to the object.
- *
- * @param {string} name
- *          string defining property name
- * @param {function} fun
- *          function that should be thrown when firePropertyChangeListener is
- *          called
- */
-ObjectWithListeners.prototype.addPropertyChangeListener = function (name, fun) {
-  if (this._validPropertyListeners[name] === undefined) {
-    throw new Error("Unknown property type: " + name);
-  }
-
-  if (typeof fun !== "function") {
-    throw new Error("Second parameter must be a function but \"" + typeof (fun) + "\" found.");
-  }
-
-  this._validPropertyListeners[name].push(fun);
-};
-
-/**
- * Register new type of listener.
- *
- * @param type
- *          string identifying new type of listener
- */
-ObjectWithListeners.prototype.registerListenerType = function (type) {
-  if (this._validListeners[type] !== undefined) {
-    throw new Error("Listener type already registered: " + type);
-  }
-  this._validListeners[type] = [];
-};
-
-/**
- * Register new property for listening.
- *
- * @param name
- *          string identifying property
- */
-ObjectWithListeners.prototype.registerPropertyType = function (name) {
-  if (this._validPropertyListeners[name] !== undefined) {
-    throw new Error("Property already registered: " + name);
-  }
-  this._validPropertyListeners[name] = [];
-};
-
-/**
- * Removes listener from the object.
- *
- * @param type
- *          type of the listener
- * @param fun
- *          function that was call when event occurred that should be removed
- */
-ObjectWithListeners.prototype.removeListener = function (type, fun) {
-  if (this._validListeners[type] === undefined) {
-    throw new Error("Unknown listener type: " + type);
-  }
-
-  if (typeof (fun) !== "function") {
-    throw new Error("Second parameter must be a function but \"" + typeof (fun) + "\" found.");
-  }
-
-  var listenerList = this._validListeners[type];
-
-  var index = listenerList.indexOf(fun);
-  if (index > -1) {
-    listenerList.splice(index, 1);
-  } else {
-    logger.warn("Cannot remove listener. It doesn't exist", type, fun);
-  }
-};
-
-/**
- * Removes property listener from the object.
- *
- * @param name
- *          name of the property
- * @param fun
- *          function that was call when event occurred that should be removed
- */
-ObjectWithListeners.prototype.removePropertyListener = function (name, fun) {
-  if (this._validPropertyListeners[name] === undefined) {
-    throw new Error("Unknown property: " + name);
-  }
-
-  if (typeof (fun) !== "function") {
-    throw new Error("Second parameter must be a function but \"" + typeof (fun) + "\" found.");
-  }
-
-  var listenerList = this._validPropertyListeners[name];
-
-  var index = listenerList.indexOf(fun);
-  if (index > -1) {
-    listenerList.splice(index, 1);
-  } else {
-    logger.warn("Cannot remove listener. It doesn't exist", name, fun);
-  }
-};
-
-/**
- * Fires listeners of a given type.
- *
- * @param {string} type
- *          type of the listener (string)
- * @param arg
- *          argument data passed to the handler
- *
- * @returns {PromiseLike}
- */
-ObjectWithListeners.prototype.callListeners = function (type, arg) {
-  if (this._validListeners[type] === undefined) {
-    throw new Error("Unknown listener type: " + type);
-  }
-  var listenerList = this._validListeners[type];
-  var promises = [];
-  if (listenerList.length > 0) {
-    for (var i in listenerList) {
-      if (listenerList.hasOwnProperty(i)) {
-        var e = {
-          type: type,
-          object: this,
-          arg: arg
-        };
-        promises.push(listenerList[i](e));
-      }
-    }
-  }
-  return Promise.all(promises);
-};
-
-ObjectWithListeners.prototype.getListeners = function (type) {
-  if (this._validListeners[type] === undefined) {
-    throw new Error("Unknown listener type: " + type);
-  }
-  return this._validListeners[type];
-};
-
-/**
- * Fires property change listeners for a given property name.
- *
- * @param propertyName
- *          name of the property
- * @param oldValue
- *          old value of the property
- * @param newValue
- *          new value of the property
- */
-ObjectWithListeners.prototype.firePropertyChangeListener = function (propertyName, oldValue, newValue) {
-  var self = this;
-  if (this._validPropertyListeners[propertyName] === undefined) {
-    throw new Error("Unknown property type: " + propertyName);
-  }
-  var listenerList = this._validPropertyListeners[propertyName];
-  var promises = [];
-  if (listenerList.length > 0) {
-    for (var i in listenerList) {
-      var e = {
-        propertyName: propertyName,
-        object: self,
-        oldVal: oldValue,
-        newVal: newValue
-      };
-      promises.push(listenerList[i](e));
-    }
-  }
-  return Promise.all(promises);
-};
-
-module.exports = ObjectWithListeners;
+"use strict";
+
+var Promise = require("bluebird");
+
+var logger = require('./logger');
+
+/**
+ * An abstract class that allows to register listeners and call them in case of
+ * events.
+ * @constructor
+ */
+function ObjectWithListeners() {
+  this._validListeners = [];
+  this._validPropertyListeners = [];
+}
+
+/**
+ * @callback ListenerCallback
+ * @param event
+ */
+/**
+ * Adds a listener function to the object.
+ *
+ * @param {string} type
+ *          string defining type of the listener
+ * @param {ListenerCallback} fun
+ *          function that should be thrown when type event occurs
+ */
+ObjectWithListeners.prototype.addListener = function (type, fun) {
+  if (this._validListeners[type] === undefined) {
+    throw new Error("Unknown listener type: " + type);
+  }
+
+  if (typeof fun !== "function") {
+    throw new Error("Second parameter must be a function but \"" + typeof (fun) + "\" found.");
+  }
+
+  this._validListeners[type].push(fun);
+};
+
+/**
+ * Adds a property change listener function to the object.
+ *
+ * @param {string} name
+ *          string defining property name
+ * @param {function} fun
+ *          function that should be thrown when firePropertyChangeListener is
+ *          called
+ */
+ObjectWithListeners.prototype.addPropertyChangeListener = function (name, fun) {
+  if (this._validPropertyListeners[name] === undefined) {
+    throw new Error("Unknown property type: " + name);
+  }
+
+  if (typeof fun !== "function") {
+    throw new Error("Second parameter must be a function but \"" + typeof (fun) + "\" found.");
+  }
+
+  this._validPropertyListeners[name].push(fun);
+};
+
+/**
+ * Register new type of listener.
+ *
+ * @param type
+ *          string identifying new type of listener
+ */
+ObjectWithListeners.prototype.registerListenerType = function (type) {
+  if (this._validListeners[type] !== undefined) {
+    throw new Error("Listener type already registered: " + type);
+  }
+  this._validListeners[type] = [];
+};
+
+/**
+ * Register new property for listening.
+ *
+ * @param name
+ *          string identifying property
+ */
+ObjectWithListeners.prototype.registerPropertyType = function (name) {
+  if (this._validPropertyListeners[name] !== undefined) {
+    throw new Error("Property already registered: " + name);
+  }
+  this._validPropertyListeners[name] = [];
+};
+
+/**
+ * Removes listener from the object.
+ *
+ * @param type
+ *          type of the listener
+ * @param fun
+ *          function that was call when event occurred that should be removed
+ */
+ObjectWithListeners.prototype.removeListener = function (type, fun) {
+  if (this._validListeners[type] === undefined) {
+    throw new Error("Unknown listener type: " + type);
+  }
+
+  if (typeof (fun) !== "function") {
+    throw new Error("Second parameter must be a function but \"" + typeof (fun) + "\" found.");
+  }
+
+  var listenerList = this._validListeners[type];
+
+  var index = listenerList.indexOf(fun);
+  if (index > -1) {
+    listenerList.splice(index, 1);
+  } else {
+    logger.warn("Cannot remove listener. It doesn't exist", type, fun);
+  }
+};
+
+/**
+ * Removes property listener from the object.
+ *
+ * @param name
+ *          name of the property
+ * @param fun
+ *          function that was call when event occurred that should be removed
+ */
+ObjectWithListeners.prototype.removePropertyListener = function (name, fun) {
+  if (this._validPropertyListeners[name] === undefined) {
+    throw new Error("Unknown property: " + name);
+  }
+
+  if (typeof (fun) !== "function") {
+    throw new Error("Second parameter must be a function but \"" + typeof (fun) + "\" found.");
+  }
+
+  var listenerList = this._validPropertyListeners[name];
+
+  var index = listenerList.indexOf(fun);
+  if (index > -1) {
+    listenerList.splice(index, 1);
+  } else {
+    logger.warn("Cannot remove listener. It doesn't exist", name, fun);
+  }
+};
+
+/**
+ * Fires listeners of a given type.
+ *
+ * @param {string} type
+ *          type of the listener (string)
+ * @param arg
+ *          argument data passed to the handler
+ *
+ * @returns {PromiseLike}
+ */
+ObjectWithListeners.prototype.callListeners = function (type, arg) {
+  if (this._validListeners[type] === undefined) {
+    throw new Error("Unknown listener type: " + type);
+  }
+  var listenerList = this._validListeners[type];
+  var promises = [];
+  if (listenerList.length > 0) {
+    for (var i in listenerList) {
+      if (listenerList.hasOwnProperty(i)) {
+        var e = {
+          type: type,
+          object: this,
+          arg: arg
+        };
+        promises.push(listenerList[i](e));
+      }
+    }
+  }
+  return Promise.all(promises);
+};
+
+ObjectWithListeners.prototype.getListeners = function (type) {
+  if (this._validListeners[type] === undefined) {
+    throw new Error("Unknown listener type: " + type);
+  }
+  return this._validListeners[type];
+};
+
+/**
+ * Fires property change listeners for a given property name.
+ *
+ * @param propertyName
+ *          name of the property
+ * @param oldValue
+ *          old value of the property
+ * @param newValue
+ *          new value of the property
+ */
+ObjectWithListeners.prototype.firePropertyChangeListener = function (propertyName, oldValue, newValue) {
+  var self = this;
+  if (this._validPropertyListeners[propertyName] === undefined) {
+    throw new Error("Unknown property type: " + propertyName);
+  }
+  var listenerList = this._validPropertyListeners[propertyName];
+  var promises = [];
+  if (listenerList.length > 0) {
+    for (var i in listenerList) {
+      var e = {
+        propertyName: propertyName,
+        object: self,
+        oldVal: oldValue,
+        newVal: newValue
+      };
+      promises.push(listenerList[i](e));
+    }
+  }
+  return Promise.all(promises);
+};
+
+module.exports = ObjectWithListeners;
diff --git a/frontend-js/src/main/js/SecurityError.js b/frontend-js/src/main/js/SecurityError.js
index 7d180d91f4e4b54855719e6d8f610f9f4a1a4682..c5755cafbf7c01cf49adac587591c5641cd1b456 100644
--- a/frontend-js/src/main/js/SecurityError.js
+++ b/frontend-js/src/main/js/SecurityError.js
@@ -1,15 +1,15 @@
-"use strict";
-
-/* exported logger */
-
-var logger = require('./logger');
-
-function SecurityError(message) {
-  this.message = message;
-  this.stack = (new Error()).stack;
-}
-
-SecurityError.prototype = Object.create(Error.prototype);
-SecurityError.prototype.constructor = SecurityError;
-
-module.exports = SecurityError;
+"use strict";
+
+/* exported logger */
+
+var logger = require('./logger');
+
+function SecurityError(message) {
+  this.message = message;
+  this.stack = (new Error()).stack;
+}
+
+SecurityError.prototype = Object.create(Error.prototype);
+SecurityError.prototype.constructor = SecurityError;
+
+module.exports = SecurityError;
diff --git a/frontend-js/src/main/js/SessionData.js b/frontend-js/src/main/js/SessionData.js
index 3d3776a211ce0151e1beae29383c1daf55ff4f34..30b8d32347b85aba7f3ae332b534edc97f9e808b 100644
--- a/frontend-js/src/main/js/SessionData.js
+++ b/frontend-js/src/main/js/SessionData.js
@@ -1,225 +1,225 @@
-"use strict";
-
-/* exported logger */
-
-var Point = require('./map/canvas/Point');
-var SessionObjectType = require('./SessionObjectType');
-
-var Cookies = require('js-cookie');
-
-var logger = require('./logger');
-
-function SessionData(project) {
-  if (project === undefined) {
-    throw new Error("Project must be passed as an argument");
-  }
-  this.setProject(project);
-}
-
-SessionData.prototype.setProject = function(project) {
-  this._project = project;
-};
-
-SessionData.prototype.getProject = function() {
-  return this._project;
-};
-
-SessionData.prototype.getProjectId = function() {
-  return this._project.getProjectId();
-};
-
-SessionData.prototype.getShowComments = function() {
-  var key = this.getKey(SessionObjectType.SHOW_COMMENT);
-  return Cookies.get(key) === "true";
-};
-
-SessionData.prototype.setSearchQuery = function(value) {
-  var key = this.getKey(SessionObjectType.SEARCH_QUERY);
-  Cookies.set(key, JSON.stringify(value));
-};
-
-SessionData.prototype.setQuery = function(param) {
-  if (param.type === "drug") {
-    this.setDrugQuery(param.query);
-  } else if (param.type === "search") {
-    this.setSearchQuery(param.query);
-  } else if (param.type === "chemical") {
-    this.setChemicalQuery(param.query);
-  } else if (param.type === "mirna") {
-    this.setMiRnaQuery(param.query);
-  } else {
-    throw new Error("Invalid query type: " + param.type);
-  }
-};
-
-SessionData.prototype.getSearchQuery = function() {
-  var key = this.getKey(SessionObjectType.SEARCH_QUERY);
-  var result = Cookies.get(key);
-  if (result !== undefined) {
-    result = JSON.parse(result);
-  }
-  return result;
-};
-
-SessionData.prototype.setDrugQuery = function(value) {
-  var key = this.getKey(SessionObjectType.DRUG_QUERY);
-  Cookies.set(key, JSON.stringify(value));
-};
-
-SessionData.prototype.getDrugQuery = function() {
-  var key = this.getKey(SessionObjectType.DRUG_QUERY);
-  var result = Cookies.get(key);
-  if (result !== undefined) {
-    result = JSON.parse(result);
-  }
-  return result;
-};
-
-SessionData.prototype.setMiRnaQuery = function(value) {
-  var key = this.getKey(SessionObjectType.MI_RNA_QUERY);
-  Cookies.set(key, JSON.stringify(value));
-};
-
-SessionData.prototype.getMiRnaQuery = function() {
-  var key = this.getKey(SessionObjectType.MI_RNA_QUERY);
-  var result = Cookies.get(key);
-  if (result !== undefined) {
-    result = JSON.parse(result);
-  }
-  return result;
-};
-
-SessionData.prototype.setChemicalQuery = function(value) {
-  var key = this.getKey(SessionObjectType.CHEMICAL_QUERY);
-  Cookies.set(key, JSON.stringify(value));
-};
-
-SessionData.prototype.getChemicalQuery = function() {
-  var key = this.getKey(SessionObjectType.CHEMICAL_QUERY);
-  var result = Cookies.get(key);
-  if (result !== undefined) {
-    result = JSON.parse(result);
-  }
-  return result;
-};
-
-SessionData.prototype.setShowComments = function(value) {
-  var key = this.getKey(SessionObjectType.SHOW_COMMENT);
-  Cookies.set(key, value + "");
-};
-
-SessionData.prototype.getSelectedBackgroundOverlay = function() {
-  var key = this.getKey(SessionObjectType.SELECTED_BACKGROUND_OVERLAY);
-  return Cookies.get(key);
-};
-
-SessionData.prototype.setSelectedBackgroundOverlay = function(value) {
-  var key = this.getKey(SessionObjectType.SELECTED_BACKGROUND_OVERLAY);
-  Cookies.set(key, value + "");
-};
-
-SessionData.prototype.getVisibleOverlays = function() {
-  var key = this.getKey(SessionObjectType.VISIBLE_OVERLAYS);
-  var value = Cookies.get(key);
-  if (value === undefined || value === "") {
-    value = [];
-  } else {
-    value = value.split(",");
-  }
-  return value;
-};
-
-SessionData.prototype.setVisibleOverlays = function(value) {
-  var key = this.getKey(SessionObjectType.VISIBLE_OVERLAYS);
-  Cookies.set(key, value + "");
-};
-
-/**
- *
- * @param {MapModel} model
- * @param {number} value
- */
-SessionData.prototype.setZoomLevel = function(model, value) {
-  var key = this.getKey(SessionObjectType.ZOOM_LEVEL, [ model.getId() ]);
-  Cookies.set(key, value + "");
-};
-
-/**
- *
- * @param {MapModel} model
- * @returns {number}
- */
-SessionData.prototype.getZoomLevel = function(model) {
-  var key = this.getKey(SessionObjectType.ZOOM_LEVEL, [ model.getId() ]);
-  var value = Cookies.get(key);
-  if (value !== undefined) {
-    value = parseInt(value);
-  }
-  return value;
-};
-
-SessionData.prototype.setToken = function(token) {
-  var key = SessionObjectType.TOKEN;
-  if (token === undefined) {
-    Cookies.remove(key);
-  } else {
-    Cookies.set(key, token);
-  }
-};
-
-SessionData.prototype.getToken = function() {
-  var key = SessionObjectType.TOKEN;
-  return Cookies.get(key);
-};
-
-SessionData.prototype.setLogin = function(login) {
-  var key = SessionObjectType.LOGIN;
-  if (login === undefined) {
-    Cookies.remove(key);
-  } else {
-    Cookies.set(key, login);
-  }
-};
-
-SessionData.prototype.getLogin = function() {
-  var key = SessionObjectType.LOGIN;
-  return Cookies.get(key);
-};
-
-SessionData.prototype.setCenter = function(model, value) {
-  var key = this.getKey(SessionObjectType.CENTER, [ model.getId() ]);
-  Cookies.set(key, value.x + "," + value.y);
-};
-
-/**
- *
- * @param {MapModel} model
- * @returns {Point}
- */
-SessionData.prototype.getCenter = function(model) {
-  var key = this.getKey(SessionObjectType.CENTER, [ model.getId() ]);
-  var value = Cookies.get(key);
-  if (value !== undefined) {
-    var tmp = value.split(",");
-    value = new Point(tmp[0], tmp[1]);
-  }
-  return value;
-};
-
-/**
- *
- * @param {string} type
- * @param {Array} [args]
- * @returns {string}
- */
-SessionData.prototype.getKey = function(type, args) {
-  if (type === undefined) {
-    throw new Error("Undefined type");
-  }
-  if (args === undefined) {
-    args = [];
-  }
-  return type + "_" + this.getProjectId() + "_" + args.join("_");
-};
-
-module.exports = SessionData;
+"use strict";
+
+/* exported logger */
+
+var Point = require('./map/canvas/Point');
+var SessionObjectType = require('./SessionObjectType');
+
+var Cookies = require('js-cookie');
+
+var logger = require('./logger');
+
+function SessionData(project) {
+  if (project === undefined) {
+    throw new Error("Project must be passed as an argument");
+  }
+  this.setProject(project);
+}
+
+SessionData.prototype.setProject = function(project) {
+  this._project = project;
+};
+
+SessionData.prototype.getProject = function() {
+  return this._project;
+};
+
+SessionData.prototype.getProjectId = function() {
+  return this._project.getProjectId();
+};
+
+SessionData.prototype.getShowComments = function() {
+  var key = this.getKey(SessionObjectType.SHOW_COMMENT);
+  return Cookies.get(key) === "true";
+};
+
+SessionData.prototype.setSearchQuery = function(value) {
+  var key = this.getKey(SessionObjectType.SEARCH_QUERY);
+  Cookies.set(key, JSON.stringify(value));
+};
+
+SessionData.prototype.setQuery = function(param) {
+  if (param.type === "drug") {
+    this.setDrugQuery(param.query);
+  } else if (param.type === "search") {
+    this.setSearchQuery(param.query);
+  } else if (param.type === "chemical") {
+    this.setChemicalQuery(param.query);
+  } else if (param.type === "mirna") {
+    this.setMiRnaQuery(param.query);
+  } else {
+    throw new Error("Invalid query type: " + param.type);
+  }
+};
+
+SessionData.prototype.getSearchQuery = function() {
+  var key = this.getKey(SessionObjectType.SEARCH_QUERY);
+  var result = Cookies.get(key);
+  if (result !== undefined) {
+    result = JSON.parse(result);
+  }
+  return result;
+};
+
+SessionData.prototype.setDrugQuery = function(value) {
+  var key = this.getKey(SessionObjectType.DRUG_QUERY);
+  Cookies.set(key, JSON.stringify(value));
+};
+
+SessionData.prototype.getDrugQuery = function() {
+  var key = this.getKey(SessionObjectType.DRUG_QUERY);
+  var result = Cookies.get(key);
+  if (result !== undefined) {
+    result = JSON.parse(result);
+  }
+  return result;
+};
+
+SessionData.prototype.setMiRnaQuery = function(value) {
+  var key = this.getKey(SessionObjectType.MI_RNA_QUERY);
+  Cookies.set(key, JSON.stringify(value));
+};
+
+SessionData.prototype.getMiRnaQuery = function() {
+  var key = this.getKey(SessionObjectType.MI_RNA_QUERY);
+  var result = Cookies.get(key);
+  if (result !== undefined) {
+    result = JSON.parse(result);
+  }
+  return result;
+};
+
+SessionData.prototype.setChemicalQuery = function(value) {
+  var key = this.getKey(SessionObjectType.CHEMICAL_QUERY);
+  Cookies.set(key, JSON.stringify(value));
+};
+
+SessionData.prototype.getChemicalQuery = function() {
+  var key = this.getKey(SessionObjectType.CHEMICAL_QUERY);
+  var result = Cookies.get(key);
+  if (result !== undefined) {
+    result = JSON.parse(result);
+  }
+  return result;
+};
+
+SessionData.prototype.setShowComments = function(value) {
+  var key = this.getKey(SessionObjectType.SHOW_COMMENT);
+  Cookies.set(key, value + "");
+};
+
+SessionData.prototype.getSelectedBackgroundOverlay = function() {
+  var key = this.getKey(SessionObjectType.SELECTED_BACKGROUND_OVERLAY);
+  return Cookies.get(key);
+};
+
+SessionData.prototype.setSelectedBackgroundOverlay = function(value) {
+  var key = this.getKey(SessionObjectType.SELECTED_BACKGROUND_OVERLAY);
+  Cookies.set(key, value + "");
+};
+
+SessionData.prototype.getVisibleOverlays = function() {
+  var key = this.getKey(SessionObjectType.VISIBLE_OVERLAYS);
+  var value = Cookies.get(key);
+  if (value === undefined || value === "") {
+    value = [];
+  } else {
+    value = value.split(",");
+  }
+  return value;
+};
+
+SessionData.prototype.setVisibleOverlays = function(value) {
+  var key = this.getKey(SessionObjectType.VISIBLE_OVERLAYS);
+  Cookies.set(key, value + "");
+};
+
+/**
+ *
+ * @param {MapModel} model
+ * @param {number} value
+ */
+SessionData.prototype.setZoomLevel = function(model, value) {
+  var key = this.getKey(SessionObjectType.ZOOM_LEVEL, [ model.getId() ]);
+  Cookies.set(key, value + "");
+};
+
+/**
+ *
+ * @param {MapModel} model
+ * @returns {number}
+ */
+SessionData.prototype.getZoomLevel = function(model) {
+  var key = this.getKey(SessionObjectType.ZOOM_LEVEL, [ model.getId() ]);
+  var value = Cookies.get(key);
+  if (value !== undefined) {
+    value = parseInt(value);
+  }
+  return value;
+};
+
+SessionData.prototype.setToken = function(token) {
+  var key = SessionObjectType.TOKEN;
+  if (token === undefined) {
+    Cookies.remove(key);
+  } else {
+    Cookies.set(key, token);
+  }
+};
+
+SessionData.prototype.getToken = function() {
+  var key = SessionObjectType.TOKEN;
+  return Cookies.get(key);
+};
+
+SessionData.prototype.setLogin = function(login) {
+  var key = SessionObjectType.LOGIN;
+  if (login === undefined) {
+    Cookies.remove(key);
+  } else {
+    Cookies.set(key, login);
+  }
+};
+
+SessionData.prototype.getLogin = function() {
+  var key = SessionObjectType.LOGIN;
+  return Cookies.get(key);
+};
+
+SessionData.prototype.setCenter = function(model, value) {
+  var key = this.getKey(SessionObjectType.CENTER, [ model.getId() ]);
+  Cookies.set(key, value.x + "," + value.y);
+};
+
+/**
+ *
+ * @param {MapModel} model
+ * @returns {Point}
+ */
+SessionData.prototype.getCenter = function(model) {
+  var key = this.getKey(SessionObjectType.CENTER, [ model.getId() ]);
+  var value = Cookies.get(key);
+  if (value !== undefined) {
+    var tmp = value.split(",");
+    value = new Point(tmp[0], tmp[1]);
+  }
+  return value;
+};
+
+/**
+ *
+ * @param {string} type
+ * @param {Array} [args]
+ * @returns {string}
+ */
+SessionData.prototype.getKey = function(type, args) {
+  if (type === undefined) {
+    throw new Error("Undefined type");
+  }
+  if (args === undefined) {
+    args = [];
+  }
+  return type + "_" + this.getProjectId() + "_" + args.join("_");
+};
+
+module.exports = SessionData;
diff --git a/frontend-js/src/main/js/SessionObjectType.js b/frontend-js/src/main/js/SessionObjectType.js
index 6240a50fff5210bfaf92ec6b7466e4f9aa2fc9d6..f2c0caa4c7336ff0496ed33589a7eeaca68c3b3a 100644
--- a/frontend-js/src/main/js/SessionObjectType.js
+++ b/frontend-js/src/main/js/SessionObjectType.js
@@ -1,19 +1,19 @@
-"use strict";
-
-var SessionObjectType = {
-  CHEMICAL_QUERY : "CHEMICAL_QUERY",
-  DRUG_QUERY : "DRUG_QUERY",
-  MI_RNA_QUERY : "MI_RNA_QUERY",
-  SHOW_COMMENT : "SHOW_COMMENT",
-  SELECTED_BACKGROUND_OVERLAY : "SELECTED_BACKGROUND_OVERLAY",
-  SEARCH_QUERY : "SEARCH_QUERY",
-  VISIBLE_OVERLAYS : "VISIBLE_OVERLAYS",
-
-  CENTER : "CENTER",
-  ZOOM_LEVEL : "ZOOM_LEVEL",
-
-  TOKEN: "MINERVA_AUTH_TOKEN",
-  LOGIN: "LOGIN"
-};
-
-module.exports = SessionObjectType;
+"use strict";
+
+var SessionObjectType = {
+  CHEMICAL_QUERY : "CHEMICAL_QUERY",
+  DRUG_QUERY : "DRUG_QUERY",
+  MI_RNA_QUERY : "MI_RNA_QUERY",
+  SHOW_COMMENT : "SHOW_COMMENT",
+  SELECTED_BACKGROUND_OVERLAY : "SELECTED_BACKGROUND_OVERLAY",
+  SEARCH_QUERY : "SEARCH_QUERY",
+  VISIBLE_OVERLAYS : "VISIBLE_OVERLAYS",
+
+  CENTER : "CENTER",
+  ZOOM_LEVEL : "ZOOM_LEVEL",
+
+  TOKEN: "MINERVA_AUTH_TOKEN",
+  LOGIN: "LOGIN"
+};
+
+module.exports = SessionObjectType;
diff --git a/frontend-js/src/main/js/ValidationError.js b/frontend-js/src/main/js/ValidationError.js
index e23e2abe0257e48d6f75528bbc63074c921e1819..aaa83e2edfdeed9654d988ad15ec67ac4b6e77a1 100644
--- a/frontend-js/src/main/js/ValidationError.js
+++ b/frontend-js/src/main/js/ValidationError.js
@@ -1,15 +1,15 @@
-"use strict";
-
-/* exported logger */
-
-var logger = require('./logger');
-
-function ValidationError(message) {
-  this.message = message;
-  this.stack = (new Error()).stack;
-}
-
-ValidationError.prototype = Object.create(Error.prototype);
-ValidationError.prototype.constructor = ValidationError;
-
-module.exports = ValidationError;
+"use strict";
+
+/* exported logger */
+
+var logger = require('./logger');
+
+function ValidationError(message) {
+  this.message = message;
+  this.stack = (new Error()).stack;
+}
+
+ValidationError.prototype = Object.create(Error.prototype);
+ValidationError.prototype.constructor = ValidationError;
+
+module.exports = ValidationError;
diff --git a/frontend-js/src/main/js/gui/AbstractGuiElement.js b/frontend-js/src/main/js/gui/AbstractGuiElement.js
index 739abfa07a8a4c91685a8480f0fd49310d8a205c..d5be62beb61320ee976f5a500c173896b9d61b9b 100644
--- a/frontend-js/src/main/js/gui/AbstractGuiElement.js
+++ b/frontend-js/src/main/js/gui/AbstractGuiElement.js
@@ -1,229 +1,229 @@
-"use strict";
-
-/* exported logger */
-
-var ObjectWithListeners = require('../ObjectWithListeners');
-var PanelControlElementType = require('./PanelControlElementType');
-
-// noinspection JSUnusedLocalSymbols
-var logger = require('../logger');
-var Functions = require('../Functions');
-
-/**
- *
- * @param {Object} params
- * @param {HTMLElement} params.element
- * @param {CustomMap} [params.customMap]
- * @param {Configuration} params.configuration
- * @param {Project} [params.project]
- * @param {ServerConnector} [params.serverConnector]
- *
- * @constructor
- *
- * @extends ObjectWithListeners
- */
-function AbstractGuiElement(params) {
-  ObjectWithListeners.call(this, params);
-
-  var self = this;
-
-  self.setElement(params.element);
-  self.setConfiguration(params.configuration);
-  self.setProject(params.project);
-  self.setMap(params.customMap);
-  self.setServerConnector(params.serverConnector);
-
-  self._controlElements = [];
-
-}
-
-AbstractGuiElement.prototype = Object.create(ObjectWithListeners.prototype);
-AbstractGuiElement.prototype.constructor = AbstractGuiElement;
-
-/**
- *
- * @param {CustomMap} map
- */
-AbstractGuiElement.prototype.setMap = function (map) {
-  this._map = map;
-};
-
-/**
- *
- * @returns {CustomMap}
- */
-AbstractGuiElement.prototype.getMap = function () {
-  return this._map;
-};
-
-/**
- *
- * @param {HTMLElement} element
- */
-AbstractGuiElement.prototype.setElement = function (element) {
-  if (element === undefined || element === null) {
-    throw new Error("DOM Element must be defined");
-  }
-  this._element = element;
-};
-
-/**
- *
- * @returns {HTMLElement}
- */
-AbstractGuiElement.prototype.getElement = function () {
-  return this._element;
-};
-
-/**
- *
- * @param {Project} project
- */
-AbstractGuiElement.prototype.setProject = function (project) {
-  this._project = project;
-};
-
-/**
- *
- * @returns {Project}
- */
-AbstractGuiElement.prototype.getProject = function () {
-  if (this._project === undefined || this._project === null) {
-    if (this.getMap()) {
-      return this.getMap().getProject();
-    } else {
-      return null;
-    }
-  } else {
-    return this._project;
-  }
-};
-
-
-/**
- *
- * @param {string} type
- * @param {HTMLElement} element
- */
-AbstractGuiElement.prototype.setControlElement = function (type, element) {
-  if (type === null || type === undefined) {
-    throw new Error("Unknown control element type");
-  }
-  if (PanelControlElementType[type] === undefined) {
-    throw new Error("Unknown control element type: " + type);
-  }
-
-  this._controlElements[type] = element;
-};
-
-/**
- *
- * @param {string} type
- * @returns {HTMLElement}
- */
-AbstractGuiElement.prototype.getControlElement = function (type) {
-  if (type === null || type === undefined) {
-    throw new Error("Unknown control element type");
-  }
-  if (PanelControlElementType[type] === undefined) {
-    throw new Error("Unknown control element type: " + type);
-  }
-
-  return this._controlElements[type];
-};
-
-/**
- *
- * @param {string} url
- */
-AbstractGuiElement.prototype.downloadFile = function (url) {
-  this._downloadFile = url;
-  window.open(url, '_blank');
-};
-
-/**
- *
- * @returns {string}
- */
-AbstractGuiElement.prototype.getLastDownloadUrl = function () {
-  return this._downloadFile;
-};
-
-/**
- *
- * @param {Configuration} configuration
- */
-AbstractGuiElement.prototype.setConfiguration = function (configuration) {
-  this._configuration = configuration;
-};
-
-/**
- *
- * @returns {Configuration}
- */
-AbstractGuiElement.prototype.getConfiguration = function () {
-  return this._configuration;
-};
-
-/**
- *
- * @param {ServerConnector} serverConnector
- */
-AbstractGuiElement.prototype.setServerConnector = function (serverConnector) {
-  this._serverConnector = serverConnector;
-};
-
-/**
- *
- * @returns {ServerConnector}
- */
-AbstractGuiElement.prototype.getServerConnector = function () {
-  if (this._serverConnector !== undefined) {
-    return this._serverConnector;
-  } else {
-    return this.getMap().getServerConnector();
-  }
-};
-
-/**
- *
- * @param {string} [params.content]
- * @param {string} params.title
- * @param {boolean} [params.input]
- * @returns {Promise}
- */
-AbstractGuiElement.prototype.askConfirmRemoval = function (params) {
-  return new Promise(function (resolve) {
-    var html;
-    var content = '';
-    if (params.content) {
-      content = params.content;
-    }
-    if (params.input) {
-      html = '<form><input type="text" style="z-index:10000" name="reason-value"><br></form>';
-    } else {
-      html = '<form><span>' + content + '</span><input type="text" style="z-index:10000;visibility: hidden" name="reason-value"><br></form>';
-    }
-    $(html).dialog({
-      modal: true,
-      title: params.title,
-      close: function () {
-        $(this).dialog('destroy').remove();
-        resolve({status: false});
-      },
-      buttons: {
-        'OK': function () {
-          var reason = $('input[name="reason-value"]').val();
-          $(this).dialog('destroy').remove();
-          resolve({reason: reason, status: true});
-        },
-        'Cancel': function () {
-          $(this).dialog('destroy').remove();
-          resolve({status: false});
-        }
-      }
-    });
-  })
-};
-
-module.exports = AbstractGuiElement;
+"use strict";
+
+/* exported logger */
+
+var ObjectWithListeners = require('../ObjectWithListeners');
+var PanelControlElementType = require('./PanelControlElementType');
+
+// noinspection JSUnusedLocalSymbols
+var logger = require('../logger');
+var Functions = require('../Functions');
+
+/**
+ *
+ * @param {Object} params
+ * @param {HTMLElement} params.element
+ * @param {CustomMap} [params.customMap]
+ * @param {Configuration} params.configuration
+ * @param {Project} [params.project]
+ * @param {ServerConnector} [params.serverConnector]
+ *
+ * @constructor
+ *
+ * @extends ObjectWithListeners
+ */
+function AbstractGuiElement(params) {
+  ObjectWithListeners.call(this, params);
+
+  var self = this;
+
+  self.setElement(params.element);
+  self.setConfiguration(params.configuration);
+  self.setProject(params.project);
+  self.setMap(params.customMap);
+  self.setServerConnector(params.serverConnector);
+
+  self._controlElements = [];
+
+}
+
+AbstractGuiElement.prototype = Object.create(ObjectWithListeners.prototype);
+AbstractGuiElement.prototype.constructor = AbstractGuiElement;
+
+/**
+ *
+ * @param {CustomMap} map
+ */
+AbstractGuiElement.prototype.setMap = function (map) {
+  this._map = map;
+};
+
+/**
+ *
+ * @returns {CustomMap}
+ */
+AbstractGuiElement.prototype.getMap = function () {
+  return this._map;
+};
+
+/**
+ *
+ * @param {HTMLElement} element
+ */
+AbstractGuiElement.prototype.setElement = function (element) {
+  if (element === undefined || element === null) {
+    throw new Error("DOM Element must be defined");
+  }
+  this._element = element;
+};
+
+/**
+ *
+ * @returns {HTMLElement}
+ */
+AbstractGuiElement.prototype.getElement = function () {
+  return this._element;
+};
+
+/**
+ *
+ * @param {Project} project
+ */
+AbstractGuiElement.prototype.setProject = function (project) {
+  this._project = project;
+};
+
+/**
+ *
+ * @returns {Project}
+ */
+AbstractGuiElement.prototype.getProject = function () {
+  if (this._project === undefined || this._project === null) {
+    if (this.getMap()) {
+      return this.getMap().getProject();
+    } else {
+      return null;
+    }
+  } else {
+    return this._project;
+  }
+};
+
+
+/**
+ *
+ * @param {string} type
+ * @param {HTMLElement} element
+ */
+AbstractGuiElement.prototype.setControlElement = function (type, element) {
+  if (type === null || type === undefined) {
+    throw new Error("Unknown control element type");
+  }
+  if (PanelControlElementType[type] === undefined) {
+    throw new Error("Unknown control element type: " + type);
+  }
+
+  this._controlElements[type] = element;
+};
+
+/**
+ *
+ * @param {string} type
+ * @returns {HTMLElement}
+ */
+AbstractGuiElement.prototype.getControlElement = function (type) {
+  if (type === null || type === undefined) {
+    throw new Error("Unknown control element type");
+  }
+  if (PanelControlElementType[type] === undefined) {
+    throw new Error("Unknown control element type: " + type);
+  }
+
+  return this._controlElements[type];
+};
+
+/**
+ *
+ * @param {string} url
+ */
+AbstractGuiElement.prototype.downloadFile = function (url) {
+  this._downloadFile = url;
+  window.open(url, '_blank');
+};
+
+/**
+ *
+ * @returns {string}
+ */
+AbstractGuiElement.prototype.getLastDownloadUrl = function () {
+  return this._downloadFile;
+};
+
+/**
+ *
+ * @param {Configuration} configuration
+ */
+AbstractGuiElement.prototype.setConfiguration = function (configuration) {
+  this._configuration = configuration;
+};
+
+/**
+ *
+ * @returns {Configuration}
+ */
+AbstractGuiElement.prototype.getConfiguration = function () {
+  return this._configuration;
+};
+
+/**
+ *
+ * @param {ServerConnector} serverConnector
+ */
+AbstractGuiElement.prototype.setServerConnector = function (serverConnector) {
+  this._serverConnector = serverConnector;
+};
+
+/**
+ *
+ * @returns {ServerConnector}
+ */
+AbstractGuiElement.prototype.getServerConnector = function () {
+  if (this._serverConnector !== undefined) {
+    return this._serverConnector;
+  } else {
+    return this.getMap().getServerConnector();
+  }
+};
+
+/**
+ *
+ * @param {string} [params.content]
+ * @param {string} params.title
+ * @param {boolean} [params.input]
+ * @returns {Promise}
+ */
+AbstractGuiElement.prototype.askConfirmRemoval = function (params) {
+  return new Promise(function (resolve) {
+    var html;
+    var content = '';
+    if (params.content) {
+      content = params.content;
+    }
+    if (params.input) {
+      html = '<form><input type="text" style="z-index:10000" name="reason-value"><br></form>';
+    } else {
+      html = '<form><span>' + content + '</span><input type="text" style="z-index:10000;visibility: hidden" name="reason-value"><br></form>';
+    }
+    $(html).dialog({
+      modal: true,
+      title: params.title,
+      close: function () {
+        $(this).dialog('destroy').remove();
+        resolve({status: false});
+      },
+      buttons: {
+        'OK': function () {
+          var reason = $('input[name="reason-value"]').val();
+          $(this).dialog('destroy').remove();
+          resolve({reason: reason, status: true});
+        },
+        'Cancel': function () {
+          $(this).dialog('destroy').remove();
+          resolve({status: false});
+        }
+      }
+    });
+  })
+};
+
+module.exports = AbstractGuiElement;
diff --git a/frontend-js/src/main/js/gui/AddOverlayDialog.js b/frontend-js/src/main/js/gui/AddOverlayDialog.js
index c1ebf8a420f517009c356d065a73b9d95f8ae0fa..d4d8871d96742d872e950466be9e4f898f38200c 100644
--- a/frontend-js/src/main/js/gui/AddOverlayDialog.js
+++ b/frontend-js/src/main/js/gui/AddOverlayDialog.js
@@ -1,296 +1,296 @@
-"use strict";
-
-/* exported logger */
-
-var AbstractGuiElement = require('./AbstractGuiElement');
-var GuiConnector = require('../GuiConnector');
-var GuiUtils = require('./leftPanel/GuiUtils');
-var DataOverlay = require('../map/data/DataOverlay');
-var NetworkError = require('../NetworkError');
-
-var OverlayParser = require('../map/OverlayParser');
-
-var Functions = require('../Functions');
-// noinspection JSUnusedLocalSymbols
-var logger = require('../logger');
-var HttpStatus = require('http-status-codes');
-
-var Promise = require("bluebird");
-var TextEncoder = require('text-encoding').TextEncoder;
-
-/**
- *
- * @param {Object} params
- * @param {HTMLElement} params.element
- * @param {CustomMap} params.customMap
- * @param {Configuration} params.configuration
- * @param {Project} params.project
- * @param {ServerConnector} [params.serverConnector]
- *
- * @constructor
- *
- * @extends AbstractGuiElement
- */
-function AddOverlayDialog(params) {
-  AbstractGuiElement.call(this, params);
-  var self = this;
-  self.registerListenerType("onAddOverlay");
-  self.createGui();
-}
-
-AddOverlayDialog.prototype = Object.create(AbstractGuiElement.prototype);
-AddOverlayDialog.prototype.constructor = AddOverlayDialog;
-
-/**
- *
- */
-AddOverlayDialog.prototype.createGui = function () {
-  var self = this;
-  var guiUtils = new GuiUtils(self.getConfiguration());
-  var content = document.createElement("div");
-  content.style.width = "100%";
-  content.style.height = "100%";
-  content.appendChild(guiUtils.createLabel("Name: "));
-  var nameInput = Functions.createElement({
-    type: "input",
-    inputType: "text",
-    name: "overlay-name"
-  });
-  content.appendChild(nameInput);
-  content.appendChild(guiUtils.createNewLine());
-
-  content.appendChild(guiUtils.createLabel("Description: "));
-  content.appendChild(guiUtils.createNewLine());
-  var descriptionInput = Functions.createElement({
-    type: "textarea",
-    name: "overlay-description"
-  });
-  content.appendChild(descriptionInput);
-  content.appendChild(guiUtils.createNewLine());
-
-  content.appendChild(guiUtils.createLabel("Type: "));
-  content.appendChild(guiUtils.createNewLine());
-  var types = self.getConfiguration().getOverlayTypes();
-  var typeSelect = Functions.createElement({
-    type: "select",
-    name: "overlay-type",
-    value: types[0]
-  });
-  for (var i = 0; i < types.length; i++) {
-    $(typeSelect).append($('<option>', {
-      value: types[i],
-      text: types[i]
-    }));
-  }
-
-  content.appendChild(typeSelect);
-  content.appendChild(guiUtils.createNewLine());
-
-  content.appendChild(guiUtils.createLabel("Upload file: "));
-  var fileInput = Functions.createElement({
-    type: "input",
-    inputType: "file",
-    name: "overlay-file"
-  });
-  fileInput.addEventListener("change", function () {
-    return self.processFile(fileInput.files[0]).then(null, GuiConnector.alert);
-  }, false);
-  content.appendChild(fileInput);
-  content.appendChild(guiUtils.createNewLine());
-
-  content.appendChild(guiUtils.createLabel("Or provide list of elements here (one per line): "));
-  content.appendChild(guiUtils.createNewLine());
-  var contentInput = Functions.createElement({
-    type: "textarea",
-    name: "overlay-content"
-  });
-  content.appendChild(contentInput);
-  content.appendChild(guiUtils.createNewLine());
-
-  var consentCheckbox = Functions.createElement({type: "input", name: "overlay-google-consent"});
-  consentCheckbox.type = "checkbox";
-  content.appendChild(consentCheckbox);
-  content.appendChild(guiUtils.createLabel("I am aware that if this map is displayed using Google Maps API, " +
-    "it falls under their license <a href='https://cloud.google.com/maps-platform/terms/' target='_blank'>" +
-    "https://cloud.google.com/maps-platform/terms/</a>, to which I agree. I warrant that this dataset contains no " +
-    "Protected Health Information (as defined in and subject to HIPAA)."));
-
-  content.appendChild(guiUtils.createNewLine());
-
-  self.getElement().appendChild(content);
-};
-
-AddOverlayDialog.prototype.processFile = function (file) {
-  var self = this;
-  self.setFileContent(null);
-  if (file) {
-    return new Promise(function (resolve, reject) {
-      var reader = new FileReader();
-      reader.readAsArrayBuffer(file);
-      reader.onload = function (evt) {
-        try {
-          var overlayParser = new OverlayParser();
-          self.setFileContent(evt.target.result);
-          var overlay = overlayParser.parse(evt.target.result);
-          var nameInput = $("[name='overlay-name']", self.getElement())[0];
-          var descriptionInput = $("[name='overlay-description']", self.getElement())[0];
-          var typeSelect = $("[name='overlay-type']", self.getElement());
-          if (overlay.getName() !== undefined) {
-            nameInput.value = overlay.getName();
-          } else {
-            var filename = $("[name='overlay-file']", self.getElement())[0].value;
-            if (filename.indexOf(".") > 0) {
-              filename = filename.substr(0, filename.indexOf("."));
-            }
-            if (filename.lastIndexOf("\\") >= 0) {
-              filename = filename.substr(filename.lastIndexOf("\\") + 1);
-            }
-            nameInput.value = filename;
-
-          }
-          if (overlay.getDescription() !== undefined) {
-            descriptionInput.value = overlay.getDescription();
-          }
-          if (overlay.getType() !== undefined) {
-            typeSelect.val(overlay.getType());
-          }
-          if (overlayParser.containsMixedNewLineCharacters(evt.target.result)) {
-            GuiConnector.warn("Selected file contains new line characters from different operating systems " +
-              "(MAC/Windows/Linux). This might cause confusion when reading the file in the editor later on.")
-          }
-          resolve(self.getFileContent());
-        } catch (error) {
-          reject(error);
-        }
-      };
-      reader.onerror = function () {
-        reject(new Error("Problem reading file"));
-      };
-    });
-  } else {
-    return Promise.resolve(null);
-  }
-};
-
-AddOverlayDialog.prototype.setFileContent = function (fileContent) {
-  if (typeof fileContent === 'string' || fileContent instanceof String) {
-    fileContent = new TextEncoder("UTF8").encode(fileContent);
-  }
-
-  this._fileContent = fileContent;
-};
-
-AddOverlayDialog.prototype.getFileContent = function () {
-  var self = this;
-  var contentInput = $("[name='overlay-content']", self.getElement())[0];
-
-  if (contentInput.value !== undefined && contentInput.value !== null) {
-    contentInput.value = contentInput.value.trim();
-    if (contentInput.value !== "") {
-      self.setFileContent(contentInput.value);
-    }
-  }
-  if (self._fileContent === undefined) {
-    return null;
-  } else {
-    return self._fileContent;
-  }
-};
-
-/**
- *
- * @returns {Promise}
- */
-AddOverlayDialog.prototype.init = function () {
-  return Promise.resolve();
-};
-
-
-AddOverlayDialog.prototype.addOverlay = function () {
-  var self = this;
-  var nameInput = $("[name='overlay-name']", self.getElement())[0];
-  var descriptionInput = $("[name='overlay-description']", self.getElement())[0];
-  var filename = $("[name='overlay-file']", self.getElement())[0].value;
-  var type = $("[name='overlay-type']", self.getElement()).val();
-  var consent = $("[name='overlay-google-consent']", self.getElement()).is(":checked");
-  var overlay = new DataOverlay({
-    name: nameInput.value,
-    description: descriptionInput.value,
-    filename: filename,
-    googleLicenseConsent: consent,
-    type: type
-  });
-
-  if (filename === undefined || filename === "") {
-    filename = "unknown.txt";
-  }
-  GuiConnector.showProcessing();
-  return self.getServerConnector().uploadFile({
-    filename: filename,
-    content: self.getFileContent()
-  }).then(function (file) {
-    return self.getServerConnector().addOverlay({
-      fileId: file.id,
-      overlay: overlay,
-      projectId: self.getProject().getProjectId()
-    });
-  }).then(function (result) {
-    overlay = result;
-    GuiConnector.hideProcessing();
-    return self.callListeners("onAddOverlay", overlay);
-  });
-};
-
-/**
- *
- * @returns {PromiseLike}
- */
-AddOverlayDialog.prototype.destroy = function () {
-  $(this.getElement()).dialog("destroy");
-  return Promise.resolve();
-};
-
-AddOverlayDialog.prototype.open = function () {
-  var self = this;
-  var div = self.getElement();
-  if (!$(div).hasClass("ui-dialog-content")) {
-    var buttons = [{
-      text: "UPLOAD",
-      click: function () {
-        var dialog = this;
-        var fileContent = self.getFileContent();
-        if (fileContent === null) {
-          GuiConnector.alert("Neither file was selected nor data was entered");
-        } else {
-          return self.addOverlay().then(function (result) {
-            $(dialog).dialog("close");
-            return result;
-          }, function (error) {
-            GuiConnector.hideProcessing();
-            if (error instanceof NetworkError && error.statusCode === HttpStatus.BAD_REQUEST) {
-              var errorMessage = JSON.parse(error.content);
-              GuiConnector.alert("Problematic input: <br/>" + errorMessage.reason);
-            } else {
-              GuiConnector.alert(error);
-            }
-          });
-        }
-      }
-    }, {
-      text: "CANCEL",
-      click: function () {
-        $(this).dialog("close");
-      }
-    }];
-
-    $(div).dialog({
-      title: "Add overlay",
-      buttons: buttons,
-      modal: true
-    });
-  }
-
-  $(div).dialog("open");
-};
-
-module.exports = AddOverlayDialog;
+"use strict";
+
+/* exported logger */
+
+var AbstractGuiElement = require('./AbstractGuiElement');
+var GuiConnector = require('../GuiConnector');
+var GuiUtils = require('./leftPanel/GuiUtils');
+var DataOverlay = require('../map/data/DataOverlay');
+var NetworkError = require('../NetworkError');
+
+var OverlayParser = require('../map/OverlayParser');
+
+var Functions = require('../Functions');
+// noinspection JSUnusedLocalSymbols
+var logger = require('../logger');
+var HttpStatus = require('http-status-codes');
+
+var Promise = require("bluebird");
+var TextEncoder = require('text-encoding').TextEncoder;
+
+/**
+ *
+ * @param {Object} params
+ * @param {HTMLElement} params.element
+ * @param {CustomMap} params.customMap
+ * @param {Configuration} params.configuration
+ * @param {Project} params.project
+ * @param {ServerConnector} [params.serverConnector]
+ *
+ * @constructor
+ *
+ * @extends AbstractGuiElement
+ */
+function AddOverlayDialog(params) {
+  AbstractGuiElement.call(this, params);
+  var self = this;
+  self.registerListenerType("onAddOverlay");
+  self.createGui();
+}
+
+AddOverlayDialog.prototype = Object.create(AbstractGuiElement.prototype);
+AddOverlayDialog.prototype.constructor = AddOverlayDialog;
+
+/**
+ *
+ */
+AddOverlayDialog.prototype.createGui = function () {
+  var self = this;
+  var guiUtils = new GuiUtils(self.getConfiguration());
+  var content = document.createElement("div");
+  content.style.width = "100%";
+  content.style.height = "100%";
+  content.appendChild(guiUtils.createLabel("Name: "));
+  var nameInput = Functions.createElement({
+    type: "input",
+    inputType: "text",
+    name: "overlay-name"
+  });
+  content.appendChild(nameInput);
+  content.appendChild(guiUtils.createNewLine());
+
+  content.appendChild(guiUtils.createLabel("Description: "));
+  content.appendChild(guiUtils.createNewLine());
+  var descriptionInput = Functions.createElement({
+    type: "textarea",
+    name: "overlay-description"
+  });
+  content.appendChild(descriptionInput);
+  content.appendChild(guiUtils.createNewLine());
+
+  content.appendChild(guiUtils.createLabel("Type: "));
+  content.appendChild(guiUtils.createNewLine());
+  var types = self.getConfiguration().getOverlayTypes();
+  var typeSelect = Functions.createElement({
+    type: "select",
+    name: "overlay-type",
+    value: types[0]
+  });
+  for (var i = 0; i < types.length; i++) {
+    $(typeSelect).append($('<option>', {
+      value: types[i],
+      text: types[i]
+    }));
+  }
+
+  content.appendChild(typeSelect);
+  content.appendChild(guiUtils.createNewLine());
+
+  content.appendChild(guiUtils.createLabel("Upload file: "));
+  var fileInput = Functions.createElement({
+    type: "input",
+    inputType: "file",
+    name: "overlay-file"
+  });
+  fileInput.addEventListener("change", function () {
+    return self.processFile(fileInput.files[0]).then(null, GuiConnector.alert);
+  }, false);
+  content.appendChild(fileInput);
+  content.appendChild(guiUtils.createNewLine());
+
+  content.appendChild(guiUtils.createLabel("Or provide list of elements here (one per line): "));
+  content.appendChild(guiUtils.createNewLine());
+  var contentInput = Functions.createElement({
+    type: "textarea",
+    name: "overlay-content"
+  });
+  content.appendChild(contentInput);
+  content.appendChild(guiUtils.createNewLine());
+
+  var consentCheckbox = Functions.createElement({type: "input", name: "overlay-google-consent"});
+  consentCheckbox.type = "checkbox";
+  content.appendChild(consentCheckbox);
+  content.appendChild(guiUtils.createLabel("I am aware that if this map is displayed using Google Maps API, " +
+    "it falls under their license <a href='https://cloud.google.com/maps-platform/terms/' target='_blank'>" +
+    "https://cloud.google.com/maps-platform/terms/</a>, to which I agree. I warrant that this dataset contains no " +
+    "Protected Health Information (as defined in and subject to HIPAA)."));
+
+  content.appendChild(guiUtils.createNewLine());
+
+  self.getElement().appendChild(content);
+};
+
+AddOverlayDialog.prototype.processFile = function (file) {
+  var self = this;
+  self.setFileContent(null);
+  if (file) {
+    return new Promise(function (resolve, reject) {
+      var reader = new FileReader();
+      reader.readAsArrayBuffer(file);
+      reader.onload = function (evt) {
+        try {
+          var overlayParser = new OverlayParser();
+          self.setFileContent(evt.target.result);
+          var overlay = overlayParser.parse(evt.target.result);
+          var nameInput = $("[name='overlay-name']", self.getElement())[0];
+          var descriptionInput = $("[name='overlay-description']", self.getElement())[0];
+          var typeSelect = $("[name='overlay-type']", self.getElement());
+          if (overlay.getName() !== undefined) {
+            nameInput.value = overlay.getName();
+          } else {
+            var filename = $("[name='overlay-file']", self.getElement())[0].value;
+            if (filename.indexOf(".") > 0) {
+              filename = filename.substr(0, filename.indexOf("."));
+            }
+            if (filename.lastIndexOf("\\") >= 0) {
+              filename = filename.substr(filename.lastIndexOf("\\") + 1);
+            }
+            nameInput.value = filename;
+
+          }
+          if (overlay.getDescription() !== undefined) {
+            descriptionInput.value = overlay.getDescription();
+          }
+          if (overlay.getType() !== undefined) {
+            typeSelect.val(overlay.getType());
+          }
+          if (overlayParser.containsMixedNewLineCharacters(evt.target.result)) {
+            GuiConnector.warn("Selected file contains new line characters from different operating systems " +
+              "(MAC/Windows/Linux). This might cause confusion when reading the file in the editor later on.")
+          }
+          resolve(self.getFileContent());
+        } catch (error) {
+          reject(error);
+        }
+      };
+      reader.onerror = function () {
+        reject(new Error("Problem reading file"));
+      };
+    });
+  } else {
+    return Promise.resolve(null);
+  }
+};
+
+AddOverlayDialog.prototype.setFileContent = function (fileContent) {
+  if (typeof fileContent === 'string' || fileContent instanceof String) {
+    fileContent = new TextEncoder("UTF8").encode(fileContent);
+  }
+
+  this._fileContent = fileContent;
+};
+
+AddOverlayDialog.prototype.getFileContent = function () {
+  var self = this;
+  var contentInput = $("[name='overlay-content']", self.getElement())[0];
+
+  if (contentInput.value !== undefined && contentInput.value !== null) {
+    contentInput.value = contentInput.value.trim();
+    if (contentInput.value !== "") {
+      self.setFileContent(contentInput.value);
+    }
+  }
+  if (self._fileContent === undefined) {
+    return null;
+  } else {
+    return self._fileContent;
+  }
+};
+
+/**
+ *
+ * @returns {Promise}
+ */
+AddOverlayDialog.prototype.init = function () {
+  return Promise.resolve();
+};
+
+
+AddOverlayDialog.prototype.addOverlay = function () {
+  var self = this;
+  var nameInput = $("[name='overlay-name']", self.getElement())[0];
+  var descriptionInput = $("[name='overlay-description']", self.getElement())[0];
+  var filename = $("[name='overlay-file']", self.getElement())[0].value;
+  var type = $("[name='overlay-type']", self.getElement()).val();
+  var consent = $("[name='overlay-google-consent']", self.getElement()).is(":checked");
+  var overlay = new DataOverlay({
+    name: nameInput.value,
+    description: descriptionInput.value,
+    filename: filename,
+    googleLicenseConsent: consent,
+    type: type
+  });
+
+  if (filename === undefined || filename === "") {
+    filename = "unknown.txt";
+  }
+  GuiConnector.showProcessing();
+  return self.getServerConnector().uploadFile({
+    filename: filename,
+    content: self.getFileContent()
+  }).then(function (file) {
+    return self.getServerConnector().addOverlay({
+      fileId: file.id,
+      overlay: overlay,
+      projectId: self.getProject().getProjectId()
+    });
+  }).then(function (result) {
+    overlay = result;
+    GuiConnector.hideProcessing();
+    return self.callListeners("onAddOverlay", overlay);
+  });
+};
+
+/**
+ *
+ * @returns {PromiseLike}
+ */
+AddOverlayDialog.prototype.destroy = function () {
+  $(this.getElement()).dialog("destroy");
+  return Promise.resolve();
+};
+
+AddOverlayDialog.prototype.open = function () {
+  var self = this;
+  var div = self.getElement();
+  if (!$(div).hasClass("ui-dialog-content")) {
+    var buttons = [{
+      text: "UPLOAD",
+      click: function () {
+        var dialog = this;
+        var fileContent = self.getFileContent();
+        if (fileContent === null) {
+          GuiConnector.alert("Neither file was selected nor data was entered");
+        } else {
+          return self.addOverlay().then(function (result) {
+            $(dialog).dialog("close");
+            return result;
+          }, function (error) {
+            GuiConnector.hideProcessing();
+            if (error instanceof NetworkError && error.statusCode === HttpStatus.BAD_REQUEST) {
+              var errorMessage = JSON.parse(error.content);
+              GuiConnector.alert("Problematic input: <br/>" + errorMessage.reason);
+            } else {
+              GuiConnector.alert(error);
+            }
+          });
+        }
+      }
+    }, {
+      text: "CANCEL",
+      click: function () {
+        $(this).dialog("close");
+      }
+    }];
+
+    $(div).dialog({
+      title: "Add overlay",
+      buttons: buttons,
+      modal: true
+    });
+  }
+
+  $(div).dialog("open");
+};
+
+module.exports = AddOverlayDialog;
diff --git a/frontend-js/src/main/js/gui/CommentDialog.js b/frontend-js/src/main/js/gui/CommentDialog.js
index 0ca87663084dad9a3f1217e80ac3c515b973a3dc..4a9dea6082de56d5d990a1032815e4514f7412a4 100644
--- a/frontend-js/src/main/js/gui/CommentDialog.js
+++ b/frontend-js/src/main/js/gui/CommentDialog.js
@@ -1,317 +1,317 @@
-"use strict";
-
-/* exported logger */
-
-var Promise = require("bluebird");
-
-var AbstractGuiElement = require('./AbstractGuiElement');
-var Alias = require('../map/data/Alias');
-var Reaction = require('../map/data/Reaction');
-// noinspection JSUnusedLocalSymbols
-var logger = require('../logger');
-var Functions = require('../Functions');
-
-function CommentDialog(params) {
-  AbstractGuiElement.call(this, params);
-  var self = this;
-  self._createGui();
-  $(self.getElement()).dialog({
-    autoOpen: false,
-    resizable: false,
-    width: window.innerWidth / 2,
-    height: window.innerHeight / 2
-  });
-}
-
-CommentDialog.prototype = Object.create(AbstractGuiElement.prototype);
-CommentDialog.prototype.constructor = CommentDialog;
-
-CommentDialog.GENERAL = "<General>";
-
-function createRow(elements) {
-  var row = document.createElement('tr');
-  for (var i = 0; i < elements.length; i++) {
-    var container = document.createElement('td');
-    container.appendChild(elements[i]);
-    row.appendChild(container);
-  }
-  return row;
-}
-
-CommentDialog.prototype.open = function (identifiedElements) {
-  var self = this;
-  self.setTypes([CommentDialog.GENERAL]);
-
-  var promises = [CommentDialog.GENERAL];
-  for (var i = 0; i < identifiedElements.length; i++) {
-    var ie = identifiedElements[i];
-    if (ie.getType() === "ALIAS") {
-      promises.push(self.getMap().getSubmapById(ie.getModelId()).getModel().getAliasById(ie.getId(), true));
-    } else if (ie.getType() === "REACTION") {
-      promises.push(self.getMap().getSubmapById(ie.getModelId()).getModel().getReactionById(ie.getId(), true));
-    } else {
-      throw new Error("Unknown element type: " + ie.getType());
-    }
-  }
-  return Promise.all(promises).then(function (elements) {
-    self.setTypes(elements);
-    return self.getMap().getServerConnector().getLoggedUser();
-  }).then(function (user) {
-    if (user.getLogin() !== "anonymous") {
-      self.setEmail(user.getEmail());
-      self.setName(user.getName() + " " + user.getSurname());
-    }
-
-    $(self.getElement()).dialog("open");
-  });
-};
-
-CommentDialog.prototype._createGui = function () {
-  var self = this;
-
-  var table = document.createElement('table');
-
-  var typeLabel = document.createElement('label');
-  typeLabel.innerHTML = "Type";
-  var typeOptions = document.createElement("select");
-  this.setTypeOptions(typeOptions);
-
-  table.appendChild(createRow([typeLabel, typeOptions]));
-
-  var detailDiv = document.createElement('div');
-
-  table.appendChild(createRow([document.createElement('div'), detailDiv]));
-
-  var pinnedLabel = document.createElement('label');
-  pinnedLabel.innerHTML = "Pinned";
-  var pinnedCheckbox = document.createElement('input');
-  pinnedCheckbox.type = "checkbox";
-  $(pinnedCheckbox).prop("checked", true);
-
-
-  table.appendChild(createRow([pinnedLabel, pinnedCheckbox]));
-  this.setPinnedCheckbox(pinnedCheckbox);
-
-  var nameLabel = document.createElement('label');
-  nameLabel.innerHTML = "Name:<br/>(Visible to moderators only)";
-  var nameInput = document.createElement('input');
-  nameInput.type = "text";
-
-  table.appendChild(createRow([nameLabel, nameInput]));
-  this.setNameInput(nameInput);
-
-  var emailLabel = document.createElement('label');
-  emailLabel.innerHTML = "Email:<br/>(Visible to moderators only)";
-  var emailInput = document.createElement('input');
-  emailInput.type = "text";
-
-  table.appendChild(createRow([emailLabel, emailInput]));
-  this.setEmailInput(emailInput);
-
-  var contentLabel = document.createElement('label');
-  contentLabel.innerHTML = "Content:";
-  var contentInput = document.createElement('textarea');
-  contentInput.cols = 80;
-  contentInput.rows = 3;
-
-  table.appendChild(createRow([contentLabel, contentInput]));
-  this.setContentInput(contentInput);
-
-  var sendButton = document.createElement('button');
-  sendButton.innerHTML = "Send";
-  sendButton.onclick = function () {
-    return self.addComment().then(function () {
-      $(self.getElement()).dialog("close");
-    });
-  };
-
-  table.appendChild(createRow([sendButton]));
-
-  self.getElement().appendChild(table);
-
-  typeOptions.onchange = function () {
-    var option = self.getSelectedType();
-    var text = "";
-    if (option instanceof Alias) {
-      if (option.getFullName() !== undefined) {
-        text = option.getFullName();
-      }
-    } else if (option instanceof Reaction) {
-      text = "Reactants: ";
-      var reactants = option.getReactants();
-      var i;
-      for (i = 0; i < reactants.length; i++) {
-        text += reactants[i].getAlias().getName() + ",";
-      }
-      text += "<br/>";
-      text += "Modifiers: ";
-      var modifiers = option.getModifiers();
-      for (i = 0; i < modifiers.length; i++) {
-        text += modifiers[i].getAlias().getName() + ",";
-      }
-      text += "<br/>";
-      text += "Products: ";
-      var products = option.getProducts();
-      for (i = 0; i < products.length; i++) {
-        text += products[i].getAlias().getName() + ",";
-      }
-      text += "<br/>";
-    }
-    detailDiv.innerHTML = text;
-  };
-};
-CommentDialog.prototype.setTypes = function (types) {
-  var typeOptions = this.getTypeOptions();
-  while (typeOptions.firstChild) {
-    typeOptions.removeChild(typeOptions.firstChild);
-  }
-
-  for (var i = 0; i < types.length; i++) {
-    var option = document.createElement("option");
-    option.value = i.toString();
-    var element = types[i];
-    var text = element;
-    if (element instanceof Alias) {
-      text = element.getType() + ": " + element.getName();
-    } else if (element instanceof Reaction) {
-      text = "Reaction: " + element.getReactionId();
-    }
-    option.text = text;
-    typeOptions.appendChild(option);
-  }
-  typeOptions.value = 0;
-
-  this._types = types;
-  typeOptions.onchange();
-};
-
-CommentDialog.prototype.getTypes = function () {
-  return this._types;
-};
-
-CommentDialog.prototype.getSelectedType = function () {
-  return this._types[this.getTypeOptions().value];
-};
-
-CommentDialog.prototype.setSelectedType = function (value) {
-  if (Functions.isInt(value)) {
-    this.getTypeOptions().value = value;
-    this.getTypeOptions().onchange();
-  } else {
-    throw new Error("Unknown value type: " + value);
-  }
-};
-
-CommentDialog.prototype.getTypeOptions = function () {
-  return this._typeOptions;
-};
-CommentDialog.prototype.setTypeOptions = function (typeOptions) {
-  this._typeOptions = typeOptions;
-};
-CommentDialog.prototype.setContentInput = function (contentInput) {
-  this._contentInput = contentInput;
-};
-CommentDialog.prototype.getContentInput = function () {
-  return this._contentInput;
-};
-CommentDialog.prototype.setNameInput = function (nameInput) {
-  this._nameInput = nameInput;
-};
-CommentDialog.prototype.getNameInput = function () {
-  return this._nameInput;
-};
-CommentDialog.prototype.setEmailInput = function (emailInput) {
-  this._emailInput = emailInput;
-};
-CommentDialog.prototype.getEmailInput = function () {
-  return this._emailInput;
-};
-CommentDialog.prototype.setPinnedCheckbox = function (pinnedCheckbox) {
-  this._pinnedCheckbox = pinnedCheckbox;
-};
-
-CommentDialog.prototype.getPinnedCheckbox = function () {
-  return this._pinnedCheckbox;
-};
-
-CommentDialog.prototype.getTypes = function () {
-  return this._types;
-};
-
-CommentDialog.prototype.setName = function (name) {
-  this.getNameInput().value = name;
-};
-
-CommentDialog.prototype.getName = function () {
-  return this.getNameInput().value;
-};
-
-CommentDialog.prototype.getEmail = function () {
-  return this.getEmailInput().value;
-};
-
-CommentDialog.prototype.setEmail = function (email) {
-  this.getEmailInput().value = email;
-};
-
-CommentDialog.prototype.getContent = function () {
-  return this.getContentInput().value;
-};
-
-CommentDialog.prototype.isPinned = function () {
-  return this.getPinnedCheckbox().checked;
-};
-CommentDialog.prototype.getSelectedTypeId = function () {
-  var selected = this.getSelectedType();
-  if (selected instanceof Alias) {
-    return selected.getId();
-  } else if (selected instanceof Reaction) {
-    return selected.getId();
-  } else {
-    return "";
-  }
-};
-
-CommentDialog.prototype.getSelectedTypeClass = function () {
-  var selected = this.getSelectedType();
-  if (selected instanceof Alias) {
-    return "ALIAS";
-  } else if (selected instanceof Reaction) {
-    return "REACTION";
-  } else {
-    return "POINT";
-  }
-};
-
-/**
- *
- * @returns {Promise}
- */
-CommentDialog.prototype.addComment = function () {
-  var self = this;
-  var name = self.getName();
-  return self.getMap().getServerConnector().addComment({
-    modelId: self.getMap().getActiveSubmapId(),
-    coordinates: self.getMap().getActiveSubmapClickCoordinates(),
-    name: name,
-    email: self.getEmail(),
-    content: self.getContent(),
-    pinned: self.isPinned(),
-    elementId: self.getSelectedTypeId(),
-    elementType: self.getSelectedTypeClass()
-
-  }).then(function (comment) {
-    //if we visualize comments add it to data set
-    if (self.getMap().getServerConnector().getSessionData(self.getProject()).getShowComments() && comment.isPinned()) {
-      return self.getMap().getOverlayByName("comment").addComment(comment);
-    } else {
-      return [];
-    }
-  });
-};
-
-CommentDialog.prototype.destroy = function () {
-  $(this.getElement()).dialog("destroy");
-};
-
-module.exports = CommentDialog;
+"use strict";
+
+/* exported logger */
+
+var Promise = require("bluebird");
+
+var AbstractGuiElement = require('./AbstractGuiElement');
+var Alias = require('../map/data/Alias');
+var Reaction = require('../map/data/Reaction');
+// noinspection JSUnusedLocalSymbols
+var logger = require('../logger');
+var Functions = require('../Functions');
+
+function CommentDialog(params) {
+  AbstractGuiElement.call(this, params);
+  var self = this;
+  self._createGui();
+  $(self.getElement()).dialog({
+    autoOpen: false,
+    resizable: false,
+    width: window.innerWidth / 2,
+    height: window.innerHeight / 2
+  });
+}
+
+CommentDialog.prototype = Object.create(AbstractGuiElement.prototype);
+CommentDialog.prototype.constructor = CommentDialog;
+
+CommentDialog.GENERAL = "<General>";
+
+function createRow(elements) {
+  var row = document.createElement('tr');
+  for (var i = 0; i < elements.length; i++) {
+    var container = document.createElement('td');
+    container.appendChild(elements[i]);
+    row.appendChild(container);
+  }
+  return row;
+}
+
+CommentDialog.prototype.open = function (identifiedElements) {
+  var self = this;
+  self.setTypes([CommentDialog.GENERAL]);
+
+  var promises = [CommentDialog.GENERAL];
+  for (var i = 0; i < identifiedElements.length; i++) {
+    var ie = identifiedElements[i];
+    if (ie.getType() === "ALIAS") {
+      promises.push(self.getMap().getSubmapById(ie.getModelId()).getModel().getAliasById(ie.getId(), true));
+    } else if (ie.getType() === "REACTION") {
+      promises.push(self.getMap().getSubmapById(ie.getModelId()).getModel().getReactionById(ie.getId(), true));
+    } else {
+      throw new Error("Unknown element type: " + ie.getType());
+    }
+  }
+  return Promise.all(promises).then(function (elements) {
+    self.setTypes(elements);
+    return self.getMap().getServerConnector().getLoggedUser();
+  }).then(function (user) {
+    if (user.getLogin() !== "anonymous") {
+      self.setEmail(user.getEmail());
+      self.setName(user.getName() + " " + user.getSurname());
+    }
+
+    $(self.getElement()).dialog("open");
+  });
+};
+
+CommentDialog.prototype._createGui = function () {
+  var self = this;
+
+  var table = document.createElement('table');
+
+  var typeLabel = document.createElement('label');
+  typeLabel.innerHTML = "Type";
+  var typeOptions = document.createElement("select");
+  this.setTypeOptions(typeOptions);
+
+  table.appendChild(createRow([typeLabel, typeOptions]));
+
+  var detailDiv = document.createElement('div');
+
+  table.appendChild(createRow([document.createElement('div'), detailDiv]));
+
+  var pinnedLabel = document.createElement('label');
+  pinnedLabel.innerHTML = "Pinned";
+  var pinnedCheckbox = document.createElement('input');
+  pinnedCheckbox.type = "checkbox";
+  $(pinnedCheckbox).prop("checked", true);
+
+
+  table.appendChild(createRow([pinnedLabel, pinnedCheckbox]));
+  this.setPinnedCheckbox(pinnedCheckbox);
+
+  var nameLabel = document.createElement('label');
+  nameLabel.innerHTML = "Name:<br/>(Visible to moderators only)";
+  var nameInput = document.createElement('input');
+  nameInput.type = "text";
+
+  table.appendChild(createRow([nameLabel, nameInput]));
+  this.setNameInput(nameInput);
+
+  var emailLabel = document.createElement('label');
+  emailLabel.innerHTML = "Email:<br/>(Visible to moderators only)";
+  var emailInput = document.createElement('input');
+  emailInput.type = "text";
+
+  table.appendChild(createRow([emailLabel, emailInput]));
+  this.setEmailInput(emailInput);
+
+  var contentLabel = document.createElement('label');
+  contentLabel.innerHTML = "Content:";
+  var contentInput = document.createElement('textarea');
+  contentInput.cols = 80;
+  contentInput.rows = 3;
+
+  table.appendChild(createRow([contentLabel, contentInput]));
+  this.setContentInput(contentInput);
+
+  var sendButton = document.createElement('button');
+  sendButton.innerHTML = "Send";
+  sendButton.onclick = function () {
+    return self.addComment().then(function () {
+      $(self.getElement()).dialog("close");
+    });
+  };
+
+  table.appendChild(createRow([sendButton]));
+
+  self.getElement().appendChild(table);
+
+  typeOptions.onchange = function () {
+    var option = self.getSelectedType();
+    var text = "";
+    if (option instanceof Alias) {
+      if (option.getFullName() !== undefined) {
+        text = option.getFullName();
+      }
+    } else if (option instanceof Reaction) {
+      text = "Reactants: ";
+      var reactants = option.getReactants();
+      var i;
+      for (i = 0; i < reactants.length; i++) {
+        text += reactants[i].getAlias().getName() + ",";
+      }
+      text += "<br/>";
+      text += "Modifiers: ";
+      var modifiers = option.getModifiers();
+      for (i = 0; i < modifiers.length; i++) {
+        text += modifiers[i].getAlias().getName() + ",";
+      }
+      text += "<br/>";
+      text += "Products: ";
+      var products = option.getProducts();
+      for (i = 0; i < products.length; i++) {
+        text += products[i].getAlias().getName() + ",";
+      }
+      text += "<br/>";
+    }
+    detailDiv.innerHTML = text;
+  };
+};
+CommentDialog.prototype.setTypes = function (types) {
+  var typeOptions = this.getTypeOptions();
+  while (typeOptions.firstChild) {
+    typeOptions.removeChild(typeOptions.firstChild);
+  }
+
+  for (var i = 0; i < types.length; i++) {
+    var option = document.createElement("option");
+    option.value = i.toString();
+    var element = types[i];
+    var text = element;
+    if (element instanceof Alias) {
+      text = element.getType() + ": " + element.getName();
+    } else if (element instanceof Reaction) {
+      text = "Reaction: " + element.getReactionId();
+    }
+    option.text = text;
+    typeOptions.appendChild(option);
+  }
+  typeOptions.value = 0;
+
+  this._types = types;
+  typeOptions.onchange();
+};
+
+CommentDialog.prototype.getTypes = function () {
+  return this._types;
+};
+
+CommentDialog.prototype.getSelectedType = function () {
+  return this._types[this.getTypeOptions().value];
+};
+
+CommentDialog.prototype.setSelectedType = function (value) {
+  if (Functions.isInt(value)) {
+    this.getTypeOptions().value = value;
+    this.getTypeOptions().onchange();
+  } else {
+    throw new Error("Unknown value type: " + value);
+  }
+};
+
+CommentDialog.prototype.getTypeOptions = function () {
+  return this._typeOptions;
+};
+CommentDialog.prototype.setTypeOptions = function (typeOptions) {
+  this._typeOptions = typeOptions;
+};
+CommentDialog.prototype.setContentInput = function (contentInput) {
+  this._contentInput = contentInput;
+};
+CommentDialog.prototype.getContentInput = function () {
+  return this._contentInput;
+};
+CommentDialog.prototype.setNameInput = function (nameInput) {
+  this._nameInput = nameInput;
+};
+CommentDialog.prototype.getNameInput = function () {
+  return this._nameInput;
+};
+CommentDialog.prototype.setEmailInput = function (emailInput) {
+  this._emailInput = emailInput;
+};
+CommentDialog.prototype.getEmailInput = function () {
+  return this._emailInput;
+};
+CommentDialog.prototype.setPinnedCheckbox = function (pinnedCheckbox) {
+  this._pinnedCheckbox = pinnedCheckbox;
+};
+
+CommentDialog.prototype.getPinnedCheckbox = function () {
+  return this._pinnedCheckbox;
+};
+
+CommentDialog.prototype.getTypes = function () {
+  return this._types;
+};
+
+CommentDialog.prototype.setName = function (name) {
+  this.getNameInput().value = name;
+};
+
+CommentDialog.prototype.getName = function () {
+  return this.getNameInput().value;
+};
+
+CommentDialog.prototype.getEmail = function () {
+  return this.getEmailInput().value;
+};
+
+CommentDialog.prototype.setEmail = function (email) {
+  this.getEmailInput().value = email;
+};
+
+CommentDialog.prototype.getContent = function () {
+  return this.getContentInput().value;
+};
+
+CommentDialog.prototype.isPinned = function () {
+  return this.getPinnedCheckbox().checked;
+};
+CommentDialog.prototype.getSelectedTypeId = function () {
+  var selected = this.getSelectedType();
+  if (selected instanceof Alias) {
+    return selected.getId();
+  } else if (selected instanceof Reaction) {
+    return selected.getId();
+  } else {
+    return "";
+  }
+};
+
+CommentDialog.prototype.getSelectedTypeClass = function () {
+  var selected = this.getSelectedType();
+  if (selected instanceof Alias) {
+    return "ALIAS";
+  } else if (selected instanceof Reaction) {
+    return "REACTION";
+  } else {
+    return "POINT";
+  }
+};
+
+/**
+ *
+ * @returns {Promise}
+ */
+CommentDialog.prototype.addComment = function () {
+  var self = this;
+  var name = self.getName();
+  return self.getMap().getServerConnector().addComment({
+    modelId: self.getMap().getActiveSubmapId(),
+    coordinates: self.getMap().getActiveSubmapClickCoordinates(),
+    name: name,
+    email: self.getEmail(),
+    content: self.getContent(),
+    pinned: self.isPinned(),
+    elementId: self.getSelectedTypeId(),
+    elementType: self.getSelectedTypeClass()
+
+  }).then(function (comment) {
+    //if we visualize comments add it to data set
+    if (self.getMap().getServerConnector().getSessionData(self.getProject()).getShowComments() && comment.isPinned()) {
+      return self.getMap().getOverlayByName("comment").addComment(comment);
+    } else {
+      return [];
+    }
+  });
+};
+
+CommentDialog.prototype.destroy = function () {
+  $(this.getElement()).dialog("destroy");
+};
+
+module.exports = CommentDialog;
diff --git a/frontend-js/src/main/js/gui/ContextMenu.js b/frontend-js/src/main/js/gui/ContextMenu.js
index 4425389f9262e500fa09bfd28be684a93915eaeb..f8fdbc8c05402036cebddda660905089440a7cb2 100644
--- a/frontend-js/src/main/js/gui/ContextMenu.js
+++ b/frontend-js/src/main/js/gui/ContextMenu.js
@@ -1,196 +1,196 @@
-"use strict";
-
-/* exported logger */
-
-var AbstractGuiElement = require('./AbstractGuiElement');
-var GuiConnector = require('../GuiConnector');
-var SubMenu = require('./SubMenu');
-
-var Functions = require('../Functions');
-
-var logger = require('../logger');
-
-var MARGIN = 5;
-
-function ContextMenu(params) {
-  AbstractGuiElement.call(this, params);
-  var self = this;
-
-  var element = self.getElement();
-  element.className = "dropdown-menu";
-  element.setAttribute("role", "menu");
-  $(element).hide();
-
-  self._handledTimeStamp = undefined;
-
-  self.MIN_SHOW_TIME = 250;
-
-  self._documentClickListener = function (e) {
-    var className = e.target.className;
-    if (typeof className === 'string' || className instanceof String) {
-      if (className.indexOf("dropdown-link") === -1) {
-        self.hide(new Date().getTime() - self.MIN_SHOW_TIME);
-      }
-    } else {
-      self.hide(new Date().getTime() - self.MIN_SHOW_TIME);
-    }
-  };
-  $(document).on('click', self._documentClickListener);
-  $(document).on('touchstart', self._documentClickListener);
-}
-
-ContextMenu.prototype = Object.create(AbstractGuiElement.prototype);
-ContextMenu.prototype.constructor = ContextMenu;
-
-ContextMenu.prototype.destroy = function () {
-  var self = this;
-  $(document).off('click', self._documentClickListener);
-  $(document).off('touchstart', self._documentClickListener);
-};
-
-ContextMenu.prototype.addOption = function (name, handler, disabled) {
-  if (!disabled) disabled = false;
-  var self = this;
-  if (name instanceof SubMenu) {
-    self.getElement().appendChild(name.getElement());
-  } else {
-    var option = Functions.createElement({
-      type: "li"
-    });
-    var link = Functions.createElement({
-      type: "a",
-      className: "dropdown-link",
-      content: name
-    });
-    if (!disabled) {
-      link.href = "#";
-    } else {
-      link.className = 'disabled-link';
-    }
-    $(link).data("handler", handler);
-    option.appendChild(link);
-    self.getElement().appendChild(option);
-  }
-};
-
-/**
- *
- * @param {number} x
- * @param {number} y
- * @param {number} timestamp
- */
-ContextMenu.prototype.open = function (x, y, timestamp) {
-  var self = this;
-  self._handledTimeStamp = timestamp;
-
-  var left = x;
-  var right = "";
-
-  if ($(self.getElement()).width() + x + MARGIN > $(document).width()) {
-    left = Math.max(0, $(document).width() - $(self.getElement()).width() - MARGIN);
-    right = 0;
-  }
-
-  $(self.getElement()).show().css({
-    position: "absolute",
-    left: left,
-    right: right,
-    top: y
-  }).off('click').on('click', 'a', function (e) {
-    //close if this is not a submenu
-    if (this.parentNode === undefined || this.parentNode.className.indexOf("dropdown-submenu") === -1) {
-      self.hide(new Date().getTime());
-      if ($(this).data("handler") !== undefined) {
-        return $(this).data("handler")();
-      } else {
-        logger.debug("Nothing to do");
-      }
-    }
-  });
-};
-
-ContextMenu.prototype.hide = function (timestamp) {
-  var self = this;
-  if (self._handledTimeStamp < timestamp) {
-    self._handledTimeStamp = timestamp;
-    $(this.getElement()).hide();
-  }
-};
-
-function extractDataOverlayIds(dataOverlays) {
-  var ids = [];
-  for (var i = 0; i < dataOverlays.length; i++) {
-    ids.push(dataOverlays[i].getId());
-  }
-  return ids;
-}
-
-ContextMenu.prototype.createExportAsImageSubmenu = function () {
-  var self = this;
-  return self.getMap().getServerConnector().getImageConverters().then(function (converters) {
-    var li = Functions.createElement({
-      type: "li"
-    });
-    var submenu = new SubMenu({
-      element: li,
-      name: "Export as image",
-      customMap: self.getMap()
-    });
-
-    var map = self.getMap();
-    converters.forEach(function (converter) {
-      submenu.addOption(converter.name, function () {
-        return map.getVisibleDataOverlays().then(function (visibleDataOverlays) {
-          var submapId = map.getActiveSubmapId();
-
-          return map.getServerConnector().getImageDownloadUrl({
-            polygonString: map.getSelectedPolygon(),
-            modelId: submapId,
-            handlerClass: converter.handler,
-            backgroundOverlayId: map.getBackgroundDataOverlay().getId(),
-            zoomLevel: map.getSubmapById(submapId).getZoom(),
-            overlayIds: extractDataOverlayIds(visibleDataOverlays)
-          });
-        }).then(function (url) {
-          return self.downloadFile(url);
-        }).catch(GuiConnector.alert);
-      });
-    });
-    return submenu;
-  });
-};
-
-ContextMenu.prototype.createExportAsModelSubmenu = function () {
-  var self = this;
-  return self.getMap().getServerConnector().getModelConverters().then(function (converters) {
-    var li = Functions.createElement({
-      type: "li"
-    });
-    var submenu = new SubMenu({
-      element: li,
-      name: "Export as map",
-      customMap: self.getMap()
-    });
-
-    var map = self.getMap();
-    converters.forEach(function (converter) {
-      submenu.addOption(converter.name, function () {
-        return map.getVisibleDataOverlays().then(function (visibleDataOverlays) {
-          return map.getServerConnector().getModelDownloadUrl({
-            polygonString: map.getSelectedPolygon(),
-            modelId: map.getActiveSubmapId(),
-            handlerClass: converter.handler,
-            backgroundOverlayId: map.getBackgroundDataOverlay().getId(),
-            zoomLevel: map.getZoom(),
-            overlayIds: extractDataOverlayIds(visibleDataOverlays)
-          });
-        }).then(function (url) {
-          return self.downloadFile(url);
-        }).catch(GuiConnector.alert);
-      });
-    });
-    return submenu;
-  });
-};
-
-module.exports = ContextMenu;
+"use strict";
+
+/* exported logger */
+
+var AbstractGuiElement = require('./AbstractGuiElement');
+var GuiConnector = require('../GuiConnector');
+var SubMenu = require('./SubMenu');
+
+var Functions = require('../Functions');
+
+var logger = require('../logger');
+
+var MARGIN = 5;
+
+function ContextMenu(params) {
+  AbstractGuiElement.call(this, params);
+  var self = this;
+
+  var element = self.getElement();
+  element.className = "dropdown-menu";
+  element.setAttribute("role", "menu");
+  $(element).hide();
+
+  self._handledTimeStamp = undefined;
+
+  self.MIN_SHOW_TIME = 250;
+
+  self._documentClickListener = function (e) {
+    var className = e.target.className;
+    if (typeof className === 'string' || className instanceof String) {
+      if (className.indexOf("dropdown-link") === -1) {
+        self.hide(new Date().getTime() - self.MIN_SHOW_TIME);
+      }
+    } else {
+      self.hide(new Date().getTime() - self.MIN_SHOW_TIME);
+    }
+  };
+  $(document).on('click', self._documentClickListener);
+  $(document).on('touchstart', self._documentClickListener);
+}
+
+ContextMenu.prototype = Object.create(AbstractGuiElement.prototype);
+ContextMenu.prototype.constructor = ContextMenu;
+
+ContextMenu.prototype.destroy = function () {
+  var self = this;
+  $(document).off('click', self._documentClickListener);
+  $(document).off('touchstart', self._documentClickListener);
+};
+
+ContextMenu.prototype.addOption = function (name, handler, disabled) {
+  if (!disabled) disabled = false;
+  var self = this;
+  if (name instanceof SubMenu) {
+    self.getElement().appendChild(name.getElement());
+  } else {
+    var option = Functions.createElement({
+      type: "li"
+    });
+    var link = Functions.createElement({
+      type: "a",
+      className: "dropdown-link",
+      content: name
+    });
+    if (!disabled) {
+      link.href = "#";
+    } else {
+      link.className = 'disabled-link';
+    }
+    $(link).data("handler", handler);
+    option.appendChild(link);
+    self.getElement().appendChild(option);
+  }
+};
+
+/**
+ *
+ * @param {number} x
+ * @param {number} y
+ * @param {number} timestamp
+ */
+ContextMenu.prototype.open = function (x, y, timestamp) {
+  var self = this;
+  self._handledTimeStamp = timestamp;
+
+  var left = x;
+  var right = "";
+
+  if ($(self.getElement()).width() + x + MARGIN > $(document).width()) {
+    left = Math.max(0, $(document).width() - $(self.getElement()).width() - MARGIN);
+    right = 0;
+  }
+
+  $(self.getElement()).show().css({
+    position: "absolute",
+    left: left,
+    right: right,
+    top: y
+  }).off('click').on('click', 'a', function (e) {
+    //close if this is not a submenu
+    if (this.parentNode === undefined || this.parentNode.className.indexOf("dropdown-submenu") === -1) {
+      self.hide(new Date().getTime());
+      if ($(this).data("handler") !== undefined) {
+        return $(this).data("handler")();
+      } else {
+        logger.debug("Nothing to do");
+      }
+    }
+  });
+};
+
+ContextMenu.prototype.hide = function (timestamp) {
+  var self = this;
+  if (self._handledTimeStamp < timestamp) {
+    self._handledTimeStamp = timestamp;
+    $(this.getElement()).hide();
+  }
+};
+
+function extractDataOverlayIds(dataOverlays) {
+  var ids = [];
+  for (var i = 0; i < dataOverlays.length; i++) {
+    ids.push(dataOverlays[i].getId());
+  }
+  return ids;
+}
+
+ContextMenu.prototype.createExportAsImageSubmenu = function () {
+  var self = this;
+  return self.getMap().getServerConnector().getImageConverters().then(function (converters) {
+    var li = Functions.createElement({
+      type: "li"
+    });
+    var submenu = new SubMenu({
+      element: li,
+      name: "Export as image",
+      customMap: self.getMap()
+    });
+
+    var map = self.getMap();
+    converters.forEach(function (converter) {
+      submenu.addOption(converter.name, function () {
+        return map.getVisibleDataOverlays().then(function (visibleDataOverlays) {
+          var submapId = map.getActiveSubmapId();
+
+          return map.getServerConnector().getImageDownloadUrl({
+            polygonString: map.getSelectedPolygon(),
+            modelId: submapId,
+            handlerClass: converter.handler,
+            backgroundOverlayId: map.getBackgroundDataOverlay().getId(),
+            zoomLevel: map.getSubmapById(submapId).getZoom(),
+            overlayIds: extractDataOverlayIds(visibleDataOverlays)
+          });
+        }).then(function (url) {
+          return self.downloadFile(url);
+        }).catch(GuiConnector.alert);
+      });
+    });
+    return submenu;
+  });
+};
+
+ContextMenu.prototype.createExportAsModelSubmenu = function () {
+  var self = this;
+  return self.getMap().getServerConnector().getModelConverters().then(function (converters) {
+    var li = Functions.createElement({
+      type: "li"
+    });
+    var submenu = new SubMenu({
+      element: li,
+      name: "Export as map",
+      customMap: self.getMap()
+    });
+
+    var map = self.getMap();
+    converters.forEach(function (converter) {
+      submenu.addOption(converter.name, function () {
+        return map.getVisibleDataOverlays().then(function (visibleDataOverlays) {
+          return map.getServerConnector().getModelDownloadUrl({
+            polygonString: map.getSelectedPolygon(),
+            modelId: map.getActiveSubmapId(),
+            handlerClass: converter.handler,
+            backgroundOverlayId: map.getBackgroundDataOverlay().getId(),
+            zoomLevel: map.getZoom(),
+            overlayIds: extractDataOverlayIds(visibleDataOverlays)
+          });
+        }).then(function (url) {
+          return self.downloadFile(url);
+        }).catch(GuiConnector.alert);
+      });
+    });
+    return submenu;
+  });
+};
+
+module.exports = ContextMenu;
diff --git a/frontend-js/src/main/js/gui/GuiMessageError.js b/frontend-js/src/main/js/gui/GuiMessageError.js
index 52ccf03be23abafbcad02be87411e6aeea94734d..9cb6b8367a053c84f8e685288bb47fb4b845b033 100644
--- a/frontend-js/src/main/js/gui/GuiMessageError.js
+++ b/frontend-js/src/main/js/gui/GuiMessageError.js
@@ -1,15 +1,15 @@
-"use strict";
-
-/* exported logger */
-
-var logger = require('../logger');
-
-function GuiMessageError(message) {
-  this.message = message;
-  this.stack = (new Error()).stack;
-}
-
-GuiMessageError.prototype = Object.create(Error.prototype);
-GuiMessageError.prototype.constructor = GuiMessageError;
-
-module.exports = GuiMessageError;
+"use strict";
+
+/* exported logger */
+
+var logger = require('../logger');
+
+function GuiMessageError(message) {
+  this.message = message;
+  this.stack = (new Error()).stack;
+}
+
+GuiMessageError.prototype = Object.create(Error.prototype);
+GuiMessageError.prototype.constructor = GuiMessageError;
+
+module.exports = GuiMessageError;
diff --git a/frontend-js/src/main/js/gui/Header.js b/frontend-js/src/main/js/gui/Header.js
index 384ac53da084fc69117b7de30dde46a54037a272..2e2eeab613db1a7d42d0b1175a644ae73bc05a99 100644
--- a/frontend-js/src/main/js/gui/Header.js
+++ b/frontend-js/src/main/js/gui/Header.js
@@ -1,169 +1,169 @@
-"use strict";
-
-/* exported logger */
-
-var AbstractGuiElement = require('./AbstractGuiElement');
-var GuiConnector = require('../GuiConnector');
-var PanelControlElementType = require('./PanelControlElementType');
-var Functions = require('../Functions');
-var OptionsMenu = require('./OptionsMenu');
-
-var Promise = require("bluebird");
-
-var logger = require('../logger');
-var xss = require('xss');
-
-function Header(params) {
-  AbstractGuiElement.call(this, params);
-  var self = this;
-
-  var guiParams = {
-    adminLink: true,
-    optionsMenu: params.optionsMenu
-  };
-  if (params.adminLink !== undefined) {
-    guiParams.adminLink = params.adminLink;
-  }
-
-  self._createHeaderGui(guiParams);
-}
-
-Header.prototype = Object.create(AbstractGuiElement.prototype);
-Header.prototype.constructor = Header;
-
-Header.prototype._createHeaderGui = function (guiParams) {
-  var self = this;
-  self.getElement().className = "minerva-header";
-
-  var projectId = self.getProject().getProjectId();
-  var projectName = xss(self.getProject().getName());
-
-  var loadingDiv = Functions.createElement({
-    type: "div",
-    style: "display:none; "
-  });
-  loadingDiv.style.float = "right";
-
-  var loadingImg = Functions.createElement({
-    type: "img",
-    src: 'resources/images/icons/ajax-loader.gif'
-  });
-  loadingImg.style.height = "35px";
-  loadingDiv.appendChild(loadingImg);
-  this.setControlElement(PanelControlElementType.FOOTER_LOADING_DIV, loadingDiv);
-
-  if (guiParams.adminLink) {
-    var link = Functions.createElement({
-      type: "a",
-      style: "padding-right:15px; float:right",
-      content: '<i class="fa fa-lock" style="font-size:17px"></i>&nbsp;',
-      xss: false
-    });
-    link.href = ServerConnector.getServerBaseUrl() + "admin.xhtml?id=" + projectId;
-    self.getElement().appendChild(link);
-  }
-
-  if (guiParams.optionsMenu) {
-    var optionsElement = Functions.createElement({type: "ul"});
-    document.body.appendChild(optionsElement);
-    self._optionsMenu = new OptionsMenu({
-      customMap: self.getMap(),
-      element: optionsElement
-    });
-
-    var menuLink = Functions.createElement({
-      type: "a",
-      style: "padding-right:5px; float:right",
-      content: '<i class="fa fa-bars" style="font-size:17px"></i>&nbsp;',
-      href: "#",
-      onclick: function (e) {
-        var link = $(menuLink);
-        var offset = link.offset();
-
-        var top = offset.top;
-        var left = offset.left;
-
-        var bottom = top + link.outerHeight();
-
-        return self._optionsMenu.open(left, bottom, new Date().getTime());
-      },
-      xss: false
-    });
-    self.getElement().appendChild(menuLink);
-  }
-
-  self.getElement().appendChild(loadingDiv);
-
-  var homeLink = Functions.createElement({
-    type: "a",
-    content: '<i class="fa fa-home" style="font-size:17px"></i> ' + projectName,
-    xss: false
-  });
-  homeLink.href = ServerConnector.getServerBaseUrl() + "?id=" + projectId;
-  self.getElement().appendChild(homeLink);
-};
-
-Header.prototype.addLoadMessage = function (message) {
-  var self = this;
-  self._loadMessages.push(message);
-};
-Header.prototype.removeLoadMessage = function (message) {
-  var self = this;
-  var index = self._loadMessages.indexOf(message);
-  if (index > -1) {
-    self._loadMessages.splice(index, 1);
-  } else {
-    logger.debug("Removing message that is not there: " + message);
-  }
-};
-
-Header.prototype.init = function () {
-  var self = this;
-  return new Promise(function (resolve) {
-    var div = self.getControlElement(PanelControlElementType.FOOTER_LOADING_DIV);
-
-    self._loadMessages = [];
-    self._onDataLoadStart = function (e) {
-      self.addLoadMessage(e.arg);
-      div.style.display = "block";
-      div.title = e.arg;
-    };
-
-    self._onDataLoadStop = function (e) {
-      self.removeLoadMessage(e.arg);
-      if (self._loadMessages.length > 0) {
-        div.title = self._loadMessages[0];
-      } else {
-        div.style.display = "none";
-      }
-    };
-    ServerConnector.addListener("onDataLoadStart", self._onDataLoadStart);
-    ServerConnector.addListener("onDataLoadStop", self._onDataLoadStop);
-    resolve();
-  });
-};
-
-Header.prototype.destroy = function () {
-  var self = this;
-  if (self._onDataLoadStart) {
-    ServerConnector.removeListener("onDataLoadStart", self._onDataLoadStart);
-    ServerConnector.removeListener("onDataLoadStop", self._onDataLoadStop);
-  }
-  if (self._optionsMenu !== undefined) {
-    document.body.removeChild(self._optionsMenu.getElement());
-  }
-};
-
-Header.prototype.setPluginManager = function (pluginManager) {
-  var self = this;
-  self._pluginManager = pluginManager;
-  if (self._optionsMenu !== undefined) {
-    self._optionsMenu.setPluginManager(pluginManager);
-  }
-};
-
-Header.prototype.getPluginManager = function () {
-  return this._pluginManager;
-};
-
-module.exports = Header;
+"use strict";
+
+/* exported logger */
+
+var AbstractGuiElement = require('./AbstractGuiElement');
+var GuiConnector = require('../GuiConnector');
+var PanelControlElementType = require('./PanelControlElementType');
+var Functions = require('../Functions');
+var OptionsMenu = require('./OptionsMenu');
+
+var Promise = require("bluebird");
+
+var logger = require('../logger');
+var xss = require('xss');
+
+function Header(params) {
+  AbstractGuiElement.call(this, params);
+  var self = this;
+
+  var guiParams = {
+    adminLink: true,
+    optionsMenu: params.optionsMenu
+  };
+  if (params.adminLink !== undefined) {
+    guiParams.adminLink = params.adminLink;
+  }
+
+  self._createHeaderGui(guiParams);
+}
+
+Header.prototype = Object.create(AbstractGuiElement.prototype);
+Header.prototype.constructor = Header;
+
+Header.prototype._createHeaderGui = function (guiParams) {
+  var self = this;
+  self.getElement().className = "minerva-header";
+
+  var projectId = self.getProject().getProjectId();
+  var projectName = xss(self.getProject().getName());
+
+  var loadingDiv = Functions.createElement({
+    type: "div",
+    style: "display:none; "
+  });
+  loadingDiv.style.float = "right";
+
+  var loadingImg = Functions.createElement({
+    type: "img",
+    src: 'resources/images/icons/ajax-loader.gif'
+  });
+  loadingImg.style.height = "35px";
+  loadingDiv.appendChild(loadingImg);
+  this.setControlElement(PanelControlElementType.FOOTER_LOADING_DIV, loadingDiv);
+
+  if (guiParams.adminLink) {
+    var link = Functions.createElement({
+      type: "a",
+      style: "padding-right:15px; float:right",
+      content: '<i class="fa fa-lock" style="font-size:17px"></i>&nbsp;',
+      xss: false
+    });
+    link.href = ServerConnector.getServerBaseUrl() + "admin.xhtml?id=" + projectId;
+    self.getElement().appendChild(link);
+  }
+
+  if (guiParams.optionsMenu) {
+    var optionsElement = Functions.createElement({type: "ul"});
+    document.body.appendChild(optionsElement);
+    self._optionsMenu = new OptionsMenu({
+      customMap: self.getMap(),
+      element: optionsElement
+    });
+
+    var menuLink = Functions.createElement({
+      type: "a",
+      style: "padding-right:5px; float:right",
+      content: '<i class="fa fa-bars" style="font-size:17px"></i>&nbsp;',
+      href: "#",
+      onclick: function (e) {
+        var link = $(menuLink);
+        var offset = link.offset();
+
+        var top = offset.top;
+        var left = offset.left;
+
+        var bottom = top + link.outerHeight();
+
+        return self._optionsMenu.open(left, bottom, new Date().getTime());
+      },
+      xss: false
+    });
+    self.getElement().appendChild(menuLink);
+  }
+
+  self.getElement().appendChild(loadingDiv);
+
+  var homeLink = Functions.createElement({
+    type: "a",
+    content: '<i class="fa fa-home" style="font-size:17px"></i> ' + projectName,
+    xss: false
+  });
+  homeLink.href = ServerConnector.getServerBaseUrl() + "?id=" + projectId;
+  self.getElement().appendChild(homeLink);
+};
+
+Header.prototype.addLoadMessage = function (message) {
+  var self = this;
+  self._loadMessages.push(message);
+};
+Header.prototype.removeLoadMessage = function (message) {
+  var self = this;
+  var index = self._loadMessages.indexOf(message);
+  if (index > -1) {
+    self._loadMessages.splice(index, 1);
+  } else {
+    logger.debug("Removing message that is not there: " + message);
+  }
+};
+
+Header.prototype.init = function () {
+  var self = this;
+  return new Promise(function (resolve) {
+    var div = self.getControlElement(PanelControlElementType.FOOTER_LOADING_DIV);
+
+    self._loadMessages = [];
+    self._onDataLoadStart = function (e) {
+      self.addLoadMessage(e.arg);
+      div.style.display = "block";
+      div.title = e.arg;
+    };
+
+    self._onDataLoadStop = function (e) {
+      self.removeLoadMessage(e.arg);
+      if (self._loadMessages.length > 0) {
+        div.title = self._loadMessages[0];
+      } else {
+        div.style.display = "none";
+      }
+    };
+    ServerConnector.addListener("onDataLoadStart", self._onDataLoadStart);
+    ServerConnector.addListener("onDataLoadStop", self._onDataLoadStop);
+    resolve();
+  });
+};
+
+Header.prototype.destroy = function () {
+  var self = this;
+  if (self._onDataLoadStart) {
+    ServerConnector.removeListener("onDataLoadStart", self._onDataLoadStart);
+    ServerConnector.removeListener("onDataLoadStop", self._onDataLoadStop);
+  }
+  if (self._optionsMenu !== undefined) {
+    document.body.removeChild(self._optionsMenu.getElement());
+  }
+};
+
+Header.prototype.setPluginManager = function (pluginManager) {
+  var self = this;
+  self._pluginManager = pluginManager;
+  if (self._optionsMenu !== undefined) {
+    self._optionsMenu.setPluginManager(pluginManager);
+  }
+};
+
+Header.prototype.getPluginManager = function () {
+  return this._pluginManager;
+};
+
+module.exports = Header;
diff --git a/frontend-js/src/main/js/gui/Legend.js b/frontend-js/src/main/js/gui/Legend.js
index 1dad46e65334a2e339966306c741dcb0feb3d55a..be280e82258b54357bdafd661e31af2a5d982a27 100644
--- a/frontend-js/src/main/js/gui/Legend.js
+++ b/frontend-js/src/main/js/gui/Legend.js
@@ -1,151 +1,151 @@
-"use strict";
-
-var AbstractGuiElement = require('./AbstractGuiElement');
-var ConfigurationType = require('../ConfigurationType');
-var Functions = require('../Functions');
-var PanelControlElementType = require('./PanelControlElementType');
-
-// noinspection JSUnusedLocalSymbols
-var logger = require('../logger');
-
-function Legend(params) {
-  AbstractGuiElement.call(this, params);
-
-  this._initializeGui();
-}
-
-Legend.prototype = Object.create(AbstractGuiElement.prototype);
-Legend.prototype.constructor = Legend;
-
-Legend.prototype._initializeGui = function () {
-  var self = this;
-
-  var legendDiv = Functions.createElement({
-    type: "div",
-    id: "legend-div",
-    className: "carousel slide"
-  });
-  self.getElement().appendChild(legendDiv);
-
-  var indicators = Functions.createElement({
-    type: "ol",
-    name: "indicators",
-    className: "carousel-indicators"
-  });
-  legendDiv.appendChild(indicators);
-  self.setControlElement(PanelControlElementType.LEGEND_INDICATORS_OL, indicators);
-
-  var slidesDiv = Functions.createElement({
-    type: "div",
-    name: "slides",
-    className: "carousel-inner",
-    role: "listbox"
-  });
-  legendDiv.appendChild(slidesDiv);
-  self.setControlElement(PanelControlElementType.LEGEND_SLIDES_DIV, slidesDiv);
-
-  var leftButton = Functions
-    .createElement({
-      type: "a",
-      className: "left carousel-control",
-      role: "button",
-      href: "#legend-div",
-      content: '<span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span><span class="sr-only">Previous</span>',
-      xss: false
-    });
-  leftButton.setAttribute("data-slide", "prev");
-  legendDiv.appendChild(leftButton);
-
-  var rightButton = Functions
-    .createElement({
-      type: "a",
-      className: "right carousel-control",
-      role: "button",
-      href: "#legend-div",
-      content: '<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span><span class="sr-only">Next</span>',
-      xss: false
-    });
-  rightButton.setAttribute("data-slide", "next");
-  legendDiv.appendChild(rightButton);
-};
-
-Legend.prototype.hide = function () {
-  this.getElement().style.display = "none";
-};
-Legend.prototype.show = function () {
-  var maxZIndex = Math.max.apply(null,
-    $.map($('body *'), function (e) {
-      if ($(e).css('position') !== 'static') {
-        return parseInt($(e).css('z-index')) || 1;
-      }
-    }));
-
-  this.getElement().style.display = "block";
-  $(this.getElement()).css('z-index', maxZIndex + 1);
-};
-
-function createLegendIndicator(file, index) {
-  var result = document.createElement("li");
-  result.setAttribute("data-target", "legend");
-  result.setAttribute("data-slide-to", "" + index);
-  if (index === 0) {
-    result.className = "active";
-  }
-  return result;
-}
-
-function createLegendSlide(file, index) {
-  var result = document.createElement("div");
-  if (index === 0) {
-    result.className = "item active";
-  } else {
-    result.className = "item";
-  }
-  var img = document.createElement("img");
-  img.src = file.getValue();
-  result.appendChild(img);
-  return result;
-}
-
-function getValidLegendFiles(legendFiles) {
-  var result = [];
-
-  var promises = [];
-  legendFiles.forEach(function (file) {
-    result.push(file);
-    var url = file.getValue();
-    if (url.indexOf("http") !== 0 && "" !== url) {
-      url = ServerConnector.getServerBaseUrl() + url;
-    }
-    promises.push(ServerConnector.sendGetRequest(url).catch(function (error) {
-      var index = result.indexOf(file);
-      if (index > -1) {
-        result.splice(index, 1);
-      }
-    }));
-  });
-
-  return Promise.all(promises).then(function () {
-    return result;
-  });
-}
-
-Legend.prototype.init = function () {
-  var self = this;
-  var element = self.getElement();
-  var menu = self.getControlElement(PanelControlElementType.LEGEND_INDICATORS_OL);
-  var slides = self.getControlElement(PanelControlElementType.LEGEND_SLIDES_DIV);
-  return ServerConnector.getConfigurationParam(ConfigurationType.LEGEND_FILES).then(function (legendFiles) {
-    return getValidLegendFiles(legendFiles);
-  }).then(function (legendFiles) {
-    for (var i = 0; i < legendFiles.length; i++) {
-      var legendFile = legendFiles[i];
-      menu.appendChild(createLegendIndicator(legendFile, i));
-      slides.appendChild(createLegendSlide(legendFile, i));
-    }
-    $(element).carousel();
-  });
-
-};
-
-module.exports = Legend;
+"use strict";
+
+var AbstractGuiElement = require('./AbstractGuiElement');
+var ConfigurationType = require('../ConfigurationType');
+var Functions = require('../Functions');
+var PanelControlElementType = require('./PanelControlElementType');
+
+// noinspection JSUnusedLocalSymbols
+var logger = require('../logger');
+
+function Legend(params) {
+  AbstractGuiElement.call(this, params);
+
+  this._initializeGui();
+}
+
+Legend.prototype = Object.create(AbstractGuiElement.prototype);
+Legend.prototype.constructor = Legend;
+
+Legend.prototype._initializeGui = function () {
+  var self = this;
+
+  var legendDiv = Functions.createElement({
+    type: "div",
+    id: "legend-div",
+    className: "carousel slide"
+  });
+  self.getElement().appendChild(legendDiv);
+
+  var indicators = Functions.createElement({
+    type: "ol",
+    name: "indicators",
+    className: "carousel-indicators"
+  });
+  legendDiv.appendChild(indicators);
+  self.setControlElement(PanelControlElementType.LEGEND_INDICATORS_OL, indicators);
+
+  var slidesDiv = Functions.createElement({
+    type: "div",
+    name: "slides",
+    className: "carousel-inner",
+    role: "listbox"
+  });
+  legendDiv.appendChild(slidesDiv);
+  self.setControlElement(PanelControlElementType.LEGEND_SLIDES_DIV, slidesDiv);
+
+  var leftButton = Functions
+    .createElement({
+      type: "a",
+      className: "left carousel-control",
+      role: "button",
+      href: "#legend-div",
+      content: '<span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span><span class="sr-only">Previous</span>',
+      xss: false
+    });
+  leftButton.setAttribute("data-slide", "prev");
+  legendDiv.appendChild(leftButton);
+
+  var rightButton = Functions
+    .createElement({
+      type: "a",
+      className: "right carousel-control",
+      role: "button",
+      href: "#legend-div",
+      content: '<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span><span class="sr-only">Next</span>',
+      xss: false
+    });
+  rightButton.setAttribute("data-slide", "next");
+  legendDiv.appendChild(rightButton);
+};
+
+Legend.prototype.hide = function () {
+  this.getElement().style.display = "none";
+};
+Legend.prototype.show = function () {
+  var maxZIndex = Math.max.apply(null,
+    $.map($('body *'), function (e) {
+      if ($(e).css('position') !== 'static') {
+        return parseInt($(e).css('z-index')) || 1;
+      }
+    }));
+
+  this.getElement().style.display = "block";
+  $(this.getElement()).css('z-index', maxZIndex + 1);
+};
+
+function createLegendIndicator(file, index) {
+  var result = document.createElement("li");
+  result.setAttribute("data-target", "legend");
+  result.setAttribute("data-slide-to", "" + index);
+  if (index === 0) {
+    result.className = "active";
+  }
+  return result;
+}
+
+function createLegendSlide(file, index) {
+  var result = document.createElement("div");
+  if (index === 0) {
+    result.className = "item active";
+  } else {
+    result.className = "item";
+  }
+  var img = document.createElement("img");
+  img.src = file.getValue();
+  result.appendChild(img);
+  return result;
+}
+
+function getValidLegendFiles(legendFiles) {
+  var result = [];
+
+  var promises = [];
+  legendFiles.forEach(function (file) {
+    result.push(file);
+    var url = file.getValue();
+    if (url.indexOf("http") !== 0 && "" !== url) {
+      url = ServerConnector.getServerBaseUrl() + url;
+    }
+    promises.push(ServerConnector.sendGetRequest(url).catch(function (error) {
+      var index = result.indexOf(file);
+      if (index > -1) {
+        result.splice(index, 1);
+      }
+    }));
+  });
+
+  return Promise.all(promises).then(function () {
+    return result;
+  });
+}
+
+Legend.prototype.init = function () {
+  var self = this;
+  var element = self.getElement();
+  var menu = self.getControlElement(PanelControlElementType.LEGEND_INDICATORS_OL);
+  var slides = self.getControlElement(PanelControlElementType.LEGEND_SLIDES_DIV);
+  return ServerConnector.getConfigurationParam(ConfigurationType.LEGEND_FILES).then(function (legendFiles) {
+    return getValidLegendFiles(legendFiles);
+  }).then(function (legendFiles) {
+    for (var i = 0; i < legendFiles.length; i++) {
+      var legendFile = legendFiles[i];
+      menu.appendChild(createLegendIndicator(legendFile, i));
+      slides.appendChild(createLegendSlide(legendFile, i));
+    }
+    $(element).carousel();
+  });
+
+};
+
+module.exports = Legend;
diff --git a/frontend-js/src/main/js/gui/LoginDialog.js b/frontend-js/src/main/js/gui/LoginDialog.js
index 7a652643d9157fc10d709381730bf9c0c7989d75..a32a49e44fc012a54414433380dca59124efa06e 100644
--- a/frontend-js/src/main/js/gui/LoginDialog.js
+++ b/frontend-js/src/main/js/gui/LoginDialog.js
@@ -1,146 +1,146 @@
-"use strict";
-
-/* exported logger */
-
-var AbstractGuiElement = require('./AbstractGuiElement');
-var GuiConnector = require('../GuiConnector');
-var InvalidCredentialsError = require('../InvalidCredentialsError');
-var PanelControlElementType = require('./PanelControlElementType');
-var ConfigurationType = require("../ConfigurationType");
-
-var Functions = require('../Functions');
-var logger = require('../logger');
-
-function LoginDialog(params) {
-  AbstractGuiElement.call(this, params);
-  var self = this;
-  self._createLoginTab();
-
-  var loginButton = self.getControlElement(PanelControlElementType.USER_TAB_LOGIN_BUTTON);
-  loginButton.onclick = function() {
-    var login = self.getControlElement(PanelControlElementType.USER_TAB_LOGIN_INPUT_TEXT).value;
-    var password = self.getControlElement(PanelControlElementType.USER_TAB_PASSWORD_INPUT_TEXT).value;
-
-    return ServerConnector.login(login, password).then(function() {
-      window.location.reload(false);
-    }).then(null, function(error) {
-      if (error instanceof InvalidCredentialsError) {
-        GuiConnector.alert("invalid credentials");
-      } else {
-        GuiConnector.alert(error);
-      }
-    });
-  };
-
-}
-
-LoginDialog.prototype = Object.create(AbstractGuiElement.prototype);
-LoginDialog.prototype.constructor = LoginDialog;
-
-LoginDialog.prototype.createTableRow = function (elements) {
-  var row = Functions.createElement({
-    type: "div",
-    style: "display: table-row;"
-  });
-
-  for (var i = 0; i < elements.length; i++) {
-    var cell = Functions.createElement({
-      type : "div",
-      style : "display: table-cell;"
-    });
-    cell.appendChild(elements[i]);
-    row.appendChild(cell);
-  }
-  return row;
-};
-
-LoginDialog.prototype._createLoginTab = function () {
-  var self = this;
-
-  var authorizationFormTab = Functions.createElement({
-    type: "div",
-    style: "width:100%;display: table;border-spacing: 10px;"
-  });
-  this.getElement().appendChild(authorizationFormTab);
-
-  var loginLabel = Functions.createElement({
-    type: "div",
-    content: "LOGIN:"
-  });
-  var loginInput = Functions.createElement({
-    type: "input",
-    inputType: "text",
-    style: "width:100%",
-    name: "loginText"
-  });
-  this.setControlElement(PanelControlElementType.USER_TAB_LOGIN_INPUT_TEXT, loginInput);
-
-  authorizationFormTab.appendChild(self.createTableRow([loginLabel, loginInput]));
-
-  var passwordLabel = Functions.createElement({
-    type: "div",
-    content: "PASSWORD:"
-  });
-  var passwordInput = Functions.createElement({
-    type: "input",
-    inputType: "password",
-    style: "width:100%",
-    name: "passwordText"
-  });
-  this.setControlElement(PanelControlElementType.USER_TAB_PASSWORD_INPUT_TEXT, passwordInput);
-
-  authorizationFormTab.appendChild(self.createTableRow([passwordLabel, passwordInput]));
-
-  var centerTag = Functions.createElement({
-    type: "center"
-  });
-  this.getElement().appendChild(centerTag);
-
-  var loginButton = Functions.createElement({
-    type: "button",
-    name: "loginButton",
-    content: "LOGIN"
-  });
-  centerTag.appendChild(loginButton);
-  this.setControlElement(PanelControlElementType.USER_TAB_LOGIN_BUTTON, loginButton);
-  this.getElement().appendChild(Functions.createElement({type: "br"}));
-
-  this.getElement().appendChild(Functions.createElement({
-    type: "a",
-    name: "requestAccount",
-    content: "Request an account",
-    href: "#"
-  }));
-
-};
-
-LoginDialog.prototype.init = function () {
-  var self = this;
-  return ServerConnector.getConfigurationParam(ConfigurationType.REQUEST_ACCOUNT_EMAIL).then(function (value) {
-    var link = $("[name=requestAccount]", self.getElement());
-    link.attr("href", "mailto:" + value + "?subject=MINERVA account request");
-  });
-};
-
-LoginDialog.prototype.open = function () {
-  var self = this;
-  var div = self.getElement();
-  if (!$(div).hasClass("ui-dialog-content")) {
-    $(div).dialog({
-      autoOpen: false,
-      resizable: false
-    });
-  }
-
-  $(div).dialog('option', 'title', 'AUTHORIZATION FORM');
-  $(div).dialog("open");
-};
-
-LoginDialog.prototype.destroy = function () {
-  var self = this;
-  if ($(self.getElement()).hasClass("ui-dialog-content")) {
-    $(self.getElement()).dialog("destroy");
-  }
-};
-
-module.exports = LoginDialog;
+"use strict";
+
+/* exported logger */
+
+var AbstractGuiElement = require('./AbstractGuiElement');
+var GuiConnector = require('../GuiConnector');
+var InvalidCredentialsError = require('../InvalidCredentialsError');
+var PanelControlElementType = require('./PanelControlElementType');
+var ConfigurationType = require("../ConfigurationType");
+
+var Functions = require('../Functions');
+var logger = require('../logger');
+
+function LoginDialog(params) {
+  AbstractGuiElement.call(this, params);
+  var self = this;
+  self._createLoginTab();
+
+  var loginButton = self.getControlElement(PanelControlElementType.USER_TAB_LOGIN_BUTTON);
+  loginButton.onclick = function() {
+    var login = self.getControlElement(PanelControlElementType.USER_TAB_LOGIN_INPUT_TEXT).value;
+    var password = self.getControlElement(PanelControlElementType.USER_TAB_PASSWORD_INPUT_TEXT).value;
+
+    return ServerConnector.login(login, password).then(function() {
+      window.location.reload(false);
+    }).then(null, function(error) {
+      if (error instanceof InvalidCredentialsError) {
+        GuiConnector.alert("invalid credentials");
+      } else {
+        GuiConnector.alert(error);
+      }
+    });
+  };
+
+}
+
+LoginDialog.prototype = Object.create(AbstractGuiElement.prototype);
+LoginDialog.prototype.constructor = LoginDialog;
+
+LoginDialog.prototype.createTableRow = function (elements) {
+  var row = Functions.createElement({
+    type: "div",
+    style: "display: table-row;"
+  });
+
+  for (var i = 0; i < elements.length; i++) {
+    var cell = Functions.createElement({
+      type : "div",
+      style : "display: table-cell;"
+    });
+    cell.appendChild(elements[i]);
+    row.appendChild(cell);
+  }
+  return row;
+};
+
+LoginDialog.prototype._createLoginTab = function () {
+  var self = this;
+
+  var authorizationFormTab = Functions.createElement({
+    type: "div",
+    style: "width:100%;display: table;border-spacing: 10px;"
+  });
+  this.getElement().appendChild(authorizationFormTab);
+
+  var loginLabel = Functions.createElement({
+    type: "div",
+    content: "LOGIN:"
+  });
+  var loginInput = Functions.createElement({
+    type: "input",
+    inputType: "text",
+    style: "width:100%",
+    name: "loginText"
+  });
+  this.setControlElement(PanelControlElementType.USER_TAB_LOGIN_INPUT_TEXT, loginInput);
+
+  authorizationFormTab.appendChild(self.createTableRow([loginLabel, loginInput]));
+
+  var passwordLabel = Functions.createElement({
+    type: "div",
+    content: "PASSWORD:"
+  });
+  var passwordInput = Functions.createElement({
+    type: "input",
+    inputType: "password",
+    style: "width:100%",
+    name: "passwordText"
+  });
+  this.setControlElement(PanelControlElementType.USER_TAB_PASSWORD_INPUT_TEXT, passwordInput);
+
+  authorizationFormTab.appendChild(self.createTableRow([passwordLabel, passwordInput]));
+
+  var centerTag = Functions.createElement({
+    type: "center"
+  });
+  this.getElement().appendChild(centerTag);
+
+  var loginButton = Functions.createElement({
+    type: "button",
+    name: "loginButton",
+    content: "LOGIN"
+  });
+  centerTag.appendChild(loginButton);
+  this.setControlElement(PanelControlElementType.USER_TAB_LOGIN_BUTTON, loginButton);
+  this.getElement().appendChild(Functions.createElement({type: "br"}));
+
+  this.getElement().appendChild(Functions.createElement({
+    type: "a",
+    name: "requestAccount",
+    content: "Request an account",
+    href: "#"
+  }));
+
+};
+
+LoginDialog.prototype.init = function () {
+  var self = this;
+  return ServerConnector.getConfigurationParam(ConfigurationType.REQUEST_ACCOUNT_EMAIL).then(function (value) {
+    var link = $("[name=requestAccount]", self.getElement());
+    link.attr("href", "mailto:" + value + "?subject=MINERVA account request");
+  });
+};
+
+LoginDialog.prototype.open = function () {
+  var self = this;
+  var div = self.getElement();
+  if (!$(div).hasClass("ui-dialog-content")) {
+    $(div).dialog({
+      autoOpen: false,
+      resizable: false
+    });
+  }
+
+  $(div).dialog('option', 'title', 'AUTHORIZATION FORM');
+  $(div).dialog("open");
+};
+
+LoginDialog.prototype.destroy = function () {
+  var self = this;
+  if ($(self.getElement()).hasClass("ui-dialog-content")) {
+    $(self.getElement()).dialog("destroy");
+  }
+};
+
+module.exports = LoginDialog;
diff --git a/frontend-js/src/main/js/gui/MapContextMenu.js b/frontend-js/src/main/js/gui/MapContextMenu.js
index c66c5f077c6c852f9b27d31b1233cae6f2e12846..048e16d10b15aa8221e6978002ca7373464f99d9 100644
--- a/frontend-js/src/main/js/gui/MapContextMenu.js
+++ b/frontend-js/src/main/js/gui/MapContextMenu.js
@@ -1,49 +1,49 @@
-"use strict";
-
-/* exported logger */
-
-var ContextMenu = require('./ContextMenu');
-
-var logger = require('../logger');
-
-function MapContextMenu(params) {
-  ContextMenu.call(this, params);
-  var self = this;
-
-  self._createMapContextMenuGui();
-  self.setMolArt(params.molArt);
-}
-
-MapContextMenu.prototype = Object.create(ContextMenu.prototype);
-MapContextMenu.prototype.constructor = MapContextMenu;
-
-
-MapContextMenu.prototype._createMapContextMenuGui = function() {
-  var self = this;
-  self.addOption("Add comment", function() {
-    return self.getMap().openCommentDialog();
-  });
-  self.addOption("Select mode", function() {
-    return self.getMap().toggleDrawing();
-  });  
-};
-
-MapContextMenu.prototype.init = function() {
-  var self = this;
-  return self.createExportAsImageSubmenu().then(function(submenu){
-    self.addOption(submenu);
-    return self.createExportAsModelSubmenu();
-  }).then(function(submenu){
-    self.addOption(submenu);
-  });
-};
-
-MapContextMenu.prototype.setMolArt = function(molArt){
-  this._molArt = molArt;
-};
-
-MapContextMenu.prototype.getMolArt = function(){
-  return this._molArt;
-};
-
-module.exports = MapContextMenu;
+"use strict";
+
+/* exported logger */
+
+var ContextMenu = require('./ContextMenu');
+
+var logger = require('../logger');
+
+function MapContextMenu(params) {
+  ContextMenu.call(this, params);
+  var self = this;
+
+  self._createMapContextMenuGui();
+  self.setMolArt(params.molArt);
+}
+
+MapContextMenu.prototype = Object.create(ContextMenu.prototype);
+MapContextMenu.prototype.constructor = MapContextMenu;
+
+
+MapContextMenu.prototype._createMapContextMenuGui = function() {
+  var self = this;
+  self.addOption("Add comment", function() {
+    return self.getMap().openCommentDialog();
+  });
+  self.addOption("Select mode", function() {
+    return self.getMap().toggleDrawing();
+  });  
+};
+
+MapContextMenu.prototype.init = function() {
+  var self = this;
+  return self.createExportAsImageSubmenu().then(function(submenu){
+    self.addOption(submenu);
+    return self.createExportAsModelSubmenu();
+  }).then(function(submenu){
+    self.addOption(submenu);
+  });
+};
+
+MapContextMenu.prototype.setMolArt = function(molArt){
+  this._molArt = molArt;
+};
+
+MapContextMenu.prototype.getMolArt = function(){
+  return this._molArt;
+};
+
+module.exports = MapContextMenu;
diff --git a/frontend-js/src/main/js/gui/OptionsMenu.js b/frontend-js/src/main/js/gui/OptionsMenu.js
index 9ef28aaeb490653ccbb1d3e7b6d13edef02f740b..178fa188aea9f3d883f450f2ed8e722e5cd1ba91 100644
--- a/frontend-js/src/main/js/gui/OptionsMenu.js
+++ b/frontend-js/src/main/js/gui/OptionsMenu.js
@@ -1,56 +1,56 @@
-"use strict";
-
-var ContextMenu = require('./ContextMenu');
-var PluginDialog = require('./PluginDialog');
-var Promise = require('bluebird');
-
-function OptionsMenu(params) {
-  ContextMenu.call(this, params);
-  var self = this;
-
-  self._createMenuGui();
-}
-
-OptionsMenu.prototype = Object.create(ContextMenu.prototype);
-OptionsMenu.prototype.constructor = OptionsMenu;
-
-
-OptionsMenu.prototype._createMenuGui = function () {
-  var self = this;
-  self.addOption("Plugins", function () {
-    var initPromise = Promise.resolve();
-    if (self._pluginDialog === undefined) {
-      self._pluginDialog = new PluginDialog({
-        element: document.createElement("div"),
-        customMap: self.getMap(),
-        pluginManager: self.getPluginManager()
-      });
-      initPromise = self._pluginDialog.init();
-    }
-    return initPromise.then(function () {
-      return self._pluginDialog.open();
-    })
-  });
-};
-
-OptionsMenu.prototype.init = function () {
-  return Promise.resolve();
-};
-OptionsMenu.prototype.destroy = function () {
-  var self = this;
-  var promises = [];
-  if (self._pluginDialog !== undefined) {
-    promises.push(self._pluginDialog.destroy());
-  }
-  return Promise.all(promises);
-};
-
-OptionsMenu.prototype.setPluginManager = function (pluginManager) {
-  this._pluginManager = pluginManager;
-};
-
-OptionsMenu.prototype.getPluginManager = function () {
-  return this._pluginManager;
-};
-
-module.exports = OptionsMenu;
+"use strict";
+
+var ContextMenu = require('./ContextMenu');
+var PluginDialog = require('./PluginDialog');
+var Promise = require('bluebird');
+
+function OptionsMenu(params) {
+  ContextMenu.call(this, params);
+  var self = this;
+
+  self._createMenuGui();
+}
+
+OptionsMenu.prototype = Object.create(ContextMenu.prototype);
+OptionsMenu.prototype.constructor = OptionsMenu;
+
+
+OptionsMenu.prototype._createMenuGui = function () {
+  var self = this;
+  self.addOption("Plugins", function () {
+    var initPromise = Promise.resolve();
+    if (self._pluginDialog === undefined) {
+      self._pluginDialog = new PluginDialog({
+        element: document.createElement("div"),
+        customMap: self.getMap(),
+        pluginManager: self.getPluginManager()
+      });
+      initPromise = self._pluginDialog.init();
+    }
+    return initPromise.then(function () {
+      return self._pluginDialog.open();
+    })
+  });
+};
+
+OptionsMenu.prototype.init = function () {
+  return Promise.resolve();
+};
+OptionsMenu.prototype.destroy = function () {
+  var self = this;
+  var promises = [];
+  if (self._pluginDialog !== undefined) {
+    promises.push(self._pluginDialog.destroy());
+  }
+  return Promise.all(promises);
+};
+
+OptionsMenu.prototype.setPluginManager = function (pluginManager) {
+  this._pluginManager = pluginManager;
+};
+
+OptionsMenu.prototype.getPluginManager = function () {
+  return this._pluginManager;
+};
+
+module.exports = OptionsMenu;
diff --git a/frontend-js/src/main/js/gui/OverviewDialog.js b/frontend-js/src/main/js/gui/OverviewDialog.js
index ae3a5c4023cab0f5cca9978a6c536001c853fb5f..864743375a6f03efd4037d0f905894bf137f1235 100644
--- a/frontend-js/src/main/js/gui/OverviewDialog.js
+++ b/frontend-js/src/main/js/gui/OverviewDialog.js
@@ -1,227 +1,227 @@
-"use strict";
-
-/* exported logger */
-
-var AbstractGuiElement = require('./AbstractGuiElement');
-var GuiConnector = require('../GuiConnector');
-var Point = require('../map/canvas/Point');
-
-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 re-sized 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 = new Point(xNormal, 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) {
-      self.openLink(link);
-    }
-  };
-
-  this.overviewImageTag.onclick = onClickEvent;
-
-  // resize canvas where on mouse over highlight 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 cursor 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 = new Point(xNormal, 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.openLink = function (link) {
-  var self = this;
-  var map = self.getMap();
-  if (link.type === "OverviewModelLink") {
-    logger.debug("Opening model from overview. ModelId: " + link.modelLinkId);
-    logger.debug("link coordinates [" + link.idObject + "]: " + link.modelPoint);
-
-    map.openSubmap(link.modelLinkId);
-    var submap = map.getSubmapById(link.modelLinkId);
-    logger.debug("zoom [" + link.idObject + "]: " + link.zoomLevel + submap.getMinZoom());
-    submap.setCenter(new Point(link.modelPoint));
-    submap.setZoom(link.zoomLevel + submap.getMinZoom());
-
-    $(self.getElement()).dialog("close");
-  } 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);
-    return map.getOverlayByName("search").searchByQuery(link.query).then(function () {
-      $(self.getElement()).dialog("close");
-    }, GuiConnector.alert);
-  } else {
-    logger.warn("Unknown type of link: " + link.type + ". Don't know what to do... LinkId: " + link.idObject);
-  }
-};
-
-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;
+"use strict";
+
+/* exported logger */
+
+var AbstractGuiElement = require('./AbstractGuiElement');
+var GuiConnector = require('../GuiConnector');
+var Point = require('../map/canvas/Point');
+
+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 re-sized 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 = new Point(xNormal, 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) {
+      self.openLink(link);
+    }
+  };
+
+  this.overviewImageTag.onclick = onClickEvent;
+
+  // resize canvas where on mouse over highlight 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 cursor 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 = new Point(xNormal, 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.openLink = function (link) {
+  var self = this;
+  var map = self.getMap();
+  if (link.type === "OverviewModelLink") {
+    logger.debug("Opening model from overview. ModelId: " + link.modelLinkId);
+    logger.debug("link coordinates [" + link.idObject + "]: " + link.modelPoint);
+
+    map.openSubmap(link.modelLinkId);
+    var submap = map.getSubmapById(link.modelLinkId);
+    logger.debug("zoom [" + link.idObject + "]: " + link.zoomLevel + submap.getMinZoom());
+    submap.setCenter(new Point(link.modelPoint));
+    submap.setZoom(link.zoomLevel + submap.getMinZoom());
+
+    $(self.getElement()).dialog("close");
+  } 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);
+    return map.getOverlayByName("search").searchByQuery(link.query).then(function () {
+      $(self.getElement()).dialog("close");
+    }, GuiConnector.alert);
+  } else {
+    logger.warn("Unknown type of link: " + link.type + ". Don't know what to do... LinkId: " + link.idObject);
+  }
+};
+
+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 ae0f4900331f9769f5c8d93ec74ac02b5512d7af..309fc1c6740d2e25c9c5512183782e1d296c55d7 100644
--- a/frontend-js/src/main/js/gui/Panel.js
+++ b/frontend-js/src/main/js/gui/Panel.js
@@ -1,309 +1,309 @@
-"use strict";
-
-/* exported logger */
-
-var GuiConnector = require('../GuiConnector');
-var AbstractGuiElement = require('./AbstractGuiElement');
-var GuiUtils = require('./leftPanel/GuiUtils');
-var PanelControlElementType = require('./PanelControlElementType');
-var Functions = require('../Functions');
-
-var logger = require('../logger');
-var xss = require('xss');
-
-/**
- *
- * @param {Configuration} [params.configuration]
- * @param {HTMLElement} params.element
- * @param {Project} params.project
- * @param {CustomMap} [params.customMap]
- * @param {string} params.panelName
- * @param {boolean} params.scrollable
- * @param {string} [params.helpTip]
- * @param params.parent
- *
- * @constructor
- * @extends AbstractGuiElement
- */
-
-function Panel(params) {
-  AbstractGuiElement.call(this, params);
-
-  var self = this;
-
-  self.setParent(params.parent);
-  var configuration = params.configuration;
-  if (params.configuration === undefined) {
-    configuration = self.getMap().getConfiguration();
-  }
-  var guiUtils = new GuiUtils(configuration);
-  self.setGuiUtils(guiUtils);
-  if (self.getMap() !== undefined) {
-    this.getGuiUtils().setMap(self.getMap());
-  }
-  self.setPanelName(params.panelName);
-
-  if (params.scrollable) {
-    $(self.getElement()).addClass("pre-scrollable");
-  } else {
-    $(self.getElement()).css("overflow-y", "auto");
-  }
-
-  $(self.getElement()).css("position", "relative");
-  if (params.helpTip !== undefined) {
-    self.setHelpTip(params.helpTip);
-  }
-
-  GuiConnector.addWindowResizeEvent(function () {
-    self.onresize();
-  });
-
-  $("a[href='#" + self.getElement().id + "']").on('shown.bs.tab', function () {
-    self.onresize();
-  });
-
-}
-
-Panel.prototype = Object.create(AbstractGuiElement.prototype);
-Panel.prototype.constructor = Panel;
-
-Panel.prototype.createHelpButton = function () {
-  var self = this;
-  var helpTipButton = self.getGuiUtils().createHelpButton(self.getHelpTip());
-  self.getElement().appendChild(helpTipButton);
-};
-
-Panel.prototype.disablePanel = function (message) {
-  var self = this;
-
-  $(self.getElement()).children().css("visibility", "hidden");
-  $("[class='minerva-help-button']", self.getElement()).children().css("visibility", "visible");
-  var hideReasonDiv = document.createElement("div");
-  hideReasonDiv.className = "searchPanel";
-
-  var center = document.createElement("center");
-  var messageDiv = document.createElement("h4");
-  messageDiv.innerHTML = message;
-  center.appendChild(messageDiv);
-  hideReasonDiv.appendChild(center);
-
-  $(self.getElement()).prepend(hideReasonDiv);
-};
-
-Panel.prototype.isDisabled = function () {
-  var self = this;
-  var searchQueryElement = self.getControlElement(PanelControlElementType.SEARCH_DIV);
-  return searchQueryElement.style.visibility === "hidden";
-};
-Panel.prototype.setMap = function (map) {
-  this._map = map;
-};
-
-Panel.prototype.setPanelName = function (panelName) {
-  this._panelName = panelName;
-};
-
-Panel.prototype.getPanelName = function () {
-  return this._panelName;
-};
-
-/**
- *
- * @param {HTMLElement} element
- */
-Panel.prototype.setElement = function (element) {
-  if (element === undefined || element === null) {
-    throw new Error("DOM Element must be defined");
-  }
-  this._element = element;
-};
-
-/**
- *
- * @returns {HTMLElement}
- */
-Panel.prototype.getElement = function () {
-  return this._element;
-};
-
-Panel.prototype.getElementByName = function (element, name) {
-  if (element !== undefined) {
-    if (element.getAttribute("name") === name) {
-      return element;
-    }
-    var children = element.children;
-    for (var i = 0; i < children.length; i++) {
-      var child = children[i];
-      var res = this.getElementByName(child, name);
-      if (res !== undefined) {
-        return res;
-      }
-    }
-  }
-  return undefined;
-};
-
-Panel.prototype.getDialogDiv = function (id) {
-  var dialogs = this.getElementByName(this.getElement(), "dialogs");
-  if (dialogs === undefined) {
-    dialogs = document.createElement("div");
-    dialogs.setAttribute("name", "dialogs");
-    this.getElement().appendChild(dialogs);
-
-    this._dialogs = [];
-  }
-
-  var dialogDiv = this._dialogs[id];
-
-  if (dialogDiv === undefined) {
-    dialogDiv = document.createElement("div");
-    dialogDiv.className = "ui-widget";
-    dialogDiv.setAttribute("name", "dialog-" + id);
-
-    var contentDiv = document.createElement("div");
-    contentDiv.setAttribute("name", "content");
-    dialogDiv.appendChild(contentDiv);
-
-    dialogs.appendChild(dialogDiv);
-
-    this._dialogs[id] = dialogDiv;
-  }
-  return dialogDiv;
-};
-
-Panel.prototype.assignDialogOptions = function (div, params) {
-  var dialog = $(div);
-  for (var key in params) {
-    if (params.hasOwnProperty(key)) {
-      if (key === "id") {
-        div.setAttribute("name", "dialog-" + params[key]);
-      } else if (key === "modal") {
-        dialog.dialog('option', 'modal', params[key]);
-      } else if (key === "buttons") {
-        dialog.dialog('option', 'buttons', params[key]);
-      } else if (key === "className") {
-        dialog.dialog('option', 'dialogClass', params[key]);
-      } else if (key === "title") {
-        dialog.dialog('option', 'title', params[key]);
-      } else if (key === "width") {
-        dialog.dialog('option', 'width', params[key]);
-      } else {
-        throw new Error("Unknown dialog param: " + key + " - " + params[key]);
-      }
-    }
-  }
-};
-
-Panel.prototype.openDialog = function (content, options) {
-  if (options === undefined) {
-    options = {};
-  }
-
-  if (options.id === undefined) {
-    logger.warn("Id of dialog is not defined");
-  }
-
-  var div = this.getDialogDiv(options.id);
-
-  var contentDiv = this.getElementByName(div, "content");
-  while (contentDiv.hasChildNodes()) {
-    contentDiv.removeChild(contentDiv.lastChild);
-  }
-  contentDiv.appendChild(content);
-  contentDiv.style.display = "block";
-
-  $(div).dialog({
-    close: function () {
-      contentDiv.style.display = "none";
-      $(this).dialog('destroy');
-    },
-    dialogClass: options.className
-  });
-
-  this.assignDialogOptions(div, options);
-
-  $(div).dialog("open");
-};
-
-Panel.prototype.init = function () {
-  throw new Error(this.getPanelName() + " Not implemented");
-};
-
-Panel.prototype.setParent = function (parent) {
-  this._parent = parent;
-};
-
-Panel.prototype.getParent = function () {
-  return this._parent;
-};
-
-/**
- *
- * @param {GuiUtils} guiUtils
- */
-Panel.prototype.setGuiUtils = function (guiUtils) {
-  this._guiUtils = guiUtils;
-};
-
-/**
- *
- * @returns {GuiUtils}
- */
-Panel.prototype.getGuiUtils = function () {
-  return this._guiUtils;
-};
-
-Panel.prototype.setHelpTip = function (helpTip) {
-  if (this._helpTip === undefined && helpTip !== undefined) {
-    this._helpTip = helpTip;
-    this.createHelpButton();
-  }
-};
-
-Panel.prototype.getHelpTip = function () {
-  return this._helpTip;
-};
-
-Panel.prototype.onresize = function () {
-  var self = this;
-  var footerPosition = window.innerHeight;
-
-  // compute the width (we can only compute it for visible elements)
-  var size = 100000;
-
-  if ($(self.getElement()).is(":visible")) {
-
-    $(".pre-scrollable", self.getElement()).each(function (index, element) {
-      if ($(element).is(":visible")) {
-        size = Math.min(size, footerPosition - $(element).offset().top);
-      }
-    });
-    if ($(self.getElement()).hasClass("pre-scrollable") && $(self.getElement()).is(":visible")) {
-      size = Math.min(size, footerPosition - $(self.getElement()).offset().top);
-    }
-    if (size !== 100000) {
-      $(".pre-scrollable", self.getElement()).each(function (index, element) {
-        $(element).css('max-height', size);
-        $(element).css('height', size);
-      });
-    }
-    if ($(self.getElement()).hasClass("pre-scrollable") && $(self.getElement()).is(":visible")) {
-      $(self.getElement()).css('max-height', size);
-      $(self.getElement()).css('height', size);
-    }
-  }
-
-};
-
-Panel.prototype.destroy = function () {
-  for (var id in this._dialogs) {
-    if (this._dialogs.hasOwnProperty(id)) {
-      var div = this._dialogs[id];
-      if ($(div).hasClass("ui-dialog-content")) {
-        $(div).dialog("destroy");
-      }
-    }
-  }
-};
-
-module.exports = Panel;
+"use strict";
+
+/* exported logger */
+
+var GuiConnector = require('../GuiConnector');
+var AbstractGuiElement = require('./AbstractGuiElement');
+var GuiUtils = require('./leftPanel/GuiUtils');
+var PanelControlElementType = require('./PanelControlElementType');
+var Functions = require('../Functions');
+
+var logger = require('../logger');
+var xss = require('xss');
+
+/**
+ *
+ * @param {Configuration} [params.configuration]
+ * @param {HTMLElement} params.element
+ * @param {Project} params.project
+ * @param {CustomMap} [params.customMap]
+ * @param {string} params.panelName
+ * @param {boolean} params.scrollable
+ * @param {string} [params.helpTip]
+ * @param params.parent
+ *
+ * @constructor
+ * @extends AbstractGuiElement
+ */
+
+function Panel(params) {
+  AbstractGuiElement.call(this, params);
+
+  var self = this;
+
+  self.setParent(params.parent);
+  var configuration = params.configuration;
+  if (params.configuration === undefined) {
+    configuration = self.getMap().getConfiguration();
+  }
+  var guiUtils = new GuiUtils(configuration);
+  self.setGuiUtils(guiUtils);
+  if (self.getMap() !== undefined) {
+    this.getGuiUtils().setMap(self.getMap());
+  }
+  self.setPanelName(params.panelName);
+
+  if (params.scrollable) {
+    $(self.getElement()).addClass("pre-scrollable");
+  } else {
+    $(self.getElement()).css("overflow-y", "auto");
+  }
+
+  $(self.getElement()).css("position", "relative");
+  if (params.helpTip !== undefined) {
+    self.setHelpTip(params.helpTip);
+  }
+
+  GuiConnector.addWindowResizeEvent(function () {
+    self.onresize();
+  });
+
+  $("a[href='#" + self.getElement().id + "']").on('shown.bs.tab', function () {
+    self.onresize();
+  });
+
+}
+
+Panel.prototype = Object.create(AbstractGuiElement.prototype);
+Panel.prototype.constructor = Panel;
+
+Panel.prototype.createHelpButton = function () {
+  var self = this;
+  var helpTipButton = self.getGuiUtils().createHelpButton(self.getHelpTip());
+  self.getElement().appendChild(helpTipButton);
+};
+
+Panel.prototype.disablePanel = function (message) {
+  var self = this;
+
+  $(self.getElement()).children().css("visibility", "hidden");
+  $("[class='minerva-help-button']", self.getElement()).children().css("visibility", "visible");
+  var hideReasonDiv = document.createElement("div");
+  hideReasonDiv.className = "searchPanel";
+
+  var center = document.createElement("center");
+  var messageDiv = document.createElement("h4");
+  messageDiv.innerHTML = message;
+  center.appendChild(messageDiv);
+  hideReasonDiv.appendChild(center);
+
+  $(self.getElement()).prepend(hideReasonDiv);
+};
+
+Panel.prototype.isDisabled = function () {
+  var self = this;
+  var searchQueryElement = self.getControlElement(PanelControlElementType.SEARCH_DIV);
+  return searchQueryElement.style.visibility === "hidden";
+};
+Panel.prototype.setMap = function (map) {
+  this._map = map;
+};
+
+Panel.prototype.setPanelName = function (panelName) {
+  this._panelName = panelName;
+};
+
+Panel.prototype.getPanelName = function () {
+  return this._panelName;
+};
+
+/**
+ *
+ * @param {HTMLElement} element
+ */
+Panel.prototype.setElement = function (element) {
+  if (element === undefined || element === null) {
+    throw new Error("DOM Element must be defined");
+  }
+  this._element = element;
+};
+
+/**
+ *
+ * @returns {HTMLElement}
+ */
+Panel.prototype.getElement = function () {
+  return this._element;
+};
+
+Panel.prototype.getElementByName = function (element, name) {
+  if (element !== undefined) {
+    if (element.getAttribute("name") === name) {
+      return element;
+    }
+    var children = element.children;
+    for (var i = 0; i < children.length; i++) {
+      var child = children[i];
+      var res = this.getElementByName(child, name);
+      if (res !== undefined) {
+        return res;
+      }
+    }
+  }
+  return undefined;
+};
+
+Panel.prototype.getDialogDiv = function (id) {
+  var dialogs = this.getElementByName(this.getElement(), "dialogs");
+  if (dialogs === undefined) {
+    dialogs = document.createElement("div");
+    dialogs.setAttribute("name", "dialogs");
+    this.getElement().appendChild(dialogs);
+
+    this._dialogs = [];
+  }
+
+  var dialogDiv = this._dialogs[id];
+
+  if (dialogDiv === undefined) {
+    dialogDiv = document.createElement("div");
+    dialogDiv.className = "ui-widget";
+    dialogDiv.setAttribute("name", "dialog-" + id);
+
+    var contentDiv = document.createElement("div");
+    contentDiv.setAttribute("name", "content");
+    dialogDiv.appendChild(contentDiv);
+
+    dialogs.appendChild(dialogDiv);
+
+    this._dialogs[id] = dialogDiv;
+  }
+  return dialogDiv;
+};
+
+Panel.prototype.assignDialogOptions = function (div, params) {
+  var dialog = $(div);
+  for (var key in params) {
+    if (params.hasOwnProperty(key)) {
+      if (key === "id") {
+        div.setAttribute("name", "dialog-" + params[key]);
+      } else if (key === "modal") {
+        dialog.dialog('option', 'modal', params[key]);
+      } else if (key === "buttons") {
+        dialog.dialog('option', 'buttons', params[key]);
+      } else if (key === "className") {
+        dialog.dialog('option', 'dialogClass', params[key]);
+      } else if (key === "title") {
+        dialog.dialog('option', 'title', params[key]);
+      } else if (key === "width") {
+        dialog.dialog('option', 'width', params[key]);
+      } else {
+        throw new Error("Unknown dialog param: " + key + " - " + params[key]);
+      }
+    }
+  }
+};
+
+Panel.prototype.openDialog = function (content, options) {
+  if (options === undefined) {
+    options = {};
+  }
+
+  if (options.id === undefined) {
+    logger.warn("Id of dialog is not defined");
+  }
+
+  var div = this.getDialogDiv(options.id);
+
+  var contentDiv = this.getElementByName(div, "content");
+  while (contentDiv.hasChildNodes()) {
+    contentDiv.removeChild(contentDiv.lastChild);
+  }
+  contentDiv.appendChild(content);
+  contentDiv.style.display = "block";
+
+  $(div).dialog({
+    close: function () {
+      contentDiv.style.display = "none";
+      $(this).dialog('destroy');
+    },
+    dialogClass: options.className
+  });
+
+  this.assignDialogOptions(div, options);
+
+  $(div).dialog("open");
+};
+
+Panel.prototype.init = function () {
+  throw new Error(this.getPanelName() + " Not implemented");
+};
+
+Panel.prototype.setParent = function (parent) {
+  this._parent = parent;
+};
+
+Panel.prototype.getParent = function () {
+  return this._parent;
+};
+
+/**
+ *
+ * @param {GuiUtils} guiUtils
+ */
+Panel.prototype.setGuiUtils = function (guiUtils) {
+  this._guiUtils = guiUtils;
+};
+
+/**
+ *
+ * @returns {GuiUtils}
+ */
+Panel.prototype.getGuiUtils = function () {
+  return this._guiUtils;
+};
+
+Panel.prototype.setHelpTip = function (helpTip) {
+  if (this._helpTip === undefined && helpTip !== undefined) {
+    this._helpTip = helpTip;
+    this.createHelpButton();
+  }
+};
+
+Panel.prototype.getHelpTip = function () {
+  return this._helpTip;
+};
+
+Panel.prototype.onresize = function () {
+  var self = this;
+  var footerPosition = window.innerHeight;
+
+  // compute the width (we can only compute it for visible elements)
+  var size = 100000;
+
+  if ($(self.getElement()).is(":visible")) {
+
+    $(".pre-scrollable", self.getElement()).each(function (index, element) {
+      if ($(element).is(":visible")) {
+        size = Math.min(size, footerPosition - $(element).offset().top);
+      }
+    });
+    if ($(self.getElement()).hasClass("pre-scrollable") && $(self.getElement()).is(":visible")) {
+      size = Math.min(size, footerPosition - $(self.getElement()).offset().top);
+    }
+    if (size !== 100000) {
+      $(".pre-scrollable", self.getElement()).each(function (index, element) {
+        $(element).css('max-height', size);
+        $(element).css('height', size);
+      });
+    }
+    if ($(self.getElement()).hasClass("pre-scrollable") && $(self.getElement()).is(":visible")) {
+      $(self.getElement()).css('max-height', size);
+      $(self.getElement()).css('height', size);
+    }
+  }
+
+};
+
+Panel.prototype.destroy = function () {
+  for (var id in this._dialogs) {
+    if (this._dialogs.hasOwnProperty(id)) {
+      var div = this._dialogs[id];
+      if ($(div).hasClass("ui-dialog-content")) {
+        $(div).dialog("destroy");
+      }
+    }
+  }
+};
+
+module.exports = Panel;
diff --git a/frontend-js/src/main/js/gui/PanelControlElementType.js b/frontend-js/src/main/js/gui/PanelControlElementType.js
index dd7610f6830145ebee9d41cc7f9e0c973af60bcd..9f66700a416c7eb8fa883313c4365f3aa80dffed 100644
--- a/frontend-js/src/main/js/gui/PanelControlElementType.js
+++ b/frontend-js/src/main/js/gui/PanelControlElementType.js
@@ -1,60 +1,60 @@
-"use strict";
-
-var PanelControlElementType = {
-  SEARCH_DIV : "SEARCH_DIV",
-  SEARCH_LABEL : "SEARCH_LABEL",
-  SEARCH_INPUT : "SEARCH_INPUT",
-  SEARCH_BUTTON : "SEARCH_BUTTON",
-  SEARCH_RESULTS_DIV : "SEARCH_RESULTS_DIV",
-  SEARCH_RESULTS_NAV_TAB : "SEARCH_RESULTS_NAV_TAB",
-  SEARCH_RESULTS_CONTENT_TAB : "SEARCH_RESULTS_CONTENT_TAB",
-
-  SEARCH_PERFECT_MATCH_CHECKBOX : "SEARCH_PERFECT_MATCH_CHECKBOX",
-
-  OVERLAY_GENERAL_OVERLAY_DIV : "OVERLAY_GENERAL_OVERLAY_DIV",
-  OVERLAY_GENERAL_OVERLAY_TABLE : "OVERLAY_GENERAL_OVERLAY_TABLE",
-  OVERLAY_CUSTOM_OVERLAY_DIV : "OVERLAY_CUSTOM_OVERLAY_DIV",
-  OVERLAY_CUSTOM_OVERLAY_TABLE : "OVERLAY_CUSTOM_OVERLAY_TABLE",
-  OVERLAY_CUSTOM_OVERLAY_TITLE : "OVERLAY_CUSTOM_OVERLAY_TITLE",
-  OVERLAY_ADD_OVERLAY_BUTTON : "OVERLAY_ADD_OVERLAY_BUTTON",
-
-  USER_TAB_LOGIN_DIV : "USER_TAB_LOGIN_DIV",
-  USER_TAB_LOGIN_INPUT_TEXT : "USER_TAB_LOGIN_INPUT_TEXT",
-  USER_TAB_PASSWORD_INPUT_TEXT : "USER_TAB_PASSWORD_INPUT_TEXT",
-  USER_TAB_LOGIN_BUTTON : "USER_TAB_LOGIN_BUTTON",
-
-  USER_TAB_USER_DIV : "USER_TAB_USER_DIV",
-  USER_TAB_LOGIN_TEXT : "USER_TAB_LOGIN_TEXT",
-  USER_TAB_NAME_TEXT : "USER_TAB_NAME_TEXT",
-  USER_TAB_SURNAME_TEXT : "USER_TAB_SURNAME_TEXT",
-  USER_TAB_EMAIL_TEXT : "USER_TAB_EMAIL_TEXT",
-  USER_TAB_LOGOUT_BUTTON : "USER_TAB_LOGOUT_BUTTON",
-
-  SUBMAP_TABLE : "SUBMAP_TABLE",
-  SUBMAP_DIV : "SUBMAP_DIV",
-
-  INFO_DIV : "INFO_DIV",
-  INFO_PROJECT_NAME_TEXT : "INFO_PROJECT_NAME_TEXT",
-  INFO_PROJECT_VERSION_TEXT : "INFO_PROJECT_VERSION_TEXT",
-  INFO_PROJECT_DESCRIPTION_TEXT : "INFO_PROJECT_DESCRIPTION_TEXT",
-  INFO_PROJECT_PUBLICATIONS_TEXT : "INFO_PROJECT_PUBLICATIONS_TEXT",
-  INFO_PROJECT_SHOW_PUBLICATIONS_BUTTON : "INFO_PROJECT_SHOW_PUBLICATIONS_BUTTON",
-  INFO_PROJECT_GET_ORIGINAL_FILE_BUTTON : "INFO_PROJECT_GET_ORIGINAL_FILE_BUTTON",
-
-  LEGEND_INDICATORS_OL : "LEGEND_INDICATORS_OL",
-  LEGEND_SLIDES_DIV : "LEGEND_SLIDES_DIV",
-
-  MENU_LEGEND_CHECKBOX : "MENU_LEGEND_CHECKBOX",
-  MENU_HIDE_LEFT_PANEL_BUTTON : "MENU_HIDE_LEFT_PANEL_BUTTON",
-  MENU_HIDE_LEFT_PANEL_BUTTON_ICON : "MENU_HIDE_LEFT_PANEL_BUTTON_ICON",
-  MENU_COMMENTS_CHECKBOX : "MENU_COMMENTS_CHECKBOX",
-  MENU_REFRESH_COMMENTS_BUTTON : "MENU_REFRESH_COMMENTS_BUTTON",
-  MENU_CLEAR_BUTTON : "MENU_CLEAR_BUTTON",
-  OVERVIEW_DIALOG_DIV : "OVERVIEW_DIALOG_DIV",
-  MENU_SHOW_OVERVIEW_BUTTON : "MENU_SHOW_OVERVIEW_BUTTON",
-  MENU_VERSION_DIV : "MENU_VERSION_DIV",
-
-  FOOTER_LOADING_DIV : "FOOTER_LOADING_DIV"
-};
-
-module.exports = PanelControlElementType;
+"use strict";
+
+var PanelControlElementType = {
+  SEARCH_DIV : "SEARCH_DIV",
+  SEARCH_LABEL : "SEARCH_LABEL",
+  SEARCH_INPUT : "SEARCH_INPUT",
+  SEARCH_BUTTON : "SEARCH_BUTTON",
+  SEARCH_RESULTS_DIV : "SEARCH_RESULTS_DIV",
+  SEARCH_RESULTS_NAV_TAB : "SEARCH_RESULTS_NAV_TAB",
+  SEARCH_RESULTS_CONTENT_TAB : "SEARCH_RESULTS_CONTENT_TAB",
+
+  SEARCH_PERFECT_MATCH_CHECKBOX : "SEARCH_PERFECT_MATCH_CHECKBOX",
+
+  OVERLAY_GENERAL_OVERLAY_DIV : "OVERLAY_GENERAL_OVERLAY_DIV",
+  OVERLAY_GENERAL_OVERLAY_TABLE : "OVERLAY_GENERAL_OVERLAY_TABLE",
+  OVERLAY_CUSTOM_OVERLAY_DIV : "OVERLAY_CUSTOM_OVERLAY_DIV",
+  OVERLAY_CUSTOM_OVERLAY_TABLE : "OVERLAY_CUSTOM_OVERLAY_TABLE",
+  OVERLAY_CUSTOM_OVERLAY_TITLE : "OVERLAY_CUSTOM_OVERLAY_TITLE",
+  OVERLAY_ADD_OVERLAY_BUTTON : "OVERLAY_ADD_OVERLAY_BUTTON",
+
+  USER_TAB_LOGIN_DIV : "USER_TAB_LOGIN_DIV",
+  USER_TAB_LOGIN_INPUT_TEXT : "USER_TAB_LOGIN_INPUT_TEXT",
+  USER_TAB_PASSWORD_INPUT_TEXT : "USER_TAB_PASSWORD_INPUT_TEXT",
+  USER_TAB_LOGIN_BUTTON : "USER_TAB_LOGIN_BUTTON",
+
+  USER_TAB_USER_DIV : "USER_TAB_USER_DIV",
+  USER_TAB_LOGIN_TEXT : "USER_TAB_LOGIN_TEXT",
+  USER_TAB_NAME_TEXT : "USER_TAB_NAME_TEXT",
+  USER_TAB_SURNAME_TEXT : "USER_TAB_SURNAME_TEXT",
+  USER_TAB_EMAIL_TEXT : "USER_TAB_EMAIL_TEXT",
+  USER_TAB_LOGOUT_BUTTON : "USER_TAB_LOGOUT_BUTTON",
+
+  SUBMAP_TABLE : "SUBMAP_TABLE",
+  SUBMAP_DIV : "SUBMAP_DIV",
+
+  INFO_DIV : "INFO_DIV",
+  INFO_PROJECT_NAME_TEXT : "INFO_PROJECT_NAME_TEXT",
+  INFO_PROJECT_VERSION_TEXT : "INFO_PROJECT_VERSION_TEXT",
+  INFO_PROJECT_DESCRIPTION_TEXT : "INFO_PROJECT_DESCRIPTION_TEXT",
+  INFO_PROJECT_PUBLICATIONS_TEXT : "INFO_PROJECT_PUBLICATIONS_TEXT",
+  INFO_PROJECT_SHOW_PUBLICATIONS_BUTTON : "INFO_PROJECT_SHOW_PUBLICATIONS_BUTTON",
+  INFO_PROJECT_GET_ORIGINAL_FILE_BUTTON : "INFO_PROJECT_GET_ORIGINAL_FILE_BUTTON",
+
+  LEGEND_INDICATORS_OL : "LEGEND_INDICATORS_OL",
+  LEGEND_SLIDES_DIV : "LEGEND_SLIDES_DIV",
+
+  MENU_LEGEND_CHECKBOX : "MENU_LEGEND_CHECKBOX",
+  MENU_HIDE_LEFT_PANEL_BUTTON : "MENU_HIDE_LEFT_PANEL_BUTTON",
+  MENU_HIDE_LEFT_PANEL_BUTTON_ICON : "MENU_HIDE_LEFT_PANEL_BUTTON_ICON",
+  MENU_COMMENTS_CHECKBOX : "MENU_COMMENTS_CHECKBOX",
+  MENU_REFRESH_COMMENTS_BUTTON : "MENU_REFRESH_COMMENTS_BUTTON",
+  MENU_CLEAR_BUTTON : "MENU_CLEAR_BUTTON",
+  OVERVIEW_DIALOG_DIV : "OVERVIEW_DIALOG_DIV",
+  MENU_SHOW_OVERVIEW_BUTTON : "MENU_SHOW_OVERVIEW_BUTTON",
+  MENU_VERSION_DIV : "MENU_VERSION_DIV",
+
+  FOOTER_LOADING_DIV : "FOOTER_LOADING_DIV"
+};
+
+module.exports = PanelControlElementType;
diff --git a/frontend-js/src/main/js/gui/PluginDialog.js b/frontend-js/src/main/js/gui/PluginDialog.js
index fd351bac1583f542de07b0ec827cf139b45bf52f..0837775528057939b0911029563120c6567e86b6 100644
--- a/frontend-js/src/main/js/gui/PluginDialog.js
+++ b/frontend-js/src/main/js/gui/PluginDialog.js
@@ -1,162 +1,162 @@
-"use strict";
-var AbstractGuiElement = require('./AbstractGuiElement');
-var GuiConnector = require('../GuiConnector');
-var GuiUtils = require('./leftPanel/GuiUtils');
-
-var Functions = require('../Functions');
-
-function PluginDialog(params) {
-  AbstractGuiElement.call(this, params);
-  var self = this;
-  self.setPluginManager(params.pluginManager);
-  self._knownPlugins = [];
-}
-
-PluginDialog.prototype = Object.create(AbstractGuiElement.prototype);
-PluginDialog.prototype.constructor = PluginDialog;
-
-PluginDialog.prototype._createPluginGui = function () {
-  var self = this;
-  var guiUtils = new GuiUtils();
-
-  self.getElement().innerHTML = "";
-
-  var pluginFormTab = Functions.createElement({
-    type: "div",
-    name: "minerva-plugin-list-tab",
-    style: "width:100%;display: table;border-spacing: 10px;"
-  });
-  self.getElement().appendChild(pluginFormTab);
-
-  var pluginUrlLabel = Functions.createElement({
-    type: "span",
-    content: "URL:",
-    style: "color:#999999"
-  });
-  var pluginUrlInput = Functions.createElement({
-    type: "input",
-    name: "pluginUrlValue"
-  });
-
-  var loadPluginButton = Functions.createElement({
-    type: "button",
-    name: "loadPluginButton",
-    content: "LOAD",
-    onclick: function () {
-      return self.getPluginManager().addPlugin({url: pluginUrlInput.value}).then(function () {
-        self.close();
-      }).then(null, GuiConnector.alert);
-    }
-  });
-  pluginFormTab.appendChild(guiUtils.createTableRow([pluginUrlLabel, pluginUrlInput, loadPluginButton]));
-
-  var pluginManager = self.getPluginManager();
-
-  var loadedPlugins = [];
-  var plugins = pluginManager.getPlugins();
-  var i;
-  for (i = 0; i < plugins.length; i++) {
-    loadedPlugins[plugins[i].getOptions().url] = true;
-  }
-
-  for (i = 0; i < self._knownPlugins.length; i++) {
-    var pluginData = self._knownPlugins[i];
-    var url = pluginData.url;
-
-    var pluginUrl = Functions.createElement({
-      type: "input",
-      value: url,
-      style: "color:#999999"
-    });
-    pluginUrl.readOnly = true;
-    var button;
-    if (!loadedPlugins[url]) {
-      button = Functions.createElement({
-        type: "button",
-        content: "LOAD",
-        onclick: function () {
-          return pluginManager.addPlugin({url: $(this).data("url")}).then(function () {
-            self.close();
-          }).then(null, GuiConnector.alert);
-        }
-      });
-    }
-    $(button).data("url", url);
-
-    pluginFormTab.appendChild(guiUtils.createTableRow([Functions.createElement({type: "span"}), pluginUrl, button]));
-  }
-  for (i = 0; i < plugins.length; i++) {
-    var plugin = plugins[i];
-    var removePlugin = (function () {
-      var pluginToRemove = plugin;
-      return function () {
-        return pluginManager.removePlugin(pluginToRemove).then(function () {
-          self.close();
-        }).then(null, GuiConnector.alert);
-      }
-    })();
-    pluginUrl = Functions.createElement({
-      type: "input",
-      value: plugins[i].getOptions().url,
-      style: "color:#999999"
-    });
-    pluginUrl.readOnly = true;
-    button = Functions.createElement({
-      type: "button",
-      content: "UNLOAD",
-      onclick: removePlugin
-    });
-
-    pluginFormTab.appendChild(guiUtils.createTableRow([Functions.createElement({type: "span"}), pluginUrl, button]));
-
-  }
-};
-
-PluginDialog.prototype.init = function () {
-  var self = this;
-  return ServerConnector.getConfiguration().then(function (configuration) {
-    var pluginsData = configuration.getPluginsData();
-    for (var i = 0; i < pluginsData.length; i++) {
-      var pluginData = pluginsData[i];
-      self._knownPlugins.push({url: ServerConnector.getServerBaseUrl() + pluginData.url});
-    }
-  });
-};
-
-PluginDialog.prototype.open = function () {
-  var self = this;
-  self._createPluginGui();
-  var div = self.getElement();
-  if (!$(div).hasClass("ui-dialog-content")) {
-    $(div).dialog({
-      autoOpen: false,
-      resizable: false,
-      width: 400
-    });
-  }
-
-  $(div).dialog('option', 'title', 'PLUGINS');
-  $(div).dialog("open");
-};
-PluginDialog.prototype.close = function () {
-  var self = this;
-  $(self.getElement()).dialog("close");
-};
-
-PluginDialog.prototype.destroy = function () {
-  var self = this;
-  var div = self.getElement();
-  if ($(div).hasClass("ui-dialog-content")) {
-    $(div).dialog("destroy");
-  }
-};
-
-PluginDialog.prototype.setPluginManager = function (pluginManager) {
-  this._pluginManager = pluginManager;
-};
-
-PluginDialog.prototype.getPluginManager = function () {
-  return this._pluginManager;
-};
-
-module.exports = PluginDialog;
+"use strict";
+var AbstractGuiElement = require('./AbstractGuiElement');
+var GuiConnector = require('../GuiConnector');
+var GuiUtils = require('./leftPanel/GuiUtils');
+
+var Functions = require('../Functions');
+
+function PluginDialog(params) {
+  AbstractGuiElement.call(this, params);
+  var self = this;
+  self.setPluginManager(params.pluginManager);
+  self._knownPlugins = [];
+}
+
+PluginDialog.prototype = Object.create(AbstractGuiElement.prototype);
+PluginDialog.prototype.constructor = PluginDialog;
+
+PluginDialog.prototype._createPluginGui = function () {
+  var self = this;
+  var guiUtils = new GuiUtils();
+
+  self.getElement().innerHTML = "";
+
+  var pluginFormTab = Functions.createElement({
+    type: "div",
+    name: "minerva-plugin-list-tab",
+    style: "width:100%;display: table;border-spacing: 10px;"
+  });
+  self.getElement().appendChild(pluginFormTab);
+
+  var pluginUrlLabel = Functions.createElement({
+    type: "span",
+    content: "URL:",
+    style: "color:#999999"
+  });
+  var pluginUrlInput = Functions.createElement({
+    type: "input",
+    name: "pluginUrlValue"
+  });
+
+  var loadPluginButton = Functions.createElement({
+    type: "button",
+    name: "loadPluginButton",
+    content: "LOAD",
+    onclick: function () {
+      return self.getPluginManager().addPlugin({url: pluginUrlInput.value}).then(function () {
+        self.close();
+      }).then(null, GuiConnector.alert);
+    }
+  });
+  pluginFormTab.appendChild(guiUtils.createTableRow([pluginUrlLabel, pluginUrlInput, loadPluginButton]));
+
+  var pluginManager = self.getPluginManager();
+
+  var loadedPlugins = [];
+  var plugins = pluginManager.getPlugins();
+  var i;
+  for (i = 0; i < plugins.length; i++) {
+    loadedPlugins[plugins[i].getOptions().url] = true;
+  }
+
+  for (i = 0; i < self._knownPlugins.length; i++) {
+    var pluginData = self._knownPlugins[i];
+    var url = pluginData.url;
+
+    var pluginUrl = Functions.createElement({
+      type: "input",
+      value: url,
+      style: "color:#999999"
+    });
+    pluginUrl.readOnly = true;
+    var button;
+    if (!loadedPlugins[url]) {
+      button = Functions.createElement({
+        type: "button",
+        content: "LOAD",
+        onclick: function () {
+          return pluginManager.addPlugin({url: $(this).data("url")}).then(function () {
+            self.close();
+          }).then(null, GuiConnector.alert);
+        }
+      });
+    }
+    $(button).data("url", url);
+
+    pluginFormTab.appendChild(guiUtils.createTableRow([Functions.createElement({type: "span"}), pluginUrl, button]));
+  }
+  for (i = 0; i < plugins.length; i++) {
+    var plugin = plugins[i];
+    var removePlugin = (function () {
+      var pluginToRemove = plugin;
+      return function () {
+        return pluginManager.removePlugin(pluginToRemove).then(function () {
+          self.close();
+        }).then(null, GuiConnector.alert);
+      }
+    })();
+    pluginUrl = Functions.createElement({
+      type: "input",
+      value: plugins[i].getOptions().url,
+      style: "color:#999999"
+    });
+    pluginUrl.readOnly = true;
+    button = Functions.createElement({
+      type: "button",
+      content: "UNLOAD",
+      onclick: removePlugin
+    });
+
+    pluginFormTab.appendChild(guiUtils.createTableRow([Functions.createElement({type: "span"}), pluginUrl, button]));
+
+  }
+};
+
+PluginDialog.prototype.init = function () {
+  var self = this;
+  return ServerConnector.getConfiguration().then(function (configuration) {
+    var pluginsData = configuration.getPluginsData();
+    for (var i = 0; i < pluginsData.length; i++) {
+      var pluginData = pluginsData[i];
+      self._knownPlugins.push({url: ServerConnector.getServerBaseUrl() + pluginData.url});
+    }
+  });
+};
+
+PluginDialog.prototype.open = function () {
+  var self = this;
+  self._createPluginGui();
+  var div = self.getElement();
+  if (!$(div).hasClass("ui-dialog-content")) {
+    $(div).dialog({
+      autoOpen: false,
+      resizable: false,
+      width: 400
+    });
+  }
+
+  $(div).dialog('option', 'title', 'PLUGINS');
+  $(div).dialog("open");
+};
+PluginDialog.prototype.close = function () {
+  var self = this;
+  $(self.getElement()).dialog("close");
+};
+
+PluginDialog.prototype.destroy = function () {
+  var self = this;
+  var div = self.getElement();
+  if ($(div).hasClass("ui-dialog-content")) {
+    $(div).dialog("destroy");
+  }
+};
+
+PluginDialog.prototype.setPluginManager = function (pluginManager) {
+  this._pluginManager = pluginManager;
+};
+
+PluginDialog.prototype.getPluginManager = function () {
+  return this._pluginManager;
+};
+
+module.exports = PluginDialog;
diff --git a/frontend-js/src/main/js/gui/SelectionContextMenu.js b/frontend-js/src/main/js/gui/SelectionContextMenu.js
index 16a7629ebbdc3a33f2660bb6c45291d8383fde83..1c22528851fdb0f3f0209a8b306fab2dcdad48d1 100644
--- a/frontend-js/src/main/js/gui/SelectionContextMenu.js
+++ b/frontend-js/src/main/js/gui/SelectionContextMenu.js
@@ -1,39 +1,39 @@
-"use strict";
-
-/* exported logger */
-
-var ContextMenu = require('./ContextMenu');
-
-var logger = require('../logger');
-
-function SelectionContextMenu(params) {
-  ContextMenu.call(this, params);
-  var self = this;
-
-  self._createSelectionContextMenuGui();
-}
-
-SelectionContextMenu.prototype = Object.create(ContextMenu.prototype);
-SelectionContextMenu.prototype.constructor = SelectionContextMenu;
-
-SelectionContextMenu.prototype.init = function () {
-  var self = this;
-  return self.createExportAsImageSubmenu().then(function (submenu) {
-    self.addOption(submenu);
-    return self.createExportAsModelSubmenu();
-  }).then(function (submenu) {
-    self.addOption(submenu);
-  });
-};
-
-SelectionContextMenu.prototype._createSelectionContextMenuGui = function () {
-  var self = this;
-  self.addOption("Remove Selection", function () {
-    self.getMap().removeSelection();
-    if (self.getMap().isDrawingOn()) {
-      self.getMap().toggleDrawing();
-    }
-  });
-};
-
-module.exports = SelectionContextMenu;
+"use strict";
+
+/* exported logger */
+
+var ContextMenu = require('./ContextMenu');
+
+var logger = require('../logger');
+
+function SelectionContextMenu(params) {
+  ContextMenu.call(this, params);
+  var self = this;
+
+  self._createSelectionContextMenuGui();
+}
+
+SelectionContextMenu.prototype = Object.create(ContextMenu.prototype);
+SelectionContextMenu.prototype.constructor = SelectionContextMenu;
+
+SelectionContextMenu.prototype.init = function () {
+  var self = this;
+  return self.createExportAsImageSubmenu().then(function (submenu) {
+    self.addOption(submenu);
+    return self.createExportAsModelSubmenu();
+  }).then(function (submenu) {
+    self.addOption(submenu);
+  });
+};
+
+SelectionContextMenu.prototype._createSelectionContextMenuGui = function () {
+  var self = this;
+  self.addOption("Remove Selection", function () {
+    self.getMap().removeSelection();
+    if (self.getMap().isDrawingOn()) {
+      self.getMap().toggleDrawing();
+    }
+  });
+};
+
+module.exports = SelectionContextMenu;
diff --git a/frontend-js/src/main/js/gui/SubMenu.js b/frontend-js/src/main/js/gui/SubMenu.js
index 5fe63088015b1a82538be890e6cd428231f1d699..88924fb023f5f5f9af3a1a5d0bee00af62045aea 100644
--- a/frontend-js/src/main/js/gui/SubMenu.js
+++ b/frontend-js/src/main/js/gui/SubMenu.js
@@ -1,73 +1,73 @@
-"use strict";
-
-/* exported logger */
-
-var AbstractGuiElement = require('./AbstractGuiElement');
-var Functions = require('../Functions');
-
-// noinspection JSUnusedLocalSymbols
-var logger = require('../logger');
-
-function SubMenu(params) {
-  AbstractGuiElement.call(this, params);
-  var self = this;
-
-  self._createGui(params);
-
-}
-
-SubMenu.prototype = Object.create(AbstractGuiElement.prototype);
-SubMenu.prototype.constructor = SubMenu;
-
-SubMenu.prototype._createGui = function (params) {
-  var self = this;
-
-  var element = self.getElement();
-  element.className = "dropdown-submenu";
-
-  var link = Functions.createElement({
-    type: "a",
-    href: "#",
-    className: "dropdown-link",
-    content: params.name
-  });
-  link.tabIndex = -1;
-  self.getElement().appendChild(link);
-
-  var ul = Functions.createElement({
-    type: "ul",
-    className: "dropdown-menu"
-  });
-  self.getElement().appendChild(ul);
-  self.setUl(ul);
-
-};
-SubMenu.prototype.addOption = function (name, handler) {
-  var self = this;
-  if (name instanceof SubMenu) {
-    self.getElement().appendChild(name.getElement());
-  } else {
-    var option = Functions.createElement({
-      type: "li"
-    });
-    var link = Functions.createElement({
-      type: "a",
-      href: "#",
-      className: "dropdown-link",
-      content: name
-    });
-    $(link).data("handler", handler);
-    option.appendChild(link);
-    self.getUl().appendChild(option);
-  }
-};
-
-SubMenu.prototype.setUl = function (ul) {
-  this._ul = ul;
-};
-
-SubMenu.prototype.getUl = function () {
-  return this._ul;
-};
-
-module.exports = SubMenu;
+"use strict";
+
+/* exported logger */
+
+var AbstractGuiElement = require('./AbstractGuiElement');
+var Functions = require('../Functions');
+
+// noinspection JSUnusedLocalSymbols
+var logger = require('../logger');
+
+function SubMenu(params) {
+  AbstractGuiElement.call(this, params);
+  var self = this;
+
+  self._createGui(params);
+
+}
+
+SubMenu.prototype = Object.create(AbstractGuiElement.prototype);
+SubMenu.prototype.constructor = SubMenu;
+
+SubMenu.prototype._createGui = function (params) {
+  var self = this;
+
+  var element = self.getElement();
+  element.className = "dropdown-submenu";
+
+  var link = Functions.createElement({
+    type: "a",
+    href: "#",
+    className: "dropdown-link",
+    content: params.name
+  });
+  link.tabIndex = -1;
+  self.getElement().appendChild(link);
+
+  var ul = Functions.createElement({
+    type: "ul",
+    className: "dropdown-menu"
+  });
+  self.getElement().appendChild(ul);
+  self.setUl(ul);
+
+};
+SubMenu.prototype.addOption = function (name, handler) {
+  var self = this;
+  if (name instanceof SubMenu) {
+    self.getElement().appendChild(name.getElement());
+  } else {
+    var option = Functions.createElement({
+      type: "li"
+    });
+    var link = Functions.createElement({
+      type: "a",
+      href: "#",
+      className: "dropdown-link",
+      content: name
+    });
+    $(link).data("handler", handler);
+    option.appendChild(link);
+    self.getUl().appendChild(option);
+  }
+};
+
+SubMenu.prototype.setUl = function (ul) {
+  this._ul = ul;
+};
+
+SubMenu.prototype.getUl = function () {
+  return this._ul;
+};
+
+module.exports = SubMenu;
diff --git a/frontend-js/src/main/js/gui/admin/AbstractAdminPanel.js b/frontend-js/src/main/js/gui/admin/AbstractAdminPanel.js
index 3780b8749497a11a6018655e42f606d4e09443ab..6d0c3434a8d7e1c635ab9f5a3db8b5d3b42f1a76 100644
--- a/frontend-js/src/main/js/gui/admin/AbstractAdminPanel.js
+++ b/frontend-js/src/main/js/gui/admin/AbstractAdminPanel.js
@@ -1,99 +1,99 @@
-"use strict";
-
-/* exported logger */
-/* exported Promise*/
-
-var Panel = require('../Panel');
-var UserPreferences = require('../../map/data/UserPreferences');
-var GuiConnector = require('../../GuiConnector');
-
-// noinspection JSUnusedLocalSymbols
-var logger = require('../../logger');
-// noinspection JSUnusedLocalSymbols
-var Functions = require('../../Functions');
-var Promise = require("bluebird");
-
-/**
- *
- * @param {Configuration} [params.configuration]
- * @param {HTMLElement} params.element
- * @param {Project} params.project
- * @param {CustomMap} params.customMap
- * @param {string} params.panelName
- * @param {string} [params.helpTip]
- * @param params.parent
- *
- * @constructor
- * @extends Panel
- */
-function AbstractAdminPanel(params) {
-  params["scrollable"] = true;
-  Panel.call(this, params);
-  this._createHeader(params.name);
-
-  this._initPromises = [];
-  this._eventBinds = [];
-}
-
-AbstractAdminPanel.prototype = Object.create(Panel.prototype);
-AbstractAdminPanel.prototype.constructor = AbstractAdminPanel;
-
-AbstractAdminPanel.prototype._createHeader = function (name) {
-  // this.getElement().appendChild(Functions.createElement({
-  //   type: "h1",
-  //   content: name
-  // }));
-};
-
-/**
- *
- * @returns {Promise}
- */
-AbstractAdminPanel.prototype.init = function () {
-  return Promise.all(this._initPromises);
-};
-
-/**
- *
- * @param {Object} params
- * @param {string} params.event
- * @param {jQuery} params.jQueryObject
- * @param {string} params.preferenceName
- * @param {Object} params.defaultValue
- * @param {function} params.getter
- * @param {function} params.setter
- */
-AbstractAdminPanel.prototype.bindUserGuiPreference = function (params) {
-  params.jQueryObject.on(params.event, function () {
-    return ServerConnector.getLoggedUser().then(function (user) {
-      var oldValue = user.getPreferences().getGuiPreference(params.preferenceName, params.defaultValue);
-      var newValue = params.getter();
-      if (oldValue !== newValue) {
-        user.getPreferences().setGuiPreference(params.preferenceName, newValue);
-
-        var data = new UserPreferences();
-        data.setGuiPreference(params.preferenceName, newValue);
-        return ServerConnector.updateUserPreferences({user: user, preferences: data});
-      }
-    }).catch(GuiConnector.alert);
-  });
-  this._initPromises.push(ServerConnector.getLoggedUser().then(function (user) {
-    var value = user.getPreferences().getGuiPreference(params.preferenceName, params.defaultValue);
-    return params.setter(value);
-  }));
-
-  this._eventBinds.push(params);
-};
-
-/**
- *
- * @returns {Promise}
- */
-AbstractAdminPanel.prototype.destroy = function () {
-  return Promise.each(this._eventBinds, function (params) {
-    params.jQueryObject.off(params.event);
-  });
-};
-
-
-module.exports = AbstractAdminPanel;
+"use strict";
+
+/* exported logger */
+/* exported Promise*/
+
+var Panel = require('../Panel');
+var UserPreferences = require('../../map/data/UserPreferences');
+var GuiConnector = require('../../GuiConnector');
+
+// noinspection JSUnusedLocalSymbols
+var logger = require('../../logger');
+// noinspection JSUnusedLocalSymbols
+var Functions = require('../../Functions');
+var Promise = require("bluebird");
+
+/**
+ *
+ * @param {Configuration} [params.configuration]
+ * @param {HTMLElement} params.element
+ * @param {Project} params.project
+ * @param {CustomMap} params.customMap
+ * @param {string} params.panelName
+ * @param {string} [params.helpTip]
+ * @param params.parent
+ *
+ * @constructor
+ * @extends Panel
+ */
+function AbstractAdminPanel(params) {
+  params["scrollable"] = true;
+  Panel.call(this, params);
+  this._createHeader(params.name);
+
+  this._initPromises = [];
+  this._eventBinds = [];
+}
+
+AbstractAdminPanel.prototype = Object.create(Panel.prototype);
+AbstractAdminPanel.prototype.constructor = AbstractAdminPanel;
+
+AbstractAdminPanel.prototype._createHeader = function (name) {
+  // this.getElement().appendChild(Functions.createElement({
+  //   type: "h1",
+  //   content: name
+  // }));
+};
+
+/**
+ *
+ * @returns {Promise}
+ */
+AbstractAdminPanel.prototype.init = function () {
+  return Promise.all(this._initPromises);
+};
+
+/**
+ *
+ * @param {Object} params
+ * @param {string} params.event
+ * @param {jQuery} params.jQueryObject
+ * @param {string} params.preferenceName
+ * @param {Object} params.defaultValue
+ * @param {function} params.getter
+ * @param {function} params.setter
+ */
+AbstractAdminPanel.prototype.bindUserGuiPreference = function (params) {
+  params.jQueryObject.on(params.event, function () {
+    return ServerConnector.getLoggedUser().then(function (user) {
+      var oldValue = user.getPreferences().getGuiPreference(params.preferenceName, params.defaultValue);
+      var newValue = params.getter();
+      if (oldValue !== newValue) {
+        user.getPreferences().setGuiPreference(params.preferenceName, newValue);
+
+        var data = new UserPreferences();
+        data.setGuiPreference(params.preferenceName, newValue);
+        return ServerConnector.updateUserPreferences({user: user, preferences: data});
+      }
+    }).catch(GuiConnector.alert);
+  });
+  this._initPromises.push(ServerConnector.getLoggedUser().then(function (user) {
+    var value = user.getPreferences().getGuiPreference(params.preferenceName, params.defaultValue);
+    return params.setter(value);
+  }));
+
+  this._eventBinds.push(params);
+};
+
+/**
+ *
+ * @returns {Promise}
+ */
+AbstractAdminPanel.prototype.destroy = function () {
+  return Promise.each(this._eventBinds, function (params) {
+    params.jQueryObject.off(params.event);
+  });
+};
+
+
+module.exports = AbstractAdminPanel;
diff --git a/frontend-js/src/main/js/gui/admin/AbstractAnnotatorsDialog.js b/frontend-js/src/main/js/gui/admin/AbstractAnnotatorsDialog.js
index bd6441728532085b3ce19efdb1a72656562a4dbc..275de12a40094856c98f056dfee4910da14695ac 100644
--- a/frontend-js/src/main/js/gui/admin/AbstractAnnotatorsDialog.js
+++ b/frontend-js/src/main/js/gui/admin/AbstractAnnotatorsDialog.js
@@ -1,42 +1,42 @@
-"use strict";
-
-/* exported logger */
-
-var AbstractGuiElement = require('../AbstractGuiElement');
-
-// noinspection JSUnusedLocalSymbols
-var logger = require('../../logger');
-
-function AbstractAnnotatorsDialog(params) {
-  AbstractGuiElement.call(this, params);
-}
-
-AbstractAnnotatorsDialog.prototype = Object.create(AbstractGuiElement.prototype);
-AbstractAnnotatorsDialog.prototype.constructor = AbstractAnnotatorsDialog;
-
-/**
- *
- * @param {BioEntityType} elementType
- * @param {boolean} [includeChildren=false]
- *
- * @returns {BioEntityType[]}
- */
-AbstractAnnotatorsDialog.prototype.getAllChildrenTypesIfNeeded = function (elementType, includeChildren) {
-  var result = [elementType];
-  if (includeChildren) {
-    var queue = [elementType];
-    var elementTypes = this.getConfiguration().getElementTypes();
-    while (queue.length > 0) {
-      var type = queue.shift();
-      for (var i = 0; i < elementTypes.length; i++) {
-        if (type.className === elementTypes[i].parentClass) {
-          queue.push(elementTypes[i]);
-          result.push(elementTypes[i]);
-        }
-      }
-    }
-  }
-  return result;
-};
-
-module.exports = AbstractAnnotatorsDialog;
+"use strict";
+
+/* exported logger */
+
+var AbstractGuiElement = require('../AbstractGuiElement');
+
+// noinspection JSUnusedLocalSymbols
+var logger = require('../../logger');
+
+function AbstractAnnotatorsDialog(params) {
+  AbstractGuiElement.call(this, params);
+}
+
+AbstractAnnotatorsDialog.prototype = Object.create(AbstractGuiElement.prototype);
+AbstractAnnotatorsDialog.prototype.constructor = AbstractAnnotatorsDialog;
+
+/**
+ *
+ * @param {BioEntityType} elementType
+ * @param {boolean} [includeChildren=false]
+ *
+ * @returns {BioEntityType[]}
+ */
+AbstractAnnotatorsDialog.prototype.getAllChildrenTypesIfNeeded = function (elementType, includeChildren) {
+  var result = [elementType];
+  if (includeChildren) {
+    var queue = [elementType];
+    var elementTypes = this.getConfiguration().getElementTypes();
+    while (queue.length > 0) {
+      var type = queue.shift();
+      for (var i = 0; i < elementTypes.length; i++) {
+        if (type.className === elementTypes[i].parentClass) {
+          queue.push(elementTypes[i]);
+          result.push(elementTypes[i]);
+        }
+      }
+    }
+  }
+  return result;
+};
+
+module.exports = AbstractAnnotatorsDialog;
diff --git a/frontend-js/src/main/js/gui/admin/ChooseAnnotatorsDialog.js b/frontend-js/src/main/js/gui/admin/ChooseAnnotatorsDialog.js
index f7969805f7927a073312f7882d0af621483d2c09..63bc240de4603d9ab8ed3f11ae1c4252e776bd51 100644
--- a/frontend-js/src/main/js/gui/admin/ChooseAnnotatorsDialog.js
+++ b/frontend-js/src/main/js/gui/admin/ChooseAnnotatorsDialog.js
@@ -1,357 +1,357 @@
-"use strict";
-
-/* exported logger */
-
-var AbstractAnnotatorsDialog = require('./AbstractAnnotatorsDialog');
-var GuiConnector = require("../../GuiConnector");
-var MultiCheckboxList = require("multi-checkbox-list");
-var UserPreferences = require("../../map/data/UserPreferences");
-
-var Functions = require('../../Functions');
-// noinspection JSUnusedLocalSymbols
-var logger = require('../../logger');
-
-function ChooseAnnotatorsDialog(params) {
-  AbstractAnnotatorsDialog.call(this, params);
-  var self = this;
-  self.createGui();
-}
-
-ChooseAnnotatorsDialog.prototype = Object.create(AbstractAnnotatorsDialog.prototype);
-ChooseAnnotatorsDialog.prototype.constructor = ChooseAnnotatorsDialog;
-
-ChooseAnnotatorsDialog.prototype.createGui = function () {
-  var self = this;
-  var content = Functions.createElement({
-    type: "div",
-    style: "display:table;height:100%;width:100%"
-  });
-  content.appendChild(Functions.createElement({
-    type: "div",
-    style: "display:table-cell;height:100%;",
-    content: "<div name='elementTree' style='height:100%;overflow-y:scroll;'/>",
-    xss: false
-  }));
-
-  var annotatorsDiv = Functions.createElement({
-    type: "div",
-    style: "display:table-cell;width:100%",
-    content: "<div style='height:100%;width:100%;overflow-y:auto;'><div name='annotatorListBox'></div><div class='minerva-annotators-params'></div></div>",
-    xss: false
-  });
-  content.appendChild(annotatorsDiv);
-
-  self.getElement().appendChild(content);
-};
-
-function onChangeParameterValue(element, user) {
-  var name = $(element).siblings(".minerva-annotator-param-name")[0].childNodes[0].nodeValue;
-  var annotatorClassName = $(element).parent().parent().attr('name');
-
-  var data = new UserPreferences();
-
-  var annotatorsParams = {};
-  annotatorsParams[annotatorClassName] = {};
-  if (element.type == 'checkbox') annotatorsParams[annotatorClassName][name] = element.checked.toString();
-  else annotatorsParams[annotatorClassName][name] = element.value;
-  data.setAnnotatorsParameters(annotatorsParams);
-
-  return ServerConnector.updateUserPreferences({user: user, preferences: data}).then(null, GuiConnector.alert);
-}
-
-ChooseAnnotatorsDialog.prototype.saveAnnotatorsInfo = function (elementTypes, selectedAnnotators) {
-  selectedAnnotators = selectedAnnotators.slice();
-  return ServerConnector.getLoggedUser().then(function (user) {
-
-    var data = new UserPreferences();
-
-    var elementAnnotators = {};
-    for (var i = 0; i < elementTypes.length; i++) {
-      elementAnnotators[elementTypes[i].className] = selectedAnnotators;
-
-      var userAnnotators = user.getPreferences().getElementAnnotators(elementTypes[i].className);
-      userAnnotators.length = 0;
-      userAnnotators.push.apply(userAnnotators, selectedAnnotators);
-    }
-    data.setElementAnnotators(elementAnnotators);
-    return ServerConnector.updateUserPreferences({
-      user: user,
-      preferences: data
-    });
-  }).catch(GuiConnector.alert);
-};
-
-ChooseAnnotatorsDialog.prototype.setElementType = function (elementType) {
-  var self = this;
-
-  var configuration = self.getConfiguration();
-
-  return ServerConnector.getLoggedUser().then(function (user) {
-    var element = $("[name='annotatorListBox']", self.getElement())[0];
-    var annotatorsParams = $(".minerva-annotators-params", self.getElement())[0];
-    Functions.removeChildren(element);
-
-    var selectElement = Functions.createElement({
-      type: "div",
-      style: "width:50%; height:200px;float:left; OVERFLOW-Y:scroll"
-    });
-
-    element.appendChild(selectElement);
-    var includeChildrenCheckbox = Functions.createElement({type: "input", inputType: "checkbox"});
-    element.appendChild(includeChildrenCheckbox);
-    element.appendChild(Functions.createElement({type: "span", content: "Apply to all in subtree"}));
-    element.appendChild(Functions.createElement({type: "br"}));
-    var copyFromButton = Functions.createElement({
-      type: "button", content: "Copy from", onclick: function () {
-        var typeClassName = copyFromSelect.value;
-        var annotators;
-        for (var i = 0; i < configuration.getElementTypes().length; i++) {
-          var type = configuration.getElementTypes()[i];
-          if (typeClassName === type.className) {
-            annotators = user.getPreferences().getElementAnnotators(typeClassName);
-          }
-        }
-        if (annotators === undefined) {
-          return GuiConnector.alert("Invalid element type: " + copyFromSelect.value);
-        } else {
-          var includeChildren = includeChildrenCheckbox.checked;
-          return self.saveAnnotatorsInfo(self.getAllChildrenTypesIfNeeded(elementType, includeChildren), annotators).then(function () {
-            return self.setElementType(elementType);
-          });
-        }
-      }
-    });
-    element.appendChild(copyFromButton);
-    var copyFromSelect = Functions.createElement({type: "select", style: "margin:5px"});
-    element.appendChild(copyFromSelect);
-    var options = [], i;
-    for (i = 0; i < configuration.getElementTypes().length; i++) {
-      var type = configuration.getElementTypes()[i];
-      var name = type.className;
-      if (name.indexOf(".") > 0) {
-        name = name.substr(name.lastIndexOf(".") + 1);
-      }
-      options.push(Functions.createElement({
-        type: "option",
-        value: type.className,
-        content: name
-      }));
-    }
-    options.sort(function (a, b) {
-      return a.text === b.text ? 0 : a.text < b.text ? -1 : 1
-    });
-    for (i = 0; i < options.length; i++) {
-      copyFromSelect.appendChild(options[i]);
-    }
-
-    var annotators = configuration.getElementAnnotators(elementType);
-
-    var selectedAnnotators = user.getPreferences().getElementAnnotators(elementType.className);
-
-    var entries = [];
-
-    for (i = 0; i < annotators.length; i++) {
-      var annotator = annotators[i];
-      var entry = {name: annotator.getName(), value: annotator.getClassName(), selected: false};
-      for (var j = 0; j < selectedAnnotators.length; j++) {
-        if (annotator.getName() === selectedAnnotators[j]) {
-          entry.selected = true;
-        }
-      }
-      entries.push(entry);
-    }
-    var checkboxList = new MultiCheckboxList(selectElement, {
-      entries: entries,
-      listTitle: "Available annotators",
-      selectedTitle: "Selected annotators",
-      selectedList: true
-    });
-    var changeSelection = function (elementId, selected) {
-
-      var annotators = configuration.getElementAnnotators();
-      var annotator;
-      for (var i = 0; i < annotators.length; i++) {
-        if (elementId === annotators[i].getClassName()) {
-          annotator = annotators[i];
-        }
-      }
-      if (selected) {
-        selectedAnnotators.push(annotator.getName());
-      } else {
-        var index = selectedAnnotators.indexOf(annotator.getName());
-        if (index > -1) {
-          selectedAnnotators.splice(index, 1);
-        }
-      }
-      createAnnotatorsParams();
-      var includeChildren = includeChildrenCheckbox.checked;
-      return self.saveAnnotatorsInfo(self.getAllChildrenTypesIfNeeded(elementType, includeChildren), selectedAnnotators);
-    };
-    includeChildrenCheckbox.onchange = function () {
-      var includeChildren = includeChildrenCheckbox.checked;
-      return self.saveAnnotatorsInfo(self.getAllChildrenTypesIfNeeded(elementType, includeChildren), selectedAnnotators);
-    };
-
-    checkboxList.addListener("select", function (element) {
-      return changeSelection(element.value, true);
-    });
-    checkboxList.addListener("deselect", function (element) {
-      return changeSelection(element.value, false);
-    });
-
-
-    function createAnnotatorsParams() {
-
-      var existingAnnotatorsParameters = user.getPreferences().getAnnotatorsParameters();
-
-      Functions.removeChildren(annotatorsParams);
-      for (var i = 0; i < annotators.length; i++) {
-        var annotator = annotators[i];
-        for (var j = 0; j < selectedAnnotators.length; j++) {
-          if (annotator.getName() === selectedAnnotators[j]) {
-            var paramsDefs = annotator.getParametersDefinitions();
-            if (paramsDefs.length > 0) {
-
-              annotatorsParams.appendChild(Functions.createElement({
-                type: "div",
-                className: "minerva-annotators-params-header",
-                content: '<div>Available parameters</div>'
-              }));
-
-              var annotatorParams = Functions.createElement({
-                type: "div",
-                className: "minerva-annotator-params",
-                name: annotator.getClassName()
-              });
-
-              annotatorParams.appendChild(Functions.createElement({
-                type: "div",
-                className: "minerva-annotator-params-header",
-                content: annotator.getName()
-              }));
-
-              for (var k = 0; k < paramsDefs.length; k++) {
-                var param = paramsDefs[k];
-                var paramElement = Functions.createElement({
-                  type: "div",
-                  className: "minerva-annotator-param"
-                });
-
-                var paramName = Functions.createElement({
-                  type: "div",
-                  className: "minerva-annotator-param-name",
-                  content: param.name
-                });
-
-                var tooltipContainer = Functions.createElement({
-                  type: "span"
-                });
-                tooltipContainer.appendChild(Functions.createElement({
-                  type: "span",
-                  className: "glyphicon glyphicon-question-sign tooltip-icon"
-                }));
-                tooltipContainer.appendChild(Functions.createElement({
-                  type: "span",
-                  className: "annotator-tooltip",
-                  content: param.description
-                }));
-
-                paramName.appendChild(tooltipContainer);
-                paramElement.appendChild(paramName);
-
-                var paramValue;
-
-                var existingParamValue;
-                if (existingAnnotatorsParameters[annotator.getClassName()]) {
-                  existingParamValue = existingAnnotatorsParameters[annotator.getClassName()][param.name]
-                }
-
-                if (param.type.indexOf("String") >= 0) {
-                  paramValue = Functions.createElement({
-                    type: "textarea",
-                    onchange: function () {
-                      return onChangeParameterValue(this, user);
-                    }
-                  });
-                  if (existingParamValue) paramValue.value = existingParamValue;
-                } else if (param.type.indexOf("Integer") >= 0) {
-                  paramValue = Functions.createElement({
-                    type: "input",
-                    inputType: "number",
-                    onchange: function () {
-                      return onChangeParameterValue(this, user);
-                    }
-                  });
-                  if (existingParamValue) paramValue.value = existingParamValue;
-                } else if (param.type.indexOf("Boolean") >= 0) {
-                  paramValue = Functions.createElement({
-                    type: "input",
-                    inputType: "checkbox",
-                    onchange: function () {
-                      return onChangeParameterValue(this, user);
-                    }
-                  });
-                  paramValue.checked = (existingParamValue && existingParamValue === 'true');
-                } else {
-                  throw new Error("Unknown annotator parameter type");
-                }
-
-                paramElement.appendChild(paramValue);
-                annotatorParams.appendChild(paramElement);
-              }
-
-              annotatorsParams.appendChild(annotatorParams);
-            }
-          }
-        }
-      }
-    }
-
-    createAnnotatorsParams();
-
-  });
-
-};
-
-ChooseAnnotatorsDialog.prototype.init = function () {
-  var self = this;
-  return ServerConnector.getConfiguration().then(function (configuration) {
-
-    var treeData = configuration.getElementTypeTree();
-
-    var element = $('[name="elementTree"]', self.getElement());
-    element.jstree({
-      core: {
-        data: treeData
-      }
-    }).on('ready.jstree', function () {
-      element.jstree("open_all");
-    }).on("select_node.jstree",
-      function (evt, data) {
-        return self.setElementType(data.node.data);
-      }
-    );
-  });
-};
-
-ChooseAnnotatorsDialog.prototype.destroy = function () {
-  $(this.getElement()).dialog("destroy");
-};
-
-ChooseAnnotatorsDialog.prototype.open = function () {
-  var self = this;
-  var div = self.getElement();
-  if (!$(div).hasClass("ui-dialog-content")) {
-    $(div).dialog({
-      title: "Select annotators",
-      modal: true,
-      width: window.innerWidth / 2,
-      height: window.innerHeight / 2
-
-    });
-  }
-  $(div).dialog("open");
-  $(div).css("overflow", "hidden");
-};
-
-module.exports = ChooseAnnotatorsDialog;
+"use strict";
+
+/* exported logger */
+
+var AbstractAnnotatorsDialog = require('./AbstractAnnotatorsDialog');
+var GuiConnector = require("../../GuiConnector");
+var MultiCheckboxList = require("multi-checkbox-list");
+var UserPreferences = require("../../map/data/UserPreferences");
+
+var Functions = require('../../Functions');
+// noinspection JSUnusedLocalSymbols
+var logger = require('../../logger');
+
+function ChooseAnnotatorsDialog(params) {
+  AbstractAnnotatorsDialog.call(this, params);
+  var self = this;
+  self.createGui();
+}
+
+ChooseAnnotatorsDialog.prototype = Object.create(AbstractAnnotatorsDialog.prototype);
+ChooseAnnotatorsDialog.prototype.constructor = ChooseAnnotatorsDialog;
+
+ChooseAnnotatorsDialog.prototype.createGui = function () {
+  var self = this;
+  var content = Functions.createElement({
+    type: "div",
+    style: "display:table;height:100%;width:100%"
+  });
+  content.appendChild(Functions.createElement({
+    type: "div",
+    style: "display:table-cell;height:100%;",
+    content: "<div name='elementTree' style='height:100%;overflow-y:scroll;'/>",
+    xss: false
+  }));
+
+  var annotatorsDiv = Functions.createElement({
+    type: "div",
+    style: "display:table-cell;width:100%",
+    content: "<div style='height:100%;width:100%;overflow-y:auto;'><div name='annotatorListBox'></div><div class='minerva-annotators-params'></div></div>",
+    xss: false
+  });
+  content.appendChild(annotatorsDiv);
+
+  self.getElement().appendChild(content);
+};
+
+function onChangeParameterValue(element, user) {
+  var name = $(element).siblings(".minerva-annotator-param-name")[0].childNodes[0].nodeValue;
+  var annotatorClassName = $(element).parent().parent().attr('name');
+
+  var data = new UserPreferences();
+
+  var annotatorsParams = {};
+  annotatorsParams[annotatorClassName] = {};
+  if (element.type == 'checkbox') annotatorsParams[annotatorClassName][name] = element.checked.toString();
+  else annotatorsParams[annotatorClassName][name] = element.value;
+  data.setAnnotatorsParameters(annotatorsParams);
+
+  return ServerConnector.updateUserPreferences({user: user, preferences: data}).then(null, GuiConnector.alert);
+}
+
+ChooseAnnotatorsDialog.prototype.saveAnnotatorsInfo = function (elementTypes, selectedAnnotators) {
+  selectedAnnotators = selectedAnnotators.slice();
+  return ServerConnector.getLoggedUser().then(function (user) {
+
+    var data = new UserPreferences();
+
+    var elementAnnotators = {};
+    for (var i = 0; i < elementTypes.length; i++) {
+      elementAnnotators[elementTypes[i].className] = selectedAnnotators;
+
+      var userAnnotators = user.getPreferences().getElementAnnotators(elementTypes[i].className);
+      userAnnotators.length = 0;
+      userAnnotators.push.apply(userAnnotators, selectedAnnotators);
+    }
+    data.setElementAnnotators(elementAnnotators);
+    return ServerConnector.updateUserPreferences({
+      user: user,
+      preferences: data
+    });
+  }).catch(GuiConnector.alert);
+};
+
+ChooseAnnotatorsDialog.prototype.setElementType = function (elementType) {
+  var self = this;
+
+  var configuration = self.getConfiguration();
+
+  return ServerConnector.getLoggedUser().then(function (user) {
+    var element = $("[name='annotatorListBox']", self.getElement())[0];
+    var annotatorsParams = $(".minerva-annotators-params", self.getElement())[0];
+    Functions.removeChildren(element);
+
+    var selectElement = Functions.createElement({
+      type: "div",
+      style: "width:50%; height:200px;float:left; OVERFLOW-Y:scroll"
+    });
+
+    element.appendChild(selectElement);
+    var includeChildrenCheckbox = Functions.createElement({type: "input", inputType: "checkbox"});
+    element.appendChild(includeChildrenCheckbox);
+    element.appendChild(Functions.createElement({type: "span", content: "Apply to all in subtree"}));
+    element.appendChild(Functions.createElement({type: "br"}));
+    var copyFromButton = Functions.createElement({
+      type: "button", content: "Copy from", onclick: function () {
+        var typeClassName = copyFromSelect.value;
+        var annotators;
+        for (var i = 0; i < configuration.getElementTypes().length; i++) {
+          var type = configuration.getElementTypes()[i];
+          if (typeClassName === type.className) {
+            annotators = user.getPreferences().getElementAnnotators(typeClassName);
+          }
+        }
+        if (annotators === undefined) {
+          return GuiConnector.alert("Invalid element type: " + copyFromSelect.value);
+        } else {
+          var includeChildren = includeChildrenCheckbox.checked;
+          return self.saveAnnotatorsInfo(self.getAllChildrenTypesIfNeeded(elementType, includeChildren), annotators).then(function () {
+            return self.setElementType(elementType);
+          });
+        }
+      }
+    });
+    element.appendChild(copyFromButton);
+    var copyFromSelect = Functions.createElement({type: "select", style: "margin:5px"});
+    element.appendChild(copyFromSelect);
+    var options = [], i;
+    for (i = 0; i < configuration.getElementTypes().length; i++) {
+      var type = configuration.getElementTypes()[i];
+      var name = type.className;
+      if (name.indexOf(".") > 0) {
+        name = name.substr(name.lastIndexOf(".") + 1);
+      }
+      options.push(Functions.createElement({
+        type: "option",
+        value: type.className,
+        content: name
+      }));
+    }
+    options.sort(function (a, b) {
+      return a.text === b.text ? 0 : a.text < b.text ? -1 : 1
+    });
+    for (i = 0; i < options.length; i++) {
+      copyFromSelect.appendChild(options[i]);
+    }
+
+    var annotators = configuration.getElementAnnotators(elementType);
+
+    var selectedAnnotators = user.getPreferences().getElementAnnotators(elementType.className);
+
+    var entries = [];
+
+    for (i = 0; i < annotators.length; i++) {
+      var annotator = annotators[i];
+      var entry = {name: annotator.getName(), value: annotator.getClassName(), selected: false};
+      for (var j = 0; j < selectedAnnotators.length; j++) {
+        if (annotator.getName() === selectedAnnotators[j]) {
+          entry.selected = true;
+        }
+      }
+      entries.push(entry);
+    }
+    var checkboxList = new MultiCheckboxList(selectElement, {
+      entries: entries,
+      listTitle: "Available annotators",
+      selectedTitle: "Selected annotators",
+      selectedList: true
+    });
+    var changeSelection = function (elementId, selected) {
+
+      var annotators = configuration.getElementAnnotators();
+      var annotator;
+      for (var i = 0; i < annotators.length; i++) {
+        if (elementId === annotators[i].getClassName()) {
+          annotator = annotators[i];
+        }
+      }
+      if (selected) {
+        selectedAnnotators.push(annotator.getName());
+      } else {
+        var index = selectedAnnotators.indexOf(annotator.getName());
+        if (index > -1) {
+          selectedAnnotators.splice(index, 1);
+        }
+      }
+      createAnnotatorsParams();
+      var includeChildren = includeChildrenCheckbox.checked;
+      return self.saveAnnotatorsInfo(self.getAllChildrenTypesIfNeeded(elementType, includeChildren), selectedAnnotators);
+    };
+    includeChildrenCheckbox.onchange = function () {
+      var includeChildren = includeChildrenCheckbox.checked;
+      return self.saveAnnotatorsInfo(self.getAllChildrenTypesIfNeeded(elementType, includeChildren), selectedAnnotators);
+    };
+
+    checkboxList.addListener("select", function (element) {
+      return changeSelection(element.value, true);
+    });
+    checkboxList.addListener("deselect", function (element) {
+      return changeSelection(element.value, false);
+    });
+
+
+    function createAnnotatorsParams() {
+
+      var existingAnnotatorsParameters = user.getPreferences().getAnnotatorsParameters();
+
+      Functions.removeChildren(annotatorsParams);
+      for (var i = 0; i < annotators.length; i++) {
+        var annotator = annotators[i];
+        for (var j = 0; j < selectedAnnotators.length; j++) {
+          if (annotator.getName() === selectedAnnotators[j]) {
+            var paramsDefs = annotator.getParametersDefinitions();
+            if (paramsDefs.length > 0) {
+
+              annotatorsParams.appendChild(Functions.createElement({
+                type: "div",
+                className: "minerva-annotators-params-header",
+                content: '<div>Available parameters</div>'
+              }));
+
+              var annotatorParams = Functions.createElement({
+                type: "div",
+                className: "minerva-annotator-params",
+                name: annotator.getClassName()
+              });
+
+              annotatorParams.appendChild(Functions.createElement({
+                type: "div",
+                className: "minerva-annotator-params-header",
+                content: annotator.getName()
+              }));
+
+              for (var k = 0; k < paramsDefs.length; k++) {
+                var param = paramsDefs[k];
+                var paramElement = Functions.createElement({
+                  type: "div",
+                  className: "minerva-annotator-param"
+                });
+
+                var paramName = Functions.createElement({
+                  type: "div",
+                  className: "minerva-annotator-param-name",
+                  content: param.name
+                });
+
+                var tooltipContainer = Functions.createElement({
+                  type: "span"
+                });
+                tooltipContainer.appendChild(Functions.createElement({
+                  type: "span",
+                  className: "glyphicon glyphicon-question-sign tooltip-icon"
+                }));
+                tooltipContainer.appendChild(Functions.createElement({
+                  type: "span",
+                  className: "annotator-tooltip",
+                  content: param.description
+                }));
+
+                paramName.appendChild(tooltipContainer);
+                paramElement.appendChild(paramName);
+
+                var paramValue;
+
+                var existingParamValue;
+                if (existingAnnotatorsParameters[annotator.getClassName()]) {
+                  existingParamValue = existingAnnotatorsParameters[annotator.getClassName()][param.name]
+                }
+
+                if (param.type.indexOf("String") >= 0) {
+                  paramValue = Functions.createElement({
+                    type: "textarea",
+                    onchange: function () {
+                      return onChangeParameterValue(this, user);
+                    }
+                  });
+                  if (existingParamValue) paramValue.value = existingParamValue;
+                } else if (param.type.indexOf("Integer") >= 0) {
+                  paramValue = Functions.createElement({
+                    type: "input",
+                    inputType: "number",
+                    onchange: function () {
+                      return onChangeParameterValue(this, user);
+                    }
+                  });
+                  if (existingParamValue) paramValue.value = existingParamValue;
+                } else if (param.type.indexOf("Boolean") >= 0) {
+                  paramValue = Functions.createElement({
+                    type: "input",
+                    inputType: "checkbox",
+                    onchange: function () {
+                      return onChangeParameterValue(this, user);
+                    }
+                  });
+                  paramValue.checked = (existingParamValue && existingParamValue === 'true');
+                } else {
+                  throw new Error("Unknown annotator parameter type");
+                }
+
+                paramElement.appendChild(paramValue);
+                annotatorParams.appendChild(paramElement);
+              }
+
+              annotatorsParams.appendChild(annotatorParams);
+            }
+          }
+        }
+      }
+    }
+
+    createAnnotatorsParams();
+
+  });
+
+};
+
+ChooseAnnotatorsDialog.prototype.init = function () {
+  var self = this;
+  return ServerConnector.getConfiguration().then(function (configuration) {
+
+    var treeData = configuration.getElementTypeTree();
+
+    var element = $('[name="elementTree"]', self.getElement());
+    element.jstree({
+      core: {
+        data: treeData
+      }
+    }).on('ready.jstree', function () {
+      element.jstree("open_all");
+    }).on("select_node.jstree",
+      function (evt, data) {
+        return self.setElementType(data.node.data);
+      }
+    );
+  });
+};
+
+ChooseAnnotatorsDialog.prototype.destroy = function () {
+  $(this.getElement()).dialog("destroy");
+};
+
+ChooseAnnotatorsDialog.prototype.open = function () {
+  var self = this;
+  var div = self.getElement();
+  if (!$(div).hasClass("ui-dialog-content")) {
+    $(div).dialog({
+      title: "Select annotators",
+      modal: true,
+      width: window.innerWidth / 2,
+      height: window.innerHeight / 2
+
+    });
+  }
+  $(div).dialog("open");
+  $(div).css("overflow", "hidden");
+};
+
+module.exports = ChooseAnnotatorsDialog;
diff --git a/frontend-js/src/main/js/gui/admin/ChooseValidatorsDialog.js b/frontend-js/src/main/js/gui/admin/ChooseValidatorsDialog.js
index 2e5e45c36fff45804aa80ec812d79223817e0455..10f77ba75aa204312d8f2b37d2e0d721a209f778 100644
--- a/frontend-js/src/main/js/gui/admin/ChooseValidatorsDialog.js
+++ b/frontend-js/src/main/js/gui/admin/ChooseValidatorsDialog.js
@@ -1,409 +1,409 @@
-"use strict";
-
-/* exported logger */
-
-var AbstractAnnotatorsDialog = require('./AbstractAnnotatorsDialog');
-var GuiConnector = require("../../GuiConnector");
-var UserPreferences = require("../../map/data/UserPreferences");
-var MultiCheckboxList = require("multi-checkbox-list");
-
-var Functions = require('../../Functions');
-// noinspection JSUnusedLocalSymbols
-var logger = require('../../logger');
-
-/**
- *
- /**
- *
- * @param {Object} params
- * @param {HTMLElement} params.element
- * @param {CustomMap} params.customMap
- * @param {Configuration} [params.configuration]
- * @param {ServerConnector} [params.serverConnector]
- *
- * @constructor
- *
- * @extends AbstractGuiElement
- */
-function ChooseValidatorsDialog(params) {
-  AbstractAnnotatorsDialog.call(this, params);
-  var self = this;
-  self.createGui();
-}
-
-ChooseValidatorsDialog.prototype = Object.create(AbstractAnnotatorsDialog.prototype);
-ChooseValidatorsDialog.prototype.constructor = ChooseValidatorsDialog;
-
-/**
- *
- */
-ChooseValidatorsDialog.prototype.createGui = function () {
-  var self = this;
-  var content = Functions.createElement({
-    type: "div",
-    style: "display:table;height:100%;width:100%"
-  });
-  content.appendChild(Functions.createElement({
-    type: "div",
-    style: "display:table-cell;height:100%;",
-    content: "<div name='elementTree' style='height:100%;overflow-y:scroll;'/>",
-    xss: false
-  }));
-
-  content.appendChild(Functions.createElement({
-    type: "div",
-    style: "display:table-cell;height:100%;width:100%;",
-    content: "<div name='annotatorListBox' style='height:100%;width:100%;overflow-y:auto;'><span> </span></div>",
-    xss: false
-  }));
-
-  self.getElement().appendChild(content);
-};
-
-/**
- *
- * @param {BioEntityType} elementType
- * @returns {Promise}
- */
-ChooseValidatorsDialog.prototype.setElementType = function (elementType) {
-  var self = this;
-
-  var configuration;
-
-  return self.getServerConnector().getConfiguration().then(function (result) {
-    configuration = result;
-    return self.getServerConnector().getLoggedUser();
-  }).then(function (user) {
-    var element = $("[name='annotatorListBox']", self.getElement())[0];
-    Functions.removeChildren(element);
-
-    var validAnnotationSelect = Functions.createElement({
-      type: "select",
-      className: "minerva-multi-select"
-    });
-    element.appendChild(validAnnotationSelect);
-    self.createValidAnnotationsDualListBox(user, configuration, elementType, validAnnotationSelect);
-
-    var verifyAnnotationSelect = Functions.createElement({
-      type: "select",
-      className: "minerva-multi-select"
-    });
-    element.appendChild(verifyAnnotationSelect);
-    self.createVerifyAnnotationsDualListBox(user, configuration, elementType, verifyAnnotationSelect);
-
-    element.appendChild(Functions.createElement({type: "br"}));
-    var includeChildrenCheckbox = Functions.createElement({type: "input", inputType: "checkbox"});
-    var copyFromButton = Functions.createElement({
-      type: "button", content: "Copy from", name: "copy-from-validator", onclick: function () {
-        var typeClassName = copyFromSelect.value;
-        var requiredAnnotations, validAnnotators;
-        for (var i = 0; i < configuration.getElementTypes().length; i++) {
-          var type = configuration.getElementTypes()[i];
-          if (typeClassName === type.className) {
-            requiredAnnotations = user.getPreferences().getElementRequiredAnnotations(typeClassName);
-            validAnnotators = user.getPreferences().getElementValidAnnotations(typeClassName);
-          }
-        }
-        if (requiredAnnotations === undefined) {
-          return GuiConnector.alert("Invalid element type: " + copyFromSelect.value);
-        } else {
-          var includeChildren = includeChildrenCheckbox.checked;
-          return self.saveAnnotationsInfo({
-            elementTypes: self.getAllChildrenTypesIfNeeded(elementType, includeChildren),
-            requiredAnnotators: requiredAnnotations,
-            validAnnotators: validAnnotators
-          }).then(function () {
-            return self.setElementType(elementType);
-          });
-        }
-      }
-    });
-    element.appendChild(copyFromButton);
-    var copyFromSelect = Functions.createElement({type: "select", style: "margin:5px"});
-    element.appendChild(copyFromSelect);
-    var options = [], i;
-    for (i = 0; i < configuration.getElementTypes().length; i++) {
-      var type = configuration.getElementTypes()[i];
-      var name = type.className;
-      if (name.indexOf(".") > 0) {
-        name = name.substr(name.lastIndexOf(".") + 1);
-      }
-      options.push(Functions.createElement({
-        type: "option",
-        value: type.className,
-        content: name
-      }));
-    }
-    options.sort(function (a, b) {
-      return a.text === b.text ? 0 : a.text < b.text ? -1 : 1
-    });
-    for (i = 0; i < options.length; i++) {
-      copyFromSelect.appendChild(options[i]);
-    }
-    element.appendChild(includeChildrenCheckbox);
-    element.appendChild(Functions.createElement({type: "span", content: "Apply to all in subtree"}));
-
-  });
-
-};
-
-/**
- *
- * @param {BioEntityType[]} params.elementTypes
- * @param {{list:string[], requiredAtLeastOnce:boolean}} params.requiredAnnotators
- * @param {string[]} params.validAnnotators
- *
- * @returns {Promise}
- */
-ChooseValidatorsDialog.prototype.saveAnnotationsInfo = function (params) {
-  var elementTypes = params.elementTypes;
-  var requiredAnnotators = params.requiredAnnotators;
-  var validAnnotators = params.validAnnotators;
-  var self = this;
-  return self.getServerConnector().getLoggedUser().then(function (user) {
-
-    var data = new UserPreferences();
-
-    var elementRequiredAnnotators = {};
-    var elementValidAnnotators = {};
-    for (var i = 0; i < elementTypes.length; i++) {
-      elementRequiredAnnotators[elementTypes[i].className] = {
-        "require-at-least-one": requiredAnnotators.requiredAtLeastOnce,
-        "annotation-list": requiredAnnotators.list.slice()
-      };
-      elementValidAnnotators[elementTypes[i].className] = validAnnotators.slice();
-    }
-    data.setElementRequiredAnnotations(elementRequiredAnnotators);
-    data.setElementValidAnnotations(elementValidAnnotators);
-    return self.getServerConnector().updateUserPreferences({
-      user: user,
-      preferences: data
-    });
-  }).catch(GuiConnector.alert);
-};
-
-
-/**
- *
- * @param {User} user
- * @param {Configuration} configuration
- * @param {BioEntityType} elementType
- * @param {HTMLElement} validAnnotationSelect
- */
-ChooseValidatorsDialog.prototype.createValidAnnotationsDualListBox = function (user, configuration, elementType, validAnnotationSelect) {
-  var self = this;
-
-  var miriamTypes = configuration.getMiriamTypes();
-
-  var validAnnotations = user.getPreferences().getElementValidAnnotations(elementType.className);
-
-  var entries = [];
-
-
-  for (var i = 0; i < miriamTypes.length; i++) {
-    var miriamType = miriamTypes[i];
-    var entry = {name: miriamType.getCommonName(), value: miriamType.getName(), selected: false};
-
-    for (var j = 0; j < validAnnotations.length; j++) {
-      if (miriamType.getName() === validAnnotations[j]) {
-        entry.selected = true;
-      }
-    }
-    entries.push(entry);
-  }
-
-  var checkboxList = new MultiCheckboxList(validAnnotationSelect, {
-    entries: entries,
-    listTitle: "Available",
-    selectedTitle: "Selected",
-    selectedList: true
-  });
-
-  var changeSelection = function (elementId, selected) {
-    var miriamTypes = configuration.getMiriamTypes();
-    var miriamType;
-    for (var i = 0; i < miriamTypes.length; i++) {
-      if (elementId === miriamTypes[i].getName()) {
-        miriamType = miriamTypes[i];
-      }
-    }
-    if (selected) {
-      validAnnotations.push(miriamType.getName());
-    } else {
-      var index = validAnnotations.indexOf(miriamType.getName());
-      if (index > -1) {
-        validAnnotations.splice(index, 1);
-      }
-    }
-
-    var data = new UserPreferences();
-
-    var elementAnnotators = {};
-    elementAnnotators[elementType.className] = validAnnotations;
-    data.setElementValidAnnotations(elementAnnotators);
-    return self.getServerConnector().updateUserPreferences({
-      user: user,
-      preferences: data
-    }).catch(GuiConnector.alert);
-  };
-
-  checkboxList.addListener("select", function (element) {
-    return changeSelection(element.value, true);
-  });
-  checkboxList.addListener("deselect", function (element) {
-    return changeSelection(element.value, false);
-  });
-
-};
-
-/**
- *
- * @param {User} user
- * @param {Configuration} configuration
- * @param {BioEntityType} elementType
- * @param {HTMLElement} verifyAnnotationSelect
- */
-
-ChooseValidatorsDialog.prototype.createVerifyAnnotationsDualListBox = function (user, configuration, elementType, verifyAnnotationSelect) {
-  var self = this;
-  var requiredAnnotationsData = user.getPreferences().getElementRequiredAnnotations(elementType.className);
-
-  var verifyCheckboxDiv = Functions.createElement({type: "div"});
-  var checkbox = Functions.createElement({
-    type: "input",
-    inputType: "checkbox",
-    name: "require-at-least-one-checkbox",
-    onclick: function () {
-      var data = new UserPreferences();
-
-      var elementRequiredAnnotations = {};
-      elementRequiredAnnotations[elementType.className] = {
-        "require-at-least-one": checkbox.checked,
-        "annotation-list": requiredAnnotationsData.list
-      };
-      data.setElementRequiredAnnotations(elementRequiredAnnotations);
-      return self.getServerConnector().updateUserPreferences({user: user, preferences: data}).catch(GuiConnector.alert);
-    }
-  });
-  checkbox.checked = requiredAnnotationsData.requiredAtLeastOnce;
-  verifyCheckboxDiv.appendChild(Functions.createElement({type: "br"}));
-  verifyCheckboxDiv.appendChild(Functions.createElement({type: "br"}));
-  verifyCheckboxDiv.appendChild(checkbox);
-  verifyCheckboxDiv.appendChild(Functions.createElement({
-    type: "span",
-    content: "One of these miriam should be required"
-  }));
-  verifyAnnotationSelect.parentNode.insertBefore(verifyCheckboxDiv, verifyAnnotationSelect);
-
-  var miriamTypes = configuration.getMiriamTypes();
-
-  var entries = [];
-
-  for (var i = 0; i < miriamTypes.length; i++) {
-    var miriamType = miriamTypes[i];
-    var entry = {name: miriamType.getCommonName(), value: miriamType.getName(), selected: false};
-    for (var j = 0; j < requiredAnnotationsData.list.length; j++) {
-      if (miriamType.getName() === requiredAnnotationsData.list[j]) {
-        entry.selected = true;
-      }
-    }
-    entries.push(entry);
-  }
-
-  var checkboxList = new MultiCheckboxList(verifyAnnotationSelect, {
-    entries: entries,
-    listTitle: "Available",
-    selectedTitle: "Selected",
-    selectedList: true
-  });
-
-  var changeSelection = function (elementId, selected) {
-
-    var miriamTypes = configuration.getMiriamTypes();
-    var miriamType;
-    for (var i = 0; i < miriamTypes.length; i++) {
-      if (elementId === miriamTypes[i].getName()) {
-        miriamType = miriamTypes[i];
-      }
-    }
-    if (selected) {
-      requiredAnnotationsData.list.push(miriamType.getName());
-    } else {
-      var index = requiredAnnotationsData.list.indexOf(miriamType.getName());
-      if (index > -1) {
-        requiredAnnotationsData.list.splice(index, 1);
-      }
-    }
-
-    var data = new UserPreferences();
-
-    var elementRequiredAnnotations = {};
-    elementRequiredAnnotations[elementType.className] = {
-      "require-at-least-one": requiredAnnotationsData.requiredAtLeastOnce,
-      "annotation-list": requiredAnnotationsData.list
-    };
-    data.setElementRequiredAnnotations(elementRequiredAnnotations);
-    return self.getServerConnector().updateUserPreferences({user: user, preferences: data}).catch(GuiConnector.alert);
-  };
-
-  checkboxList.addListener("select", function (element) {
-    return changeSelection(element.value, true);
-  });
-  checkboxList.addListener("deselect", function (element) {
-    return changeSelection(element.value, false);
-  });
-
-};
-
-/**
- *
- * @returns {Promise}
- */
-ChooseValidatorsDialog.prototype.init = function () {
-  var self = this;
-  return self.getServerConnector().getConfiguration().then(function (configuration) {
-
-    var treeData = configuration.getElementTypeTree();
-
-    var element = $('[name="elementTree"]', self.getElement());
-    element.jstree({
-      core: {
-        data: treeData
-      }
-    }).on('ready.jstree', function () {
-      element.jstree("open_all");
-    }).on("select_node.jstree",
-      function (evt, data) {
-        return self.setElementType(data.node.data);
-      }
-    );
-  });
-};
-
-/**
- *
- */
-ChooseValidatorsDialog.prototype.destroy = function () {
-  $(this.getElement()).dialog("destroy");
-};
-
-/**
- *
- */
-ChooseValidatorsDialog.prototype.open = function () {
-  var self = this;
-  var div = self.getElement();
-  if (!$(div).hasClass("ui-dialog-content")) {
-    $(div).dialog({
-      title: "Select valid annotations",
-      modal: true,
-      width: window.innerWidth / 2,
-      height: window.innerHeight / 2
-
-    });
-  }
-
-  $(div).dialog("open");
-};
-
-module.exports = ChooseValidatorsDialog;
+"use strict";
+
+/* exported logger */
+
+var AbstractAnnotatorsDialog = require('./AbstractAnnotatorsDialog');
+var GuiConnector = require("../../GuiConnector");
+var UserPreferences = require("../../map/data/UserPreferences");
+var MultiCheckboxList = require("multi-checkbox-list");
+
+var Functions = require('../../Functions');
+// noinspection JSUnusedLocalSymbols
+var logger = require('../../logger');
+
+/**
+ *
+ /**
+ *
+ * @param {Object} params
+ * @param {HTMLElement} params.element
+ * @param {CustomMap} params.customMap
+ * @param {Configuration} [params.configuration]
+ * @param {ServerConnector} [params.serverConnector]
+ *
+ * @constructor
+ *
+ * @extends AbstractGuiElement
+ */
+function ChooseValidatorsDialog(params) {
+  AbstractAnnotatorsDialog.call(this, params);
+  var self = this;
+  self.createGui();
+}
+
+ChooseValidatorsDialog.prototype = Object.create(AbstractAnnotatorsDialog.prototype);
+ChooseValidatorsDialog.prototype.constructor = ChooseValidatorsDialog;
+
+/**
+ *
+ */
+ChooseValidatorsDialog.prototype.createGui = function () {
+  var self = this;
+  var content = Functions.createElement({
+    type: "div",
+    style: "display:table;height:100%;width:100%"
+  });
+  content.appendChild(Functions.createElement({
+    type: "div",
+    style: "display:table-cell;height:100%;",
+    content: "<div name='elementTree' style='height:100%;overflow-y:scroll;'/>",
+    xss: false
+  }));
+
+  content.appendChild(Functions.createElement({
+    type: "div",
+    style: "display:table-cell;height:100%;width:100%;",
+    content: "<div name='annotatorListBox' style='height:100%;width:100%;overflow-y:auto;'><span> </span></div>",
+    xss: false
+  }));
+
+  self.getElement().appendChild(content);
+};
+
+/**
+ *
+ * @param {BioEntityType} elementType
+ * @returns {Promise}
+ */
+ChooseValidatorsDialog.prototype.setElementType = function (elementType) {
+  var self = this;
+
+  var configuration;
+
+  return self.getServerConnector().getConfiguration().then(function (result) {
+    configuration = result;
+    return self.getServerConnector().getLoggedUser();
+  }).then(function (user) {
+    var element = $("[name='annotatorListBox']", self.getElement())[0];
+    Functions.removeChildren(element);
+
+    var validAnnotationSelect = Functions.createElement({
+      type: "select",
+      className: "minerva-multi-select"
+    });
+    element.appendChild(validAnnotationSelect);
+    self.createValidAnnotationsDualListBox(user, configuration, elementType, validAnnotationSelect);
+
+    var verifyAnnotationSelect = Functions.createElement({
+      type: "select",
+      className: "minerva-multi-select"
+    });
+    element.appendChild(verifyAnnotationSelect);
+    self.createVerifyAnnotationsDualListBox(user, configuration, elementType, verifyAnnotationSelect);
+
+    element.appendChild(Functions.createElement({type: "br"}));
+    var includeChildrenCheckbox = Functions.createElement({type: "input", inputType: "checkbox"});
+    var copyFromButton = Functions.createElement({
+      type: "button", content: "Copy from", name: "copy-from-validator", onclick: function () {
+        var typeClassName = copyFromSelect.value;
+        var requiredAnnotations, validAnnotators;
+        for (var i = 0; i < configuration.getElementTypes().length; i++) {
+          var type = configuration.getElementTypes()[i];
+          if (typeClassName === type.className) {
+            requiredAnnotations = user.getPreferences().getElementRequiredAnnotations(typeClassName);
+            validAnnotators = user.getPreferences().getElementValidAnnotations(typeClassName);
+          }
+        }
+        if (requiredAnnotations === undefined) {
+          return GuiConnector.alert("Invalid element type: " + copyFromSelect.value);
+        } else {
+          var includeChildren = includeChildrenCheckbox.checked;
+          return self.saveAnnotationsInfo({
+            elementTypes: self.getAllChildrenTypesIfNeeded(elementType, includeChildren),
+            requiredAnnotators: requiredAnnotations,
+            validAnnotators: validAnnotators
+          }).then(function () {
+            return self.setElementType(elementType);
+          });
+        }
+      }
+    });
+    element.appendChild(copyFromButton);
+    var copyFromSelect = Functions.createElement({type: "select", style: "margin:5px"});
+    element.appendChild(copyFromSelect);
+    var options = [], i;
+    for (i = 0; i < configuration.getElementTypes().length; i++) {
+      var type = configuration.getElementTypes()[i];
+      var name = type.className;
+      if (name.indexOf(".") > 0) {
+        name = name.substr(name.lastIndexOf(".") + 1);
+      }
+      options.push(Functions.createElement({
+        type: "option",
+        value: type.className,
+        content: name
+      }));
+    }
+    options.sort(function (a, b) {
+      return a.text === b.text ? 0 : a.text < b.text ? -1 : 1
+    });
+    for (i = 0; i < options.length; i++) {
+      copyFromSelect.appendChild(options[i]);
+    }
+    element.appendChild(includeChildrenCheckbox);
+    element.appendChild(Functions.createElement({type: "span", content: "Apply to all in subtree"}));
+
+  });
+
+};
+
+/**
+ *
+ * @param {BioEntityType[]} params.elementTypes
+ * @param {{list:string[], requiredAtLeastOnce:boolean}} params.requiredAnnotators
+ * @param {string[]} params.validAnnotators
+ *
+ * @returns {Promise}
+ */
+ChooseValidatorsDialog.prototype.saveAnnotationsInfo = function (params) {
+  var elementTypes = params.elementTypes;
+  var requiredAnnotators = params.requiredAnnotators;
+  var validAnnotators = params.validAnnotators;
+  var self = this;
+  return self.getServerConnector().getLoggedUser().then(function (user) {
+
+    var data = new UserPreferences();
+
+    var elementRequiredAnnotators = {};
+    var elementValidAnnotators = {};
+    for (var i = 0; i < elementTypes.length; i++) {
+      elementRequiredAnnotators[elementTypes[i].className] = {
+        "require-at-least-one": requiredAnnotators.requiredAtLeastOnce,
+        "annotation-list": requiredAnnotators.list.slice()
+      };
+      elementValidAnnotators[elementTypes[i].className] = validAnnotators.slice();
+    }
+    data.setElementRequiredAnnotations(elementRequiredAnnotators);
+    data.setElementValidAnnotations(elementValidAnnotators);
+    return self.getServerConnector().updateUserPreferences({
+      user: user,
+      preferences: data
+    });
+  }).catch(GuiConnector.alert);
+};
+
+
+/**
+ *
+ * @param {User} user
+ * @param {Configuration} configuration
+ * @param {BioEntityType} elementType
+ * @param {HTMLElement} validAnnotationSelect
+ */
+ChooseValidatorsDialog.prototype.createValidAnnotationsDualListBox = function (user, configuration, elementType, validAnnotationSelect) {
+  var self = this;
+
+  var miriamTypes = configuration.getMiriamTypes();
+
+  var validAnnotations = user.getPreferences().getElementValidAnnotations(elementType.className);
+
+  var entries = [];
+
+
+  for (var i = 0; i < miriamTypes.length; i++) {
+    var miriamType = miriamTypes[i];
+    var entry = {name: miriamType.getCommonName(), value: miriamType.getName(), selected: false};
+
+    for (var j = 0; j < validAnnotations.length; j++) {
+      if (miriamType.getName() === validAnnotations[j]) {
+        entry.selected = true;
+      }
+    }
+    entries.push(entry);
+  }
+
+  var checkboxList = new MultiCheckboxList(validAnnotationSelect, {
+    entries: entries,
+    listTitle: "Available",
+    selectedTitle: "Selected",
+    selectedList: true
+  });
+
+  var changeSelection = function (elementId, selected) {
+    var miriamTypes = configuration.getMiriamTypes();
+    var miriamType;
+    for (var i = 0; i < miriamTypes.length; i++) {
+      if (elementId === miriamTypes[i].getName()) {
+        miriamType = miriamTypes[i];
+      }
+    }
+    if (selected) {
+      validAnnotations.push(miriamType.getName());
+    } else {
+      var index = validAnnotations.indexOf(miriamType.getName());
+      if (index > -1) {
+        validAnnotations.splice(index, 1);
+      }
+    }
+
+    var data = new UserPreferences();
+
+    var elementAnnotators = {};
+    elementAnnotators[elementType.className] = validAnnotations;
+    data.setElementValidAnnotations(elementAnnotators);
+    return self.getServerConnector().updateUserPreferences({
+      user: user,
+      preferences: data
+    }).catch(GuiConnector.alert);
+  };
+
+  checkboxList.addListener("select", function (element) {
+    return changeSelection(element.value, true);
+  });
+  checkboxList.addListener("deselect", function (element) {
+    return changeSelection(element.value, false);
+  });
+
+};
+
+/**
+ *
+ * @param {User} user
+ * @param {Configuration} configuration
+ * @param {BioEntityType} elementType
+ * @param {HTMLElement} verifyAnnotationSelect
+ */
+
+ChooseValidatorsDialog.prototype.createVerifyAnnotationsDualListBox = function (user, configuration, elementType, verifyAnnotationSelect) {
+  var self = this;
+  var requiredAnnotationsData = user.getPreferences().getElementRequiredAnnotations(elementType.className);
+
+  var verifyCheckboxDiv = Functions.createElement({type: "div"});
+  var checkbox = Functions.createElement({
+    type: "input",
+    inputType: "checkbox",
+    name: "require-at-least-one-checkbox",
+    onclick: function () {
+      var data = new UserPreferences();
+
+      var elementRequiredAnnotations = {};
+      elementRequiredAnnotations[elementType.className] = {
+        "require-at-least-one": checkbox.checked,
+        "annotation-list": requiredAnnotationsData.list
+      };
+      data.setElementRequiredAnnotations(elementRequiredAnnotations);
+      return self.getServerConnector().updateUserPreferences({user: user, preferences: data}).catch(GuiConnector.alert);
+    }
+  });
+  checkbox.checked = requiredAnnotationsData.requiredAtLeastOnce;
+  verifyCheckboxDiv.appendChild(Functions.createElement({type: "br"}));
+  verifyCheckboxDiv.appendChild(Functions.createElement({type: "br"}));
+  verifyCheckboxDiv.appendChild(checkbox);
+  verifyCheckboxDiv.appendChild(Functions.createElement({
+    type: "span",
+    content: "One of these miriam should be required"
+  }));
+  verifyAnnotationSelect.parentNode.insertBefore(verifyCheckboxDiv, verifyAnnotationSelect);
+
+  var miriamTypes = configuration.getMiriamTypes();
+
+  var entries = [];
+
+  for (var i = 0; i < miriamTypes.length; i++) {
+    var miriamType = miriamTypes[i];
+    var entry = {name: miriamType.getCommonName(), value: miriamType.getName(), selected: false};
+    for (var j = 0; j < requiredAnnotationsData.list.length; j++) {
+      if (miriamType.getName() === requiredAnnotationsData.list[j]) {
+        entry.selected = true;
+      }
+    }
+    entries.push(entry);
+  }
+
+  var checkboxList = new MultiCheckboxList(verifyAnnotationSelect, {
+    entries: entries,
+    listTitle: "Available",
+    selectedTitle: "Selected",
+    selectedList: true
+  });
+
+  var changeSelection = function (elementId, selected) {
+
+    var miriamTypes = configuration.getMiriamTypes();
+    var miriamType;
+    for (var i = 0; i < miriamTypes.length; i++) {
+      if (elementId === miriamTypes[i].getName()) {
+        miriamType = miriamTypes[i];
+      }
+    }
+    if (selected) {
+      requiredAnnotationsData.list.push(miriamType.getName());
+    } else {
+      var index = requiredAnnotationsData.list.indexOf(miriamType.getName());
+      if (index > -1) {
+        requiredAnnotationsData.list.splice(index, 1);
+      }
+    }
+
+    var data = new UserPreferences();
+
+    var elementRequiredAnnotations = {};
+    elementRequiredAnnotations[elementType.className] = {
+      "require-at-least-one": requiredAnnotationsData.requiredAtLeastOnce,
+      "annotation-list": requiredAnnotationsData.list
+    };
+    data.setElementRequiredAnnotations(elementRequiredAnnotations);
+    return self.getServerConnector().updateUserPreferences({user: user, preferences: data}).catch(GuiConnector.alert);
+  };
+
+  checkboxList.addListener("select", function (element) {
+    return changeSelection(element.value, true);
+  });
+  checkboxList.addListener("deselect", function (element) {
+    return changeSelection(element.value, false);
+  });
+
+};
+
+/**
+ *
+ * @returns {Promise}
+ */
+ChooseValidatorsDialog.prototype.init = function () {
+  var self = this;
+  return self.getServerConnector().getConfiguration().then(function (configuration) {
+
+    var treeData = configuration.getElementTypeTree();
+
+    var element = $('[name="elementTree"]', self.getElement());
+    element.jstree({
+      core: {
+        data: treeData
+      }
+    }).on('ready.jstree', function () {
+      element.jstree("open_all");
+    }).on("select_node.jstree",
+      function (evt, data) {
+        return self.setElementType(data.node.data);
+      }
+    );
+  });
+};
+
+/**
+ *
+ */
+ChooseValidatorsDialog.prototype.destroy = function () {
+  $(this.getElement()).dialog("destroy");
+};
+
+/**
+ *
+ */
+ChooseValidatorsDialog.prototype.open = function () {
+  var self = this;
+  var div = self.getElement();
+  if (!$(div).hasClass("ui-dialog-content")) {
+    $(div).dialog({
+      title: "Select valid annotations",
+      modal: true,
+      width: window.innerWidth / 2,
+      height: window.innerHeight / 2
+
+    });
+  }
+
+  $(div).dialog("open");
+};
+
+module.exports = ChooseValidatorsDialog;
diff --git a/frontend-js/src/main/js/gui/admin/CommentsAdminPanel.js b/frontend-js/src/main/js/gui/admin/CommentsAdminPanel.js
index bfaf2efb6d1c77efb49be4211659e0acb8afbf5a..5c9f1c7791fab00acf1dc27fc94665f6da6c8e88 100644
--- a/frontend-js/src/main/js/gui/admin/CommentsAdminPanel.js
+++ b/frontend-js/src/main/js/gui/admin/CommentsAdminPanel.js
@@ -1,151 +1,151 @@
-"use strict";
-
-var AbstractGuiElement = require('../AbstractGuiElement');
-
-var Functions = require('../../Functions');
-var GuiConnector = require('../../GuiConnector');
-// noinspection JSUnusedLocalSymbols
-var logger = require('../../logger');
-
-// noinspection JSUnusedLocalSymbols
-var Promise = require("bluebird");
-var xss = require('xss');
-
-function CommentsAdminPanel(params) {
-  params.customMap = null;
-  AbstractGuiElement.call(this, params);
-
-  this._createGui();
-}
-
-CommentsAdminPanel.prototype = Object.create(AbstractGuiElement.prototype);
-CommentsAdminPanel.prototype.constructor = CommentsAdminPanel;
-
-CommentsAdminPanel.prototype._createGui = function () {
-  var self = this;
-
-  var commentsTable = Functions.createElement({
-    type: "table",
-    name: "commentsTable",
-    className: "display",
-    style: "width:100%"
-  });
-
-  self.getElement().appendChild(commentsTable);
-
-  $(commentsTable).DataTable({
-    columns: [{
-      title: 'Id'
-    }, {
-      title: 'Title'
-    }, {
-      title: 'Author'
-    }, {
-      title: 'Email'
-    }, {
-      title: 'Content'
-    }, {
-      title: 'Removed'
-    }, {
-      title: 'Pinned'
-    }]
-  });
-
-};
-
-CommentsAdminPanel.prototype.init = function () {
-  var self = this;
-  return self.refreshProjects();
-};
-
-CommentsAdminPanel.prototype.refreshComments = function () {
-  var self = this;
-
-  return ServerConnector.getComments({
-    projectId: self.getProject().getProjectId()
-  }).then(function (comments) {
-    var dataTable = $($("[name='commentsTable']", self.getElement())[0]).DataTable();
-    var data = [];
-    for (var i = 0; i < comments.length; i++) {
-      data.push(self.commentToTableRow(comments[i]));
-    }
-    dataTable.clear().rows.add(data).draw();
-    $("[name='commentsTable']", self.getElement()).on("click", "[name='removeComment']", function () {
-      var button = this;
-      return self.askConfirmRemoval({
-        title: "Why do you want to remove this comment?",
-        input: true
-      }).then(function (param) {
-        if (param.status) {
-          return ServerConnector.removeComment({
-            commentId: $(button).attr("data"),
-            reason: param.reason,
-            projectId: self.getProject().getProjectId()
-          }).then(function () {
-            $(button).after("<span>YES (" + param.reason + ")</span>");
-            button.style.display = "none";
-          });
-        }
-      }).catch(GuiConnector.alert)
-    });
-  });
-};
-
-CommentsAdminPanel.prototype.commentToTableRow = function (comment) {
-  var self = this;
-  var projectId = self.getProject().getProjectId();
-  var toYesNo = function (val) {
-    if (val) {
-      return "YES";
-    } else {
-      return "NO";
-    }
-  };
-  var title = null;
-  if (!comment.isRemoved()) {
-    var commentLink = "index.xhtml?id=" + projectId + // 
-      "&x=" + comment.getCoordinates().x + //
-      "&y=" + comment.getCoordinates().y + //
-      "&zoom=12" + //
-      "&comments=on";
-    title = "<a href='" + commentLink + "' target='" + projectId + "'>" + comment.getTitle() + "</a>";
-  } else {
-    title = comment.getTitle();
-  }
-
-  var remove = null;
-  if (comment.isRemoved()) {
-    remove = "YES (" + comment.getRemoveReason() + ")";
-  } else {
-    remove = "<button name='removeComment' data='" + comment.getId() + "'><i class='fa fa-trash-o' style='font-size:17px'></button>";
-  }
-
-  var author = comment.getAuthor();
-  if (author === undefined) {
-    author = "N/A";
-  }
-
-  var email = comment.getEmail();
-  if (email === undefined) {
-    email = "N/A";
-  }
-
-  return [comment.getId(), //
-    xss(title), //
-    xss(author), //
-    xss(email), //
-    xss(comment.getContent()), //
-    remove, //
-    toYesNo(comment.isPinned())];
-};
-
-CommentsAdminPanel.prototype.destroy = function () {
-  var self = this;
-  var table = $("[name='commentsTable']", self.getElement())[0];
-  if ($.fn.DataTable.isDataTable(table)) {
-    $(table).DataTable().destroy();
-  }
-};
-
-
-module.exports = CommentsAdminPanel;
+"use strict";
+
+var AbstractGuiElement = require('../AbstractGuiElement');
+
+var Functions = require('../../Functions');
+var GuiConnector = require('../../GuiConnector');
+// noinspection JSUnusedLocalSymbols
+var logger = require('../../logger');
+
+// noinspection JSUnusedLocalSymbols
+var Promise = require("bluebird");
+var xss = require('xss');
+
+function CommentsAdminPanel(params) {
+  params.customMap = null;
+  AbstractGuiElement.call(this, params);
+
+  this._createGui();
+}
+
+CommentsAdminPanel.prototype = Object.create(AbstractGuiElement.prototype);
+CommentsAdminPanel.prototype.constructor = CommentsAdminPanel;
+
+CommentsAdminPanel.prototype._createGui = function () {
+  var self = this;
+
+  var commentsTable = Functions.createElement({
+    type: "table",
+    name: "commentsTable",
+    className: "display",
+    style: "width:100%"
+  });
+
+  self.getElement().appendChild(commentsTable);
+
+  $(commentsTable).DataTable({
+    columns: [{
+      title: 'Id'
+    }, {
+      title: 'Title'
+    }, {
+      title: 'Author'
+    }, {
+      title: 'Email'
+    }, {
+      title: 'Content'
+    }, {
+      title: 'Removed'
+    }, {
+      title: 'Pinned'
+    }]
+  });
+
+};
+
+CommentsAdminPanel.prototype.init = function () {
+  var self = this;
+  return self.refreshProjects();
+};
+
+CommentsAdminPanel.prototype.refreshComments = function () {
+  var self = this;
+
+  return ServerConnector.getComments({
+    projectId: self.getProject().getProjectId()
+  }).then(function (comments) {
+    var dataTable = $($("[name='commentsTable']", self.getElement())[0]).DataTable();
+    var data = [];
+    for (var i = 0; i < comments.length; i++) {
+      data.push(self.commentToTableRow(comments[i]));
+    }
+    dataTable.clear().rows.add(data).draw();
+    $("[name='commentsTable']", self.getElement()).on("click", "[name='removeComment']", function () {
+      var button = this;
+      return self.askConfirmRemoval({
+        title: "Why do you want to remove this comment?",
+        input: true
+      }).then(function (param) {
+        if (param.status) {
+          return ServerConnector.removeComment({
+            commentId: $(button).attr("data"),
+            reason: param.reason,
+            projectId: self.getProject().getProjectId()
+          }).then(function () {
+            $(button).after("<span>YES (" + param.reason + ")</span>");
+            button.style.display = "none";
+          });
+        }
+      }).catch(GuiConnector.alert)
+    });
+  });
+};
+
+CommentsAdminPanel.prototype.commentToTableRow = function (comment) {
+  var self = this;
+  var projectId = self.getProject().getProjectId();
+  var toYesNo = function (val) {
+    if (val) {
+      return "YES";
+    } else {
+      return "NO";
+    }
+  };
+  var title = null;
+  if (!comment.isRemoved()) {
+    var commentLink = "index.xhtml?id=" + projectId + // 
+      "&x=" + comment.getCoordinates().x + //
+      "&y=" + comment.getCoordinates().y + //
+      "&zoom=12" + //
+      "&comments=on";
+    title = "<a href='" + commentLink + "' target='" + projectId + "'>" + comment.getTitle() + "</a>";
+  } else {
+    title = comment.getTitle();
+  }
+
+  var remove = null;
+  if (comment.isRemoved()) {
+    remove = "YES (" + comment.getRemoveReason() + ")";
+  } else {
+    remove = "<button name='removeComment' data='" + comment.getId() + "'><i class='fa fa-trash-o' style='font-size:17px'></button>";
+  }
+
+  var author = comment.getAuthor();
+  if (author === undefined) {
+    author = "N/A";
+  }
+
+  var email = comment.getEmail();
+  if (email === undefined) {
+    email = "N/A";
+  }
+
+  return [comment.getId(), //
+    xss(title), //
+    xss(author), //
+    xss(email), //
+    xss(comment.getContent()), //
+    remove, //
+    toYesNo(comment.isPinned())];
+};
+
+CommentsAdminPanel.prototype.destroy = function () {
+  var self = this;
+  var table = $("[name='commentsTable']", self.getElement())[0];
+  if ($.fn.DataTable.isDataTable(table)) {
+    $(table).DataTable().destroy();
+  }
+};
+
+
+module.exports = CommentsAdminPanel;
diff --git a/frontend-js/src/main/js/gui/admin/EditGenomeDialog.js b/frontend-js/src/main/js/gui/admin/EditGenomeDialog.js
index db63e854dc8534215b76cd1b12bf8fada93cf2ce..ff90758262320a867554675444ff8f73eeba6d23 100644
--- a/frontend-js/src/main/js/gui/admin/EditGenomeDialog.js
+++ b/frontend-js/src/main/js/gui/admin/EditGenomeDialog.js
@@ -1,703 +1,703 @@
-"use strict";
-
-var Promise = require("bluebird");
-
-var AbstractGuiElement = require('../AbstractGuiElement');
-var Annotation = require('../../map/data/Annotation');
-var GuiConnector = require('../../GuiConnector');
-
-var Functions = require('../../Functions');
-// noinspection JSUnusedLocalSymbols
-var logger = require('../../logger');
-
-var guiUtils = new (require('../leftPanel/GuiUtils'))();
-
-/**
- *
- * @param {Object} params
- * @param {HTMLElement} params.element
- * @param {CustomMap} params.customMap
- * @param {Configuration} params.configuration
- * @param {ReferenceGenome} params.referenceGenome
- * @param {ServerConnector} [params.serverConnector]
-
- * @constructor
- *
- * @extends AbstractGuiElement
- */
-function EditGenomeDialog(params) {
-  AbstractGuiElement.call(this, params);
-  var self = this;
-  self.setReferenceGenome(params.referenceGenome);
-
-  $(self.getElement()).css({overflow: "hidden"});
-
-  self.createGui();
-  self.registerListenerType("onSave");
-}
-
-EditGenomeDialog.prototype = Object.create(AbstractGuiElement.prototype);
-EditGenomeDialog.prototype.constructor = EditGenomeDialog;
-
-/**
- *
- * @param {ReferenceGenome} referenceGenome
- */
-EditGenomeDialog.prototype.setReferenceGenome = function (referenceGenome) {
-  this._referenceGenome = referenceGenome;
-};
-
-/**
- *
- * @returns {ReferenceGenome}
- */
-EditGenomeDialog.prototype.getReferenceGenome = function () {
-  return this._referenceGenome;
-};
-
-/**
- *
- * @returns {boolean}
- */
-EditGenomeDialog.prototype.isNew = function () {
-  return this.getReferenceGenome().getId() === undefined;
-};
-
-/**
- *
- */
-EditGenomeDialog.prototype.createGui = function () {
-  var self = this;
-  var element = self.getElement();
-
-  var tabDiv = Functions.createElement({
-    type: "div",
-    name: "tabView",
-    className: "tabbable boxed parentTabs",
-    style: "position:absolute;top:10px;bottom:40px;left:10px;right:10px"
-  });
-  element.appendChild(tabDiv);
-
-  var tabMenuDiv = Functions.createElement({
-    type: "ul",
-    className: "nav nav-tabs"
-  });
-  tabDiv.appendChild(tabMenuDiv);
-
-  var tabContentDiv = Functions.createElement({
-    type: "div",
-    className: "tab-content",
-    style: "height:100%"
-  });
-  tabDiv.appendChild(tabContentDiv);
-
-  self.createGeneralTab(tabMenuDiv, tabContentDiv);
-  self.createGeneMappingTab(tabMenuDiv, tabContentDiv);
-  $("a", tabMenuDiv).bind("click", function () {
-    //workaround for some css issues...
-    tabDiv.style.top = "40px";
-    tabDiv.style.bottom = "10px";
-  });
-
-};
-
-/**
- *
- * @param {HTMLElement} tabMenuDiv
- * @param {HTMLElement} tabContentDiv
- */
-EditGenomeDialog.prototype.createGeneralTab = function (tabMenuDiv, tabContentDiv) {
-  var self = this;
-  self.addTab({
-    tabMenuDiv: tabMenuDiv,
-    tabContentDiv: tabContentDiv,
-    name: "DETAILS",
-    content: self.createGeneralTabContent()
-  });
-
-};
-
-/**
- *
- * @param {HTMLElement} tabMenuDiv
- * @param {HTMLElement} tabContentDiv
- */
-EditGenomeDialog.prototype.createGeneMappingTab = function (tabMenuDiv, tabContentDiv) {
-  var self = this;
-  self.addTab({
-    tabMenuDiv: tabMenuDiv,
-    tabContentDiv: tabContentDiv,
-    name: "GENE MAPPING",
-    content: self.createGeneMappingTabContent()
-  });
-
-};
-
-var id_counter = 0;
-
-/**
- *
- * @param {string} tab_name
- * @returns {string}
- */
-EditGenomeDialog.prototype.generateTabId = function (tab_name) {
-  var self = this;
-  var id = self.getReferenceGenome().getId();
-  if (id === undefined) {
-    id = "new_genome_" + (id_counter++);
-  }
-  return id + tab_name.replace(" ", "_") + "_TAB";
-};
-
-EditGenomeDialog.prototype.addTab = function (params) {
-  var id = this.generateTabId(params.name);
-
-  var navLi = guiUtils.createTabMenuObject({
-    id: id,
-    name: params.name,
-    navigationBar: params.tabMenuDiv
-  });
-  params.tabMenuDiv.appendChild(navLi);
-
-  var contentDiv = guiUtils.createTabContentObject({
-    id: id,
-    navigationObject: navLi,
-    navigationBar: params.tabMenuDiv
-  });
-
-  $(contentDiv).css("overflow", "auto");
-  if (params.content !== undefined) {
-    contentDiv.appendChild(params.content);
-  }
-
-  params.tabContentDiv.appendChild(contentDiv);
-};
-
-/**
- *
- * @returns {HTMLElement}
- */
-EditGenomeDialog.prototype.createGeneralTabContent = function () {
-
-  var self = this;
-
-  var result = Functions.createElement({
-    type: "div",
-    style: "margin-top:10px;"
-  });
-
-  var table = Functions.createElement({
-    type: "table",
-    name: "detailsTable",
-    className: "display",
-    style: "width:100%"
-  });
-  result.appendChild(table);
-
-  $(table).on("change", "[name='genomeOrganismSelect']", function () {
-    return self._fillTypeSelect(self.getReferenceGenome(), self.getSelectedOrganism());
-  });
-
-  $(table).on("change", "[name='genomeTypeSelect']", function () {
-    return self._fillVersionSelect(self.getReferenceGenome(), self.getSelectedOrganism(), self.getSelectedType());
-  });
-
-  $(table).on("change", "[name='genomeVersionSelect']", function () {
-    return self._fillUrl(self.getReferenceGenome(), self.getSelectedOrganism(), self.getSelectedType(), self.getSelectedVersion());
-  });
-
-
-  var menuRow = Functions.createElement({
-    type: "div",
-    className: "minerva-menu-row",
-    style: "display:table-row; margin:10px"
-  });
-  result.appendChild(menuRow);
-
-  var saveUserButton = Functions.createElement({
-    type: "button",
-    name: "saveGenome",
-    content: '<span class="ui-icon ui-icon-disk"></span>&nbsp;SAVE',
-    onclick: function () {
-      return self.onSaveClicked().then(function () {
-        return self.close();
-      }).catch(GuiConnector.alert);
-    },
-    xss: false
-  });
-  var cancelButton = Functions.createElement({
-    type: "button",
-    name: "cancelGenome",
-    content: '<span class="ui-icon ui-icon-cancel"></span>&nbsp;CANCEL',
-    onclick: function () {
-      return self.close();
-    },
-    xss: false
-  });
-  menuRow.appendChild(saveUserButton);
-  menuRow.appendChild(cancelButton);
-
-  return result;
-};
-
-/**
- *
- * @returns {HTMLElement}
- */
-EditGenomeDialog.prototype.createGeneMappingTabContent = function () {
-
-  var self = this;
-
-  var result = Functions.createElement({
-    type: "div",
-    style: "margin-top:10px;"
-  });
-
-  var geneMappingTable = Functions.createElement({
-    type: "table",
-    name: "geneMappingTable",
-    className: "display",
-    style: "width:100%"
-  });
-  result.appendChild(geneMappingTable);
-
-  // noinspection JSUnusedGlobalSymbols
-  $(geneMappingTable).DataTable({
-    columns: [{
-      title: 'Name'
-    }, {
-      title: 'Source'
-    }, {
-      title: 'Progress'
-    }, {
-      title: 'Remove',
-      orderable: false
-    }],
-    order: [[1, "asc"]]
-  });
-
-  $(geneMappingTable).on("click", "[name='removeMapping']", function () {
-    var button = this;
-    return self.askConfirmRemoval({
-      title: "INFO",
-      content: "Do you really want to remove this gene mapping?",
-      input: false
-    }).then(function (param) {
-      if (param.status) {
-        return self.getServerConnector().removeReferenceGenomeGeneMapping({
-          mappingId: $(button).attr("data").toString(),
-          genomeId: self.getReferenceGenome().getId().toString()
-        }).then(function () {
-          return self.getServerConnector().getReferenceGenome({genomeId: self.getReferenceGenome().getId()});
-        }).then(function (referenceGenome) {
-          self.setReferenceGenome(referenceGenome);
-          return self.refresh();
-        });
-      }
-    }).catch(GuiConnector.alert);
-  });
-
-  var menuRow = Functions.createElement({
-    type: "div",
-    className: "minerva-menu-row",
-    style: "display:table-row; margin:10px"
-  });
-  result.appendChild(menuRow);
-
-  var addGeneMappingButton = Functions.createElement({
-    type: "button",
-    name: "saveGenome",
-    content: '<span class="ui-icon ui-icon-disk"></span>&nbsp;ADD GENE MAPPING',
-    onclick: function () {
-      return self.openAddGeneMapping();
-    },
-    xss: false
-  });
-
-  menuRow.appendChild(addGeneMappingButton);
-
-  return result;
-};
-
-/**
- *
- * @returns {Promise|PromiseLike}
- */
-EditGenomeDialog.prototype.onSaveClicked = function () {
-  var self = this;
-  if (!self.isNew()) {
-    return self.callListeners("onSave");
-  } else {
-    var genome = self.getReferenceGenome();
-    genome.setSourceUrl(self.getSourceUrl());
-    genome.setOrganism(self.getSelectedOrganism());
-    genome.setType(self.getSelectedType());
-    genome.setVersion(self.getSelectedVersion());
-    return self.getServerConnector().addReferenceGenome(genome).then(function () {
-      return self.callListeners("onSave");
-    });
-  }
-};
-/**
- *
- * @param {ReferenceGenome} genome
- * @returns {Promise}
- * @private
- */
-EditGenomeDialog.prototype._fillOrganismSelect = function (genome) {
-  var self = this;
-  return self.getServerConnector().getReferenceGenomeOrganisms().then(function (organisms) {
-    var genomeOrganismSelect = $("[name=genomeOrganismSelect]", self.getElement());
-    genomeOrganismSelect.empty();
-    var selectedOrganism;
-    if (self.isNew()) {
-      selectedOrganism = organisms[0];
-      for (var i = 0; i < organisms.length; i++) {
-        if (organisms[i].getResource() === "9606") {
-          selectedOrganism = organisms[i];
-        }
-      }
-    } else {
-      selectedOrganism = genome.getOrganism();
-    }
-    $.each(organisms, function (i, organism) {
-      var disable = false;
-      if (organism.getResource() !== selectedOrganism.getResource() && !self.isNew()) {
-        disable = true;
-      }
-      genomeOrganismSelect.append($('<option>', {
-        value: organism.getResource(),
-        text: organism.getResource(),
-        disabled: disable
-      }));
-    });
-    genomeOrganismSelect.val(selectedOrganism.getResource());
-    return self._fillTypeSelect(genome, selectedOrganism);
-  });
-};
-
-/**
- *
- * @param {ReferenceGenome} genome
- * @param {Annotation} selectedOrganism
- * @returns {Promise}
- * @private
- */
-EditGenomeDialog.prototype._fillTypeSelect = function (genome, selectedOrganism) {
-  var self = this;
-  return self.getServerConnector().getReferenceGenomeTypes({organism: selectedOrganism}).then(function (types) {
-
-    var genomeTypeSelect = $("[name=genomeTypeSelect]", self.getElement());
-    genomeTypeSelect.empty();
-
-    var selectedType;
-    if (self.isNew()) {
-      selectedType = types[0].type;
-    } else {
-      selectedType = genome.getType();
-    }
-    $.each(types, function (i, type) {
-      var disable = false;
-      if (type.type !== selectedType && !self.isNew()) {
-        disable = true;
-      }
-      genomeTypeSelect.append($('<option>', {
-        value: type.type,
-        text: type.type,
-        disabled: disable
-      }));
-    });
-    genomeTypeSelect.val(selectedType);
-    return self._fillVersionSelect(genome, selectedOrganism, selectedType);
-  })
-};
-
-/**
- *
- * @param {ReferenceGenome} genome
- * @param {Annotation} selectedOrganism
- * @param {string} selectedType
- * @returns {Promise}
- * @private
- */
-EditGenomeDialog.prototype._fillVersionSelect = function (genome, selectedOrganism, selectedType) {
-  var self = this;
-  return self.getServerConnector().getReferenceGenomeVersions({
-    organism: selectedOrganism,
-    type: selectedType
-  }).then(function (versions) {
-    var genomeVersionSelect = $("[name=genomeVersionSelect]", self.getElement());
-    genomeVersionSelect.empty();
-
-    var selectedVersion;
-    if (self.isNew()) {
-      selectedVersion = versions[0].version;
-    } else {
-      selectedVersion = genome.getVersion();
-    }
-    $.each(versions, function (i, version) {
-      var disable = false;
-      if (version.version !== selectedVersion && !self.isNew()) {
-        disable = true;
-      }
-      genomeVersionSelect.append($('<option>', {
-        value: version.version,
-        text: version.version,
-        disabled: disable
-      }));
-    });
-    genomeVersionSelect.val(selectedVersion);
-    return self._fillUrl(genome, selectedOrganism, selectedType, selectedVersion);
-  })
-};
-
-/**
- *
- * @param {ReferenceGenome} genome
- * @param {Annotation} organism
- * @param {string} type
- * @param {string} version
- * @returns {Promise}
- * @private
- */
-EditGenomeDialog.prototype._fillUrl = function (genome, organism, type, version) {
-  var self = this;
-  var genomeSourceUrlInput = $("[name=genomeSourceUrl]", self.getElement());
-  var genomeLocalUrlInput = $("[name=genomeLocalUrl]", self.getElement());
-  var genomeProgressInput = $("[name=genomeProgress]", self.getElement());
-  genomeLocalUrlInput.prop("disabled", true);
-  genomeProgressInput.val(genome.getDownloadProgressStatus());
-  genomeProgressInput.prop("disabled", true);
-  if (!self.isNew()) {
-    genomeSourceUrlInput.val(genome.getSourceUrl());
-    genomeSourceUrlInput.prop("disabled", true);
-
-    genomeLocalUrlInput.val(genome.getLocalUrl());
-  } else {
-    genomeSourceUrlInput.prop("disabled", false);
-
-    genomeLocalUrlInput.val("");
-    return self.getServerConnector().getAvailableGenomeUrls({
-      organism: organism,
-      type: type,
-      version: version
-    }).then(function (urls) {
-      if (urls.length > 0) {
-        genomeSourceUrlInput.val(urls[0]);
-      } else {
-        genomeSourceUrlInput.val("");
-      }
-    })
-  }
-  return Promise.resolve();
-}
-;
-
-
-/**
- *
- * @param {ReferenceGenomeGeneMapping} geneMapping
- * @returns {Array}
- */
-EditGenomeDialog.prototype.geneMappingToTableRow = function (geneMapping) {
-  var row = [];
-  row[0] = geneMapping.getName();
-  row[1] = geneMapping.getSourceUrl();
-  row[2] = geneMapping.getProgress();
-  row[3] = "<button name='removeMapping' data='" + geneMapping.getId() + "'><i class='fa fa-trash-o' style='font-size:17px'></button>";
-  return row;
-};
-/**
- *
- * @returns {Promise}
- */
-EditGenomeDialog.prototype.init = function () {
-  var self = this;
-
-  var detailsTable = $("[name=detailsTable]", self.getElement())[0];
-
-  // noinspection JSCheckFunctionSignatures
-  $(detailsTable).DataTable({
-    columns: [{
-      title: "Name"
-    }, {
-      title: "Value"
-    }],
-    paging: false,
-    ordering: false,
-    searching: false,
-    bInfo: false
-  });
-
-  return self.refresh();
-};
-
-/**
- *
- * @returns {Promise}
- */
-EditGenomeDialog.prototype.refresh = function () {
-  var self = this;
-
-  var genome = self.getReferenceGenome();
-
-  var dataTable = $("[name=detailsTable]", self.getElement()).DataTable();
-  var data = [];
-
-  data.push(['Organism', Functions.createElement({type: "select", name: "genomeOrganismSelect"}).outerHTML]);
-  data.push(['Type', Functions.createElement({type: "select", name: "genomeTypeSelect"}).outerHTML]);
-  data.push(['Version', Functions.createElement({type: "select", name: "genomeVersionSelect"}).outerHTML]);
-  data.push(['Source url', Functions.createElement({type: "input", name: "genomeSourceUrl"}).outerHTML]);
-  data.push(['Local url', Functions.createElement({type: "input", name: "genomeLocalUrl"}).outerHTML]);
-  data.push(['Progress', Functions.createElement({type: "input", name: "genomeProgress"}).outerHTML]);
-
-  dataTable.clear().rows.add(data).draw();
-
-  dataTable = $("[name=geneMappingTable]", self.getElement()).DataTable();
-  data = [];
-  var page = dataTable.page();
-
-  for (var i = 0; i < genome.getGeneMappings().length; i++) {
-    var geneMapping = genome.getGeneMappings()[i];
-    var rowData = self.geneMappingToTableRow(geneMapping);
-    data.push(rowData);
-  }
-  //it should be simplified, but I couldn't make it work
-  dataTable.clear().rows.add(data).page(page).draw(false).page(page).draw(false);
-
-  return self._fillOrganismSelect(genome);
-};
-
-/**
- *
- */
-EditGenomeDialog.prototype.destroy = function () {
-  var self = this;
-  var div = self.getElement();
-
-  var detailsTable = $("[name=detailsTable]", div)[0];
-  if ($.fn.DataTable.isDataTable(detailsTable)) {
-    $(detailsTable).DataTable().destroy();
-  }
-
-  var geneMappingTable = $("[name=geneMappingTable]", div)[0];
-  if ($.fn.DataTable.isDataTable(geneMappingTable)) {
-    $(geneMappingTable).DataTable().destroy();
-  }
-
-  if ($(div).hasClass("ui-dialog-content")) {
-    $(div).dialog("destroy");
-  }
-};
-
-/**
- *
- */
-EditGenomeDialog.prototype.open = function () {
-  var self = this;
-  var div = self.getElement();
-  var title;
-  if (self.isNew()) {
-    title = "Download genome";
-  } else {
-    var genome = self.getReferenceGenome();
-    title = genome.getType() + " " + genome.getOrganism().getResource() + " " + genome.getVersion();
-  }
-  if (!$(div).hasClass("ui-dialog-content")) {
-    $(div).dialog({
-      title: title,
-      width: window.innerWidth / 2,
-      height: window.innerHeight / 2
-    });
-  }
-  $(div).dialog("open");
-};
-
-/**
- *
- */
-EditGenomeDialog.prototype.close = function () {
-  var self = this;
-  $(self.getElement()).dialog("close");
-};
-
-/**
- *
- * @returns {Annotation}
- */
-EditGenomeDialog.prototype.getSelectedOrganism = function () {
-  var self = this;
-  return new Annotation({
-    resource: ($("[name='genomeOrganismSelect']", self.getElement()).val()).toString(),
-    link: '',
-    id: 0,
-    type: ''
-  })
-};
-
-/**
- *
- * @returns {string}
- */
-EditGenomeDialog.prototype.getSelectedType = function () {
-  var self = this;
-  return ($("[name='genomeTypeSelect']", self.getElement()).val()).toString();
-};
-
-/**
- *
- * @returns {string}
- */
-EditGenomeDialog.prototype.getSelectedVersion = function () {
-  var self = this;
-  return ($("[name='genomeVersionSelect']", self.getElement()).val()).toString();
-};
-
-/**
- *
- * @returns {string}
- */
-EditGenomeDialog.prototype.getSourceUrl = function () {
-  var self = this;
-  return ($("[name='genomeSourceUrl']", self.getElement()).val()).toString();
-};
-
-/**
- *
- */
-EditGenomeDialog.prototype.openAddGeneMapping = function () {
-  var self = this;
-  var html = '<form style="z-index:10000"><span>Name: </span><input type="text" name="gene-mapping-name"><br>' +
-    '<span>Url: </span><input type="text" name="gene-mapping-url"><br></form>';
-  $(html).dialog({
-    modal: true,
-    title: "Add gene mapping",
-    close: function () {
-      $(this).dialog('destroy').remove();
-    },
-    buttons: {
-      'ADD': function () {
-        var dialog = this;
-        var name = $('input[name="gene-mapping-name"]').val().toString();
-        var url = $('input[name="gene-mapping-url"]').val().toString();
-        return self.getServerConnector().addGeneMapping({
-          genomeId: self.getReferenceGenome().getId(),
-          mappingName: name,
-          mappingUrl: url
-        }).then(function () {
-          return self.getServerConnector().getReferenceGenome({genomeId: self.getReferenceGenome().getId()});
-        }).then(function (referenceGenome) {
-          self.setReferenceGenome(referenceGenome);
-          return self.refresh();
-        }).then(function () {
-          $(dialog).dialog('destroy').remove();
-        });
-      },
-      'Cancel': function () {
-        $(this).dialog('destroy').remove();
-      }
-    }
-  });
-};
-
-module.exports = EditGenomeDialog;
+"use strict";
+
+var Promise = require("bluebird");
+
+var AbstractGuiElement = require('../AbstractGuiElement');
+var Annotation = require('../../map/data/Annotation');
+var GuiConnector = require('../../GuiConnector');
+
+var Functions = require('../../Functions');
+// noinspection JSUnusedLocalSymbols
+var logger = require('../../logger');
+
+var guiUtils = new (require('../leftPanel/GuiUtils'))();
+
+/**
+ *
+ * @param {Object} params
+ * @param {HTMLElement} params.element
+ * @param {CustomMap} params.customMap
+ * @param {Configuration} params.configuration
+ * @param {ReferenceGenome} params.referenceGenome
+ * @param {ServerConnector} [params.serverConnector]
+
+ * @constructor
+ *
+ * @extends AbstractGuiElement
+ */
+function EditGenomeDialog(params) {
+  AbstractGuiElement.call(this, params);
+  var self = this;
+  self.setReferenceGenome(params.referenceGenome);
+
+  $(self.getElement()).css({overflow: "hidden"});
+
+  self.createGui();
+  self.registerListenerType("onSave");
+}
+
+EditGenomeDialog.prototype = Object.create(AbstractGuiElement.prototype);
+EditGenomeDialog.prototype.constructor = EditGenomeDialog;
+
+/**
+ *
+ * @param {ReferenceGenome} referenceGenome
+ */
+EditGenomeDialog.prototype.setReferenceGenome = function (referenceGenome) {
+  this._referenceGenome = referenceGenome;
+};
+
+/**
+ *
+ * @returns {ReferenceGenome}
+ */
+EditGenomeDialog.prototype.getReferenceGenome = function () {
+  return this._referenceGenome;
+};
+
+/**
+ *
+ * @returns {boolean}
+ */
+EditGenomeDialog.prototype.isNew = function () {
+  return this.getReferenceGenome().getId() === undefined;
+};
+
+/**
+ *
+ */
+EditGenomeDialog.prototype.createGui = function () {
+  var self = this;
+  var element = self.getElement();
+
+  var tabDiv = Functions.createElement({
+    type: "div",
+    name: "tabView",
+    className: "tabbable boxed parentTabs",
+    style: "position:absolute;top:10px;bottom:40px;left:10px;right:10px"
+  });
+  element.appendChild(tabDiv);
+
+  var tabMenuDiv = Functions.createElement({
+    type: "ul",
+    className: "nav nav-tabs"
+  });
+  tabDiv.appendChild(tabMenuDiv);
+
+  var tabContentDiv = Functions.createElement({
+    type: "div",
+    className: "tab-content",
+    style: "height:100%"
+  });
+  tabDiv.appendChild(tabContentDiv);
+
+  self.createGeneralTab(tabMenuDiv, tabContentDiv);
+  self.createGeneMappingTab(tabMenuDiv, tabContentDiv);
+  $("a", tabMenuDiv).bind("click", function () {
+    //workaround for some css issues...
+    tabDiv.style.top = "40px";
+    tabDiv.style.bottom = "10px";
+  });
+
+};
+
+/**
+ *
+ * @param {HTMLElement} tabMenuDiv
+ * @param {HTMLElement} tabContentDiv
+ */
+EditGenomeDialog.prototype.createGeneralTab = function (tabMenuDiv, tabContentDiv) {
+  var self = this;
+  self.addTab({
+    tabMenuDiv: tabMenuDiv,
+    tabContentDiv: tabContentDiv,
+    name: "DETAILS",
+    content: self.createGeneralTabContent()
+  });
+
+};
+
+/**
+ *
+ * @param {HTMLElement} tabMenuDiv
+ * @param {HTMLElement} tabContentDiv
+ */
+EditGenomeDialog.prototype.createGeneMappingTab = function (tabMenuDiv, tabContentDiv) {
+  var self = this;
+  self.addTab({
+    tabMenuDiv: tabMenuDiv,
+    tabContentDiv: tabContentDiv,
+    name: "GENE MAPPING",
+    content: self.createGeneMappingTabContent()
+  });
+
+};
+
+var id_counter = 0;
+
+/**
+ *
+ * @param {string} tab_name
+ * @returns {string}
+ */
+EditGenomeDialog.prototype.generateTabId = function (tab_name) {
+  var self = this;
+  var id = self.getReferenceGenome().getId();
+  if (id === undefined) {
+    id = "new_genome_" + (id_counter++);
+  }
+  return id + tab_name.replace(" ", "_") + "_TAB";
+};
+
+EditGenomeDialog.prototype.addTab = function (params) {
+  var id = this.generateTabId(params.name);
+
+  var navLi = guiUtils.createTabMenuObject({
+    id: id,
+    name: params.name,
+    navigationBar: params.tabMenuDiv
+  });
+  params.tabMenuDiv.appendChild(navLi);
+
+  var contentDiv = guiUtils.createTabContentObject({
+    id: id,
+    navigationObject: navLi,
+    navigationBar: params.tabMenuDiv
+  });
+
+  $(contentDiv).css("overflow", "auto");
+  if (params.content !== undefined) {
+    contentDiv.appendChild(params.content);
+  }
+
+  params.tabContentDiv.appendChild(contentDiv);
+};
+
+/**
+ *
+ * @returns {HTMLElement}
+ */
+EditGenomeDialog.prototype.createGeneralTabContent = function () {
+
+  var self = this;
+
+  var result = Functions.createElement({
+    type: "div",
+    style: "margin-top:10px;"
+  });
+
+  var table = Functions.createElement({
+    type: "table",
+    name: "detailsTable",
+    className: "display",
+    style: "width:100%"
+  });
+  result.appendChild(table);
+
+  $(table).on("change", "[name='genomeOrganismSelect']", function () {
+    return self._fillTypeSelect(self.getReferenceGenome(), self.getSelectedOrganism());
+  });
+
+  $(table).on("change", "[name='genomeTypeSelect']", function () {
+    return self._fillVersionSelect(self.getReferenceGenome(), self.getSelectedOrganism(), self.getSelectedType());
+  });
+
+  $(table).on("change", "[name='genomeVersionSelect']", function () {
+    return self._fillUrl(self.getReferenceGenome(), self.getSelectedOrganism(), self.getSelectedType(), self.getSelectedVersion());
+  });
+
+
+  var menuRow = Functions.createElement({
+    type: "div",
+    className: "minerva-menu-row",
+    style: "display:table-row; margin:10px"
+  });
+  result.appendChild(menuRow);
+
+  var saveUserButton = Functions.createElement({
+    type: "button",
+    name: "saveGenome",
+    content: '<span class="ui-icon ui-icon-disk"></span>&nbsp;SAVE',
+    onclick: function () {
+      return self.onSaveClicked().then(function () {
+        return self.close();
+      }).catch(GuiConnector.alert);
+    },
+    xss: false
+  });
+  var cancelButton = Functions.createElement({
+    type: "button",
+    name: "cancelGenome",
+    content: '<span class="ui-icon ui-icon-cancel"></span>&nbsp;CANCEL',
+    onclick: function () {
+      return self.close();
+    },
+    xss: false
+  });
+  menuRow.appendChild(saveUserButton);
+  menuRow.appendChild(cancelButton);
+
+  return result;
+};
+
+/**
+ *
+ * @returns {HTMLElement}
+ */
+EditGenomeDialog.prototype.createGeneMappingTabContent = function () {
+
+  var self = this;
+
+  var result = Functions.createElement({
+    type: "div",
+    style: "margin-top:10px;"
+  });
+
+  var geneMappingTable = Functions.createElement({
+    type: "table",
+    name: "geneMappingTable",
+    className: "display",
+    style: "width:100%"
+  });
+  result.appendChild(geneMappingTable);
+
+  // noinspection JSUnusedGlobalSymbols
+  $(geneMappingTable).DataTable({
+    columns: [{
+      title: 'Name'
+    }, {
+      title: 'Source'
+    }, {
+      title: 'Progress'
+    }, {
+      title: 'Remove',
+      orderable: false
+    }],
+    order: [[1, "asc"]]
+  });
+
+  $(geneMappingTable).on("click", "[name='removeMapping']", function () {
+    var button = this;
+    return self.askConfirmRemoval({
+      title: "INFO",
+      content: "Do you really want to remove this gene mapping?",
+      input: false
+    }).then(function (param) {
+      if (param.status) {
+        return self.getServerConnector().removeReferenceGenomeGeneMapping({
+          mappingId: $(button).attr("data").toString(),
+          genomeId: self.getReferenceGenome().getId().toString()
+        }).then(function () {
+          return self.getServerConnector().getReferenceGenome({genomeId: self.getReferenceGenome().getId()});
+        }).then(function (referenceGenome) {
+          self.setReferenceGenome(referenceGenome);
+          return self.refresh();
+        });
+      }
+    }).catch(GuiConnector.alert);
+  });
+
+  var menuRow = Functions.createElement({
+    type: "div",
+    className: "minerva-menu-row",
+    style: "display:table-row; margin:10px"
+  });
+  result.appendChild(menuRow);
+
+  var addGeneMappingButton = Functions.createElement({
+    type: "button",
+    name: "saveGenome",
+    content: '<span class="ui-icon ui-icon-disk"></span>&nbsp;ADD GENE MAPPING',
+    onclick: function () {
+      return self.openAddGeneMapping();
+    },
+    xss: false
+  });
+
+  menuRow.appendChild(addGeneMappingButton);
+
+  return result;
+};
+
+/**
+ *
+ * @returns {Promise|PromiseLike}
+ */
+EditGenomeDialog.prototype.onSaveClicked = function () {
+  var self = this;
+  if (!self.isNew()) {
+    return self.callListeners("onSave");
+  } else {
+    var genome = self.getReferenceGenome();
+    genome.setSourceUrl(self.getSourceUrl());
+    genome.setOrganism(self.getSelectedOrganism());
+    genome.setType(self.getSelectedType());
+    genome.setVersion(self.getSelectedVersion());
+    return self.getServerConnector().addReferenceGenome(genome).then(function () {
+      return self.callListeners("onSave");
+    });
+  }
+};
+/**
+ *
+ * @param {ReferenceGenome} genome
+ * @returns {Promise}
+ * @private
+ */
+EditGenomeDialog.prototype._fillOrganismSelect = function (genome) {
+  var self = this;
+  return self.getServerConnector().getReferenceGenomeOrganisms().then(function (organisms) {
+    var genomeOrganismSelect = $("[name=genomeOrganismSelect]", self.getElement());
+    genomeOrganismSelect.empty();
+    var selectedOrganism;
+    if (self.isNew()) {
+      selectedOrganism = organisms[0];
+      for (var i = 0; i < organisms.length; i++) {
+        if (organisms[i].getResource() === "9606") {
+          selectedOrganism = organisms[i];
+        }
+      }
+    } else {
+      selectedOrganism = genome.getOrganism();
+    }
+    $.each(organisms, function (i, organism) {
+      var disable = false;
+      if (organism.getResource() !== selectedOrganism.getResource() && !self.isNew()) {
+        disable = true;
+      }
+      genomeOrganismSelect.append($('<option>', {
+        value: organism.getResource(),
+        text: organism.getResource(),
+        disabled: disable
+      }));
+    });
+    genomeOrganismSelect.val(selectedOrganism.getResource());
+    return self._fillTypeSelect(genome, selectedOrganism);
+  });
+};
+
+/**
+ *
+ * @param {ReferenceGenome} genome
+ * @param {Annotation} selectedOrganism
+ * @returns {Promise}
+ * @private
+ */
+EditGenomeDialog.prototype._fillTypeSelect = function (genome, selectedOrganism) {
+  var self = this;
+  return self.getServerConnector().getReferenceGenomeTypes({organism: selectedOrganism}).then(function (types) {
+
+    var genomeTypeSelect = $("[name=genomeTypeSelect]", self.getElement());
+    genomeTypeSelect.empty();
+
+    var selectedType;
+    if (self.isNew()) {
+      selectedType = types[0].type;
+    } else {
+      selectedType = genome.getType();
+    }
+    $.each(types, function (i, type) {
+      var disable = false;
+      if (type.type !== selectedType && !self.isNew()) {
+        disable = true;
+      }
+      genomeTypeSelect.append($('<option>', {
+        value: type.type,
+        text: type.type,
+        disabled: disable
+      }));
+    });
+    genomeTypeSelect.val(selectedType);
+    return self._fillVersionSelect(genome, selectedOrganism, selectedType);
+  })
+};
+
+/**
+ *
+ * @param {ReferenceGenome} genome
+ * @param {Annotation} selectedOrganism
+ * @param {string} selectedType
+ * @returns {Promise}
+ * @private
+ */
+EditGenomeDialog.prototype._fillVersionSelect = function (genome, selectedOrganism, selectedType) {
+  var self = this;
+  return self.getServerConnector().getReferenceGenomeVersions({
+    organism: selectedOrganism,
+    type: selectedType
+  }).then(function (versions) {
+    var genomeVersionSelect = $("[name=genomeVersionSelect]", self.getElement());
+    genomeVersionSelect.empty();
+
+    var selectedVersion;
+    if (self.isNew()) {
+      selectedVersion = versions[0].version;
+    } else {
+      selectedVersion = genome.getVersion();
+    }
+    $.each(versions, function (i, version) {
+      var disable = false;
+      if (version.version !== selectedVersion && !self.isNew()) {
+        disable = true;
+      }
+      genomeVersionSelect.append($('<option>', {
+        value: version.version,
+        text: version.version,
+        disabled: disable
+      }));
+    });
+    genomeVersionSelect.val(selectedVersion);
+    return self._fillUrl(genome, selectedOrganism, selectedType, selectedVersion);
+  })
+};
+
+/**
+ *
+ * @param {ReferenceGenome} genome
+ * @param {Annotation} organism
+ * @param {string} type
+ * @param {string} version
+ * @returns {Promise}
+ * @private
+ */
+EditGenomeDialog.prototype._fillUrl = function (genome, organism, type, version) {
+  var self = this;
+  var genomeSourceUrlInput = $("[name=genomeSourceUrl]", self.getElement());
+  var genomeLocalUrlInput = $("[name=genomeLocalUrl]", self.getElement());
+  var genomeProgressInput = $("[name=genomeProgress]", self.getElement());
+  genomeLocalUrlInput.prop("disabled", true);
+  genomeProgressInput.val(genome.getDownloadProgressStatus());
+  genomeProgressInput.prop("disabled", true);
+  if (!self.isNew()) {
+    genomeSourceUrlInput.val(genome.getSourceUrl());
+    genomeSourceUrlInput.prop("disabled", true);
+
+    genomeLocalUrlInput.val(genome.getLocalUrl());
+  } else {
+    genomeSourceUrlInput.prop("disabled", false);
+
+    genomeLocalUrlInput.val("");
+    return self.getServerConnector().getAvailableGenomeUrls({
+      organism: organism,
+      type: type,
+      version: version
+    }).then(function (urls) {
+      if (urls.length > 0) {
+        genomeSourceUrlInput.val(urls[0]);
+      } else {
+        genomeSourceUrlInput.val("");
+      }
+    })
+  }
+  return Promise.resolve();
+}
+;
+
+
+/**
+ *
+ * @param {ReferenceGenomeGeneMapping} geneMapping
+ * @returns {Array}
+ */
+EditGenomeDialog.prototype.geneMappingToTableRow = function (geneMapping) {
+  var row = [];
+  row[0] = geneMapping.getName();
+  row[1] = geneMapping.getSourceUrl();
+  row[2] = geneMapping.getProgress();
+  row[3] = "<button name='removeMapping' data='" + geneMapping.getId() + "'><i class='fa fa-trash-o' style='font-size:17px'></button>";
+  return row;
+};
+/**
+ *
+ * @returns {Promise}
+ */
+EditGenomeDialog.prototype.init = function () {
+  var self = this;
+
+  var detailsTable = $("[name=detailsTable]", self.getElement())[0];
+
+  // noinspection JSCheckFunctionSignatures
+  $(detailsTable).DataTable({
+    columns: [{
+      title: "Name"
+    }, {
+      title: "Value"
+    }],
+    paging: false,
+    ordering: false,
+    searching: false,
+    bInfo: false
+  });
+
+  return self.refresh();
+};
+
+/**
+ *
+ * @returns {Promise}
+ */
+EditGenomeDialog.prototype.refresh = function () {
+  var self = this;
+
+  var genome = self.getReferenceGenome();
+
+  var dataTable = $("[name=detailsTable]", self.getElement()).DataTable();
+  var data = [];
+
+  data.push(['Organism', Functions.createElement({type: "select", name: "genomeOrganismSelect"}).outerHTML]);
+  data.push(['Type', Functions.createElement({type: "select", name: "genomeTypeSelect"}).outerHTML]);
+  data.push(['Version', Functions.createElement({type: "select", name: "genomeVersionSelect"}).outerHTML]);
+  data.push(['Source url', Functions.createElement({type: "input", name: "genomeSourceUrl"}).outerHTML]);
+  data.push(['Local url', Functions.createElement({type: "input", name: "genomeLocalUrl"}).outerHTML]);
+  data.push(['Progress', Functions.createElement({type: "input", name: "genomeProgress"}).outerHTML]);
+
+  dataTable.clear().rows.add(data).draw();
+
+  dataTable = $("[name=geneMappingTable]", self.getElement()).DataTable();
+  data = [];
+  var page = dataTable.page();
+
+  for (var i = 0; i < genome.getGeneMappings().length; i++) {
+    var geneMapping = genome.getGeneMappings()[i];
+    var rowData = self.geneMappingToTableRow(geneMapping);
+    data.push(rowData);
+  }
+  //it should be simplified, but I couldn't make it work
+  dataTable.clear().rows.add(data).page(page).draw(false).page(page).draw(false);
+
+  return self._fillOrganismSelect(genome);
+};
+
+/**
+ *
+ */
+EditGenomeDialog.prototype.destroy = function () {
+  var self = this;
+  var div = self.getElement();
+
+  var detailsTable = $("[name=detailsTable]", div)[0];
+  if ($.fn.DataTable.isDataTable(detailsTable)) {
+    $(detailsTable).DataTable().destroy();
+  }
+
+  var geneMappingTable = $("[name=geneMappingTable]", div)[0];
+  if ($.fn.DataTable.isDataTable(geneMappingTable)) {
+    $(geneMappingTable).DataTable().destroy();
+  }
+
+  if ($(div).hasClass("ui-dialog-content")) {
+    $(div).dialog("destroy");
+  }
+};
+
+/**
+ *
+ */
+EditGenomeDialog.prototype.open = function () {
+  var self = this;
+  var div = self.getElement();
+  var title;
+  if (self.isNew()) {
+    title = "Download genome";
+  } else {
+    var genome = self.getReferenceGenome();
+    title = genome.getType() + " " + genome.getOrganism().getResource() + " " + genome.getVersion();
+  }
+  if (!$(div).hasClass("ui-dialog-content")) {
+    $(div).dialog({
+      title: title,
+      width: window.innerWidth / 2,
+      height: window.innerHeight / 2
+    });
+  }
+  $(div).dialog("open");
+};
+
+/**
+ *
+ */
+EditGenomeDialog.prototype.close = function () {
+  var self = this;
+  $(self.getElement()).dialog("close");
+};
+
+/**
+ *
+ * @returns {Annotation}
+ */
+EditGenomeDialog.prototype.getSelectedOrganism = function () {
+  var self = this;
+  return new Annotation({
+    resource: ($("[name='genomeOrganismSelect']", self.getElement()).val()).toString(),
+    link: '',
+    id: 0,
+    type: ''
+  })
+};
+
+/**
+ *
+ * @returns {string}
+ */
+EditGenomeDialog.prototype.getSelectedType = function () {
+  var self = this;
+  return ($("[name='genomeTypeSelect']", self.getElement()).val()).toString();
+};
+
+/**
+ *
+ * @returns {string}
+ */
+EditGenomeDialog.prototype.getSelectedVersion = function () {
+  var self = this;
+  return ($("[name='genomeVersionSelect']", self.getElement()).val()).toString();
+};
+
+/**
+ *
+ * @returns {string}
+ */
+EditGenomeDialog.prototype.getSourceUrl = function () {
+  var self = this;
+  return ($("[name='genomeSourceUrl']", self.getElement()).val()).toString();
+};
+
+/**
+ *
+ */
+EditGenomeDialog.prototype.openAddGeneMapping = function () {
+  var self = this;
+  var html = '<form style="z-index:10000"><span>Name: </span><input type="text" name="gene-mapping-name"><br>' +
+    '<span>Url: </span><input type="text" name="gene-mapping-url"><br></form>';
+  $(html).dialog({
+    modal: true,
+    title: "Add gene mapping",
+    close: function () {
+      $(this).dialog('destroy').remove();
+    },
+    buttons: {
+      'ADD': function () {
+        var dialog = this;
+        var name = $('input[name="gene-mapping-name"]').val().toString();
+        var url = $('input[name="gene-mapping-url"]').val().toString();
+        return self.getServerConnector().addGeneMapping({
+          genomeId: self.getReferenceGenome().getId(),
+          mappingName: name,
+          mappingUrl: url
+        }).then(function () {
+          return self.getServerConnector().getReferenceGenome({genomeId: self.getReferenceGenome().getId()});
+        }).then(function (referenceGenome) {
+          self.setReferenceGenome(referenceGenome);
+          return self.refresh();
+        }).then(function () {
+          $(dialog).dialog('destroy').remove();
+        });
+      },
+      'Cancel': function () {
+        $(this).dialog('destroy').remove();
+      }
+    }
+  });
+};
+
+module.exports = EditGenomeDialog;
diff --git a/frontend-js/src/main/js/gui/admin/EditUserDialog.js b/frontend-js/src/main/js/gui/admin/EditUserDialog.js
index 3030c8cab407a8ce2f5c38275cba2f4acd858435..7cf9719e85ae2c81b8da50ba758bb3f4b86dd64e 100644
--- a/frontend-js/src/main/js/gui/admin/EditUserDialog.js
+++ b/frontend-js/src/main/js/gui/admin/EditUserDialog.js
@@ -1,630 +1,630 @@
-"use strict";
-
-var Promise = require("bluebird");
-var xss = require('xss');
-
-var AbstractGuiElement = require('../AbstractGuiElement');
-var GuiConnector = require('../../GuiConnector');
-var ValidationError = require('../../ValidationError');
-
-var Functions = require('../../Functions');
-// noinspection JSUnusedLocalSymbols
-var logger = require('../../logger');
-
-var guiUtils = new (require('../leftPanel/GuiUtils'))();
-
-function EditUserDialog(params) {
-  AbstractGuiElement.call(this, params);
-  var self = this;
-  self.setUser(params.user);
-
-  $(self.getElement()).css({overflow: "hidden"});
-
-  self.createGui();
-  self.registerListenerType("onSave");
-}
-
-EditUserDialog.prototype = Object.create(AbstractGuiElement.prototype);
-EditUserDialog.prototype.constructor = EditUserDialog;
-
-EditUserDialog.prototype.setUser = function (user) {
-  this._user = user;
-  this.setIsNewUser(user.getLogin() === undefined);
-};
-EditUserDialog.prototype.getUser = function () {
-  return this._user;
-};
-
-EditUserDialog.prototype.setIsNewUser = function (isNewUser) {
-  this._isNewUser = isNewUser;
-};
-EditUserDialog.prototype.getIsNewUser = function () {
-  return this._isNewUser;
-};
-
-EditUserDialog.prototype.createGui = function () {
-  var self = this;
-  var element = self.getElement();
-
-  var tabDiv = Functions.createElement({
-    type: "div",
-    name: "tabView",
-    className: "tabbable boxed parentTabs",
-    style: "position:absolute;top:10px;bottom:40px;left:10px;right:10px"
-  });
-  element.appendChild(tabDiv);
-
-  var tabMenuDiv = Functions.createElement({
-    type: "ul",
-    className: "nav nav-tabs"
-  });
-  tabDiv.appendChild(tabMenuDiv);
-
-  var tabContentDiv = Functions.createElement({
-    type: "div",
-    className: "tab-content",
-    style: "height:100%"
-  });
-  tabDiv.appendChild(tabContentDiv);
-
-  self.createGeneralTab(tabMenuDiv, tabContentDiv);
-  self.createPrivilegesTab(tabMenuDiv, tabContentDiv);
-  self.createProjectsTab(tabMenuDiv, tabContentDiv);
-  $("a", tabMenuDiv).bind("click", function () {
-    //workaround for some css issues...
-    tabDiv.style.top = "40px";
-    tabDiv.style.bottom = "10px";
-  });
-};
-
-EditUserDialog.prototype.createGeneralTab = function (tabMenuDiv, tabContentDiv) {
-  var self = this;
-  self.addTab({
-    tabMenuDiv: tabMenuDiv,
-    tabContentDiv: tabContentDiv,
-    name: "DETAILS",
-    content: self.createGeneralTabContent()
-  });
-
-};
-
-var login_counter = 0;
-
-EditUserDialog.prototype.generateTabId = function (tab_name) {
-  var self = this;
-  var login = self.getUser().getLogin();
-  if (login === undefined) {
-    login = "new_user_" + (login_counter++);
-  }
-  return login.replace(".", "_") + tab_name.replace(" ", "_") + "_TAB";
-};
-
-EditUserDialog.prototype.createPrivilegesTab = function (tabMenuDiv, tabContentDiv) {
-  var self = this;
-  self.addTab({
-    tabMenuDiv: tabMenuDiv,
-    tabContentDiv: tabContentDiv,
-    name: "GLOBAL PRIVILEGES",
-    content: self.createPrivilegesTabContent()
-  });
-
-};
-
-EditUserDialog.prototype.addTab = function (params) {
-  var id = this.generateTabId(params.name);
-
-  var navLi = guiUtils.createTabMenuObject({
-    id: id,
-    name: params.name,
-    navigationBar: params.tabMenuDiv
-  });
-  params.tabMenuDiv.appendChild(navLi);
-
-  var contentDiv = guiUtils.createTabContentObject({
-    id: id,
-    navigationObject: navLi,
-    navigationBar: params.tabMenuDiv
-  });
-
-  $(contentDiv).css("overflow","auto");
-  if (params.content !== undefined) {
-    contentDiv.appendChild(params.content);
-  }
-
-  params.tabContentDiv.appendChild(contentDiv);
-};
-
-function getStringIfDefined(value) {
-  if (value === undefined) {
-    return "";
-  }
-  return xss(value);
-}
-
-EditUserDialog.prototype.createGeneralTabContent = function () {
-
-  var self = this;
-
-  var result = Functions.createElement({
-    type: "div",
-    style: "margin-top:10px;"
-  });
-
-  var table = Functions.createElement({
-    type: "table",
-    name: "detailsTable",
-    className: "display",
-    style: "width:100%"
-  });
-  result.appendChild(table);
-
-  var menuRow = Functions.createElement({
-    type: "div",
-    className: "minerva-menu-row",
-    style: "display:table-row; margin:10px"
-  });
-  result.appendChild(menuRow);
-
-  var saveUserButton = Functions.createElement({
-    type: "button",
-    name: "saveUser",
-    content: '<span class="ui-icon ui-icon-disk"></span>&nbsp;SAVE',
-    onclick: function () {
-      return self.onSaveClicked().then(function () {
-        return self.close();
-      }, GuiConnector.alert);
-    },
-    xss: false
-  });
-  var cancelButton = Functions.createElement({
-    type: "button",
-    name: "cancelProject",
-    content: '<span class="ui-icon ui-icon-cancel"></span>&nbsp;CANCEL',
-    onclick: function () {
-      return self.close();
-    },
-    xss: false
-  });
-  menuRow.appendChild(saveUserButton);
-  menuRow.appendChild(cancelButton);
-
-  return result;
-
-};
-
-EditUserDialog.prototype.createPrivilegesTabContent = function () {
-  var self = this;
-  var result = Functions.createElement({
-    type: "div",
-    style: "margin-top:10px;"
-  });
-  result.appendChild(self._createPrivilegesTable());
-  return result;
-};
-
-EditUserDialog.prototype._createPrivilegesTable = function () {
-  var result = Functions.createElement({
-    type: "div",
-    style: "margin-top:10px;"
-  });
-
-  var privilegesTable = Functions.createElement({
-    type: "table",
-    name: "privilegesTable",
-    className: "display",
-    style: "width:100%"
-  });
-  result.appendChild(privilegesTable);
-
-  return result;
-};
-
-
-EditUserDialog.prototype.createProjectsTab = function (tabMenuDiv, tabContentDiv) {
-  var self = this;
-  self.addTab({
-    tabMenuDiv: tabMenuDiv,
-    tabContentDiv: tabContentDiv,
-    name: "PROJECT PRIVILEGES",
-    content: self.createProjectsTabContent()
-  });
-};
-
-EditUserDialog.prototype.createProjectsTabContent = function () {
-  var self = this;
-  var result = Functions.createElement({
-    type: "div",
-    style: "margin-top:10px;"
-  });
-  result.appendChild(self._createProjectsTable());
-  return result;
-};
-
-EditUserDialog.prototype._createProjectsTable = function () {
-  var result = Functions.createElement({
-    type: "div",
-    style: "margin-top:10px;"
-  });
-
-  result.appendChild(Functions.createElement({
-    type: "div",
-    name: "defaultProjectsRow",
-    style: "width:100%"
-  }));
-
-  result.appendChild(Functions.createElement({
-    type: "table",
-    name: "projectsTable",
-    className: "display",
-    style: "width:100%"
-  }));
-
-  return result;
-};
-
-EditUserDialog.prototype.init = function () {
-  var self = this;
-
-  var detailsTable = $("[name=detailsTable]", self.getElement())[0];
-
-  var dataTable = $(detailsTable).DataTable({
-    columns: [{
-      title: "Name"
-    }, {
-      title: "Value"
-    }],
-    paging: false,
-    ordering: false,
-    searching: false,
-    bInfo: false
-  });
-  var data = [];
-
-  var user = self.getUser();
-
-  var readonly = '';
-  if (user.getLogin() !== undefined) {
-    readonly = ' readonly ';
-  }
-  data.push(['Login', '<input name="userLogin" value="' + getStringIfDefined(user.getLogin()) + '" ' + readonly + '/>']);
-  data.push(['Password', '<input type="password" name="userPassword" value=""/>']);
-  data.push(['Confirm password', '<input type="password" name="userPassword2" value=""/>']);
-  data.push(['Name', '<input name="userName" value="' + getStringIfDefined(user.getName()) + '"/>']);
-  data.push(['Surname', '<input name="userSurname" value="' + getStringIfDefined(user.getSurname()) + '"/>']);
-  data.push(['Email', '<input name="userEmail" value="' + getStringIfDefined(user.getEmail()) + '"/>']);
-
-  dataTable.clear().rows.add(data).draw();
-
-  return self.initProjectsTab().then(function () {
-    return self.refreshProjects();
-  }).then(function () {
-    return self.initPrivilegesTab();
-  }).then(function () {
-    $(window).trigger('resize');
-  });
-};
-
-EditUserDialog.prototype.initProjectsTab = function () {
-  var self = this;
-
-  var usersTable = $("[name=projectsTable]", self.getElement())[0];
-
-  var configuration;
-  return ServerConnector.getConfiguration().then(function (result) {
-    configuration = result;
-    return self.createUserPrivilegeColumns()
-  }).then(function (columns) {
-    $(usersTable).DataTable({
-      columns: columns
-    });
-    $(usersTable).on("click", "[name='project-privilege-checkbox']", function () {
-      var data = $(this).attr("data").split("-");
-      var privilegeType = data[0];
-      var objectId = data[1];
-      var value = $(this).is(":checked");
-      for (var i = 0; i < configuration.getPrivilegeTypes().length; i++) {
-        var privilege = configuration.getPrivilegeTypes()[i];
-        if (privilege.getName() === privilegeType) {
-          self.getUser().setPrivilege({type: privilege, value: value, objectId: objectId});
-        }
-      }
-    });
-
-    $("[name='defaultProjectsRow']", self.getElement()).on("click", "[name='project-privilege-checkbox']", function () {
-      var data = $(this).attr("data").split("-");
-      var privilegeType = data[0];
-      var objectId = data[1];
-      var value = $(this).is(":checked");
-      for (var i = 0; i < configuration.getPrivilegeTypes().length; i++) {
-        var privilege = configuration.getPrivilegeTypes()[i];
-        if (privilege.getName() === privilegeType) {
-          self.getUser().setPrivilege({type: privilege, value: value, objectId: objectId});
-        }
-      }
-    });
-
-  });
-};
-
-EditUserDialog.prototype.initPrivilegesTab = function () {
-  var self = this;
-
-  var usersTable = $("[name=privilegesTable]", self.getElement())[0];
-
-  return ServerConnector.getConfiguration().then(function (configuration) {
-    var columns = [{
-      title: "Name"
-    }, {
-      title: "Value"
-    }];
-    var dataTable = $(usersTable).DataTable({
-      columns: columns
-    });
-    var data = [];
-
-    for (var i = 0; i < configuration.getPrivilegeTypes().length; i++) {
-      var privilege = configuration.getPrivilegeTypes()[i];
-      if (privilege.getObjectType() === null) {
-        if (privilege.getValueType() === "boolean") {
-          var checked = "";
-          if (self.getUser().hasPrivilege(privilege)) {
-            checked = "checked"
-          }
-          data.push([
-            "<span>" + privilege.getCommonName() + "</span>",
-            "<input type='checkbox' name='privilege-checkbox' data='" + privilege.getName() + "' " + checked + " />"
-          ]);
-        } else if (privilege.getValueType() === "int") {
-          data.push([
-            "<span>" + privilege.getCommonName() + "</span>",
-            "<input name='privilege-int' data='" + privilege.getName() + "' value='" + self.getUser().getPrivilegeValue(privilege) + "' />"
-          ]);
-
-        }
-      }
-    }
-    dataTable.clear().rows.add(data).draw();
-    $(usersTable).on("click", "[name='privilege-checkbox']", function () {
-      var privilegeType = $(this).attr("data");
-      for (var i = 0; i < configuration.getPrivilegeTypes().length; i++) {
-        var privilege = configuration.getPrivilegeTypes()[i];
-        if (privilege.getName() === privilegeType) {
-          self.getUser().setPrivilege({type: privilege, value: $(this).is(":checked")});
-        }
-      }
-    });
-    $(usersTable).on("change", "[name='privilege-int']", function () {
-      var privilegeType = $(this).attr("data");
-      var value = $(this).val();
-      value = parseInt(value);
-      if (Functions.isInt(value)) {
-        for (var i = 0; i < configuration.getPrivilegeTypes().length; i++) {
-          var privilege = configuration.getPrivilegeTypes()[i];
-          if (privilege.getName() === privilegeType) {
-            self.getUser().setPrivilege({type: privilege, value: value});
-          }
-        }
-      }
-    });
-  });
-};
-
-EditUserDialog.prototype.refreshProjects = function () {
-  var self = this;
-  return ServerConnector.getProjects().then(function (projects) {
-    return self.setProjects(projects);
-  });
-};
-
-EditUserDialog.prototype.setProjects = function (projects) {
-  var self = this;
-  self._userByLogin = [];
-  return self.createUserPrivilegeColumns().then(function (columns) {
-    var dataTable = $("[name='projectsTable']", self.getElement()).DataTable();
-    var data = [], i;
-
-    var rowData = self.projectToTableRow(null, columns);
-    var defaultRow = $("[name='defaultProjectsRow']", self.getElement())[0];
-    defaultRow.innerHTML = "";
-    defaultRow.appendChild(Functions.createElement({
-      type: "span",
-      content: rowData[0],
-      xss: false
-    }));
-    defaultRow.appendChild(Functions.createElement({type: "br"}));
-    for (i = 1; i < columns.length; i++) {
-      defaultRow.appendChild(Functions.createElement({
-        type: "div",
-        content: rowData[i] + columns[i].title,
-        style: "float:left;padding:5px;",
-        xss: false
-      }));
-    }
-    defaultRow.appendChild(Functions.createElement({type: "br"}));
-    defaultRow.appendChild(Functions.createElement({type: "hr"}));
-    // data.push(rowData);
-    for (i = 0; i < projects.length; i++) {
-      var project = projects[i];
-      rowData = self.projectToTableRow(project, columns);
-      data.push(rowData);
-    }
-    dataTable.clear().rows.add(data).draw();
-  });
-};
-
-EditUserDialog.prototype.projectToTableRow = function (project, columns) {
-  var user = this.getUser();
-  var row = [];
-  var id = null;
-  var projectId = "<b>DEFAULT PRIVILEGE FOR NEW PROJECT</b>";
-  if (project !== null) {
-    id = project.getId();
-    projectId = project.getProjectId();
-  }
-
-  row[0] = "<span data='" + id + "'>" + projectId + "</span>";
-
-  for (var i = 1; i < columns.length; i++) {
-    var privilege = columns[i].privilegeType;
-    var checked = "";
-    if (user.hasPrivilege(privilege, id)) {
-      checked = "checked";
-    }
-    row.push("<input type='checkbox' name='project-privilege-checkbox' data='" + privilege.getName() + "-" + id + "' " + checked + " />");
-  }
-
-  return row;
-};
-
-
-EditUserDialog.prototype.destroy = function () {
-  var self = this;
-  var div = self.getElement();
-  var usersTable = $("[name=projectsTable]", div)[0];
-  if ($.fn.DataTable.isDataTable(usersTable)) {
-    $(usersTable).DataTable().destroy();
-  }
-
-  var privilegesTable = $("[name=privilegesTable]", div)[0];
-  if ($.fn.DataTable.isDataTable(privilegesTable)) {
-    $(privilegesTable).DataTable().destroy();
-  }
-
-  var detailsTable = $("[name=detailsTable]", div)[0];
-  if ($.fn.DataTable.isDataTable(detailsTable)) {
-    $(detailsTable).DataTable().destroy();
-  }
-
-
-  if ($(div).hasClass("ui-dialog-content")) {
-    $(div).dialog("destroy");
-  }
-};
-
-EditUserDialog.prototype.open = function () {
-  var self = this;
-  var div = self.getElement();
-  var title = self.getUser().getLogin();
-  if (title === undefined) {
-    title = "NEW USER";
-  }
-  if (!$(div).hasClass("ui-dialog-content")) {
-    $(div).dialog({
-      title: title,
-      width: window.innerWidth / 2,
-      height: window.innerHeight / 2
-    });
-  }
-  $(div).dialog("open");
-};
-
-EditUserDialog.prototype.onSaveClicked = function () {
-  var self = this;
-  var user = self.getUser();
-  return self.checkValidity().then(function () {
-    user.setLogin(self.getLogin());
-    user.setPassword(self.getPassword());
-    user.setEmail(self.getEmail());
-    user.setName(self.getName());
-    user.setSurname(self.getSurname());
-    if (self.getIsNewUser()) {
-      return ServerConnector.addUser(user);
-    } else {
-      return ServerConnector.updateUser(user);
-    }
-  }).then(function () {
-    return self.callListeners("onSave", user);
-  });
-};
-
-EditUserDialog.prototype.checkValidity = function () {
-  var self = this;
-  var isValid = true;
-  var error = "<b>Some data is missing.</b><ul>";
-  if (self.getPassword() !== self.getPassword2()) {
-    error += "<li>Password doesn't match</li>";
-    isValid = false;
-  }
-  if (self.getLogin() === "" || self.getLogin() === undefined || self.getLogin() === null) {
-    error += "<li>Login must not be empty</li>";
-    isValid = false;
-  }
-  var promise = Promise.resolve();
-  if (self.getUser().getLogin() !== self.getLogin()) {
-    promise = ServerConnector.getUser(self.getLogin()).then(function (remoteUser) {
-      if (remoteUser !== null) {
-        error += "<li>Login already used</li>";
-        isValid = false;
-      }
-    });
-  }
-  return promise.then(function () {
-    if (isValid) {
-      return Promise.resolve(true);
-    } else {
-      return Promise.reject(new ValidationError(error));
-    }
-  });
-};
-
-EditUserDialog.prototype.getPassword = function () {
-  var self = this;
-  return $("[name='userPassword']", self.getElement()).val();
-};
-EditUserDialog.prototype.getPassword2 = function () {
-  var self = this;
-  return $("[name='userPassword2']", self.getElement()).val();
-};
-
-EditUserDialog.prototype.getLogin = function () {
-  var self = this;
-  return $("[name='userLogin']", self.getElement()).val();
-};
-
-EditUserDialog.prototype.getEmail = function () {
-  var self = this;
-  return $("[name='userEmail']", self.getElement()).val();
-};
-EditUserDialog.prototype.getName = function () {
-  var self = this;
-  return $("[name='userName']", self.getElement()).val();
-};
-EditUserDialog.prototype.getSurname = function () {
-  var self = this;
-  return $("[name='userSurname']", self.getElement()).val();
-};
-
-
-EditUserDialog.prototype.close = function () {
-  var self = this;
-  $(self.getElement()).dialog("close");
-};
-
-EditUserDialog.prototype.createUserPrivilegeColumns = function () {
-  var self = this;
-
-  if (self._userPrivilegeColumns !== undefined) {
-    return Promise.resolve(self._userPrivilegeColumns);
-  }
-
-  return ServerConnector.getConfiguration().then(function (configuration) {
-    self._userPrivilegeColumns = [{
-      title: "ProjectId"
-    }];
-    var privilegeTypes = configuration.getPrivilegeTypes();
-    for (var i = 0; i < privilegeTypes.length; i++) {
-      var type = privilegeTypes[i];
-      if (type.getObjectType() === "Project") {
-        self._userPrivilegeColumns.push({
-          "title": type.getCommonName(),
-          privilegeType: type
-        });
-      }
-    }
-    return self._userPrivilegeColumns;
-  });
-
-};
-
-
-module.exports = EditUserDialog;
+"use strict";
+
+var Promise = require("bluebird");
+var xss = require('xss');
+
+var AbstractGuiElement = require('../AbstractGuiElement');
+var GuiConnector = require('../../GuiConnector');
+var ValidationError = require('../../ValidationError');
+
+var Functions = require('../../Functions');
+// noinspection JSUnusedLocalSymbols
+var logger = require('../../logger');
+
+var guiUtils = new (require('../leftPanel/GuiUtils'))();
+
+function EditUserDialog(params) {
+  AbstractGuiElement.call(this, params);
+  var self = this;
+  self.setUser(params.user);
+
+  $(self.getElement()).css({overflow: "hidden"});
+
+  self.createGui();
+  self.registerListenerType("onSave");
+}
+
+EditUserDialog.prototype = Object.create(AbstractGuiElement.prototype);
+EditUserDialog.prototype.constructor = EditUserDialog;
+
+EditUserDialog.prototype.setUser = function (user) {
+  this._user = user;
+  this.setIsNewUser(user.getLogin() === undefined);
+};
+EditUserDialog.prototype.getUser = function () {
+  return this._user;
+};
+
+EditUserDialog.prototype.setIsNewUser = function (isNewUser) {
+  this._isNewUser = isNewUser;
+};
+EditUserDialog.prototype.getIsNewUser = function () {
+  return this._isNewUser;
+};
+
+EditUserDialog.prototype.createGui = function () {
+  var self = this;
+  var element = self.getElement();
+
+  var tabDiv = Functions.createElement({
+    type: "div",
+    name: "tabView",
+    className: "tabbable boxed parentTabs",
+    style: "position:absolute;top:10px;bottom:40px;left:10px;right:10px"
+  });
+  element.appendChild(tabDiv);
+
+  var tabMenuDiv = Functions.createElement({
+    type: "ul",
+    className: "nav nav-tabs"
+  });
+  tabDiv.appendChild(tabMenuDiv);
+
+  var tabContentDiv = Functions.createElement({
+    type: "div",
+    className: "tab-content",
+    style: "height:100%"
+  });
+  tabDiv.appendChild(tabContentDiv);
+
+  self.createGeneralTab(tabMenuDiv, tabContentDiv);
+  self.createPrivilegesTab(tabMenuDiv, tabContentDiv);
+  self.createProjectsTab(tabMenuDiv, tabContentDiv);
+  $("a", tabMenuDiv).bind("click", function () {
+    //workaround for some css issues...
+    tabDiv.style.top = "40px";
+    tabDiv.style.bottom = "10px";
+  });
+};
+
+EditUserDialog.prototype.createGeneralTab = function (tabMenuDiv, tabContentDiv) {
+  var self = this;
+  self.addTab({
+    tabMenuDiv: tabMenuDiv,
+    tabContentDiv: tabContentDiv,
+    name: "DETAILS",
+    content: self.createGeneralTabContent()
+  });
+
+};
+
+var login_counter = 0;
+
+EditUserDialog.prototype.generateTabId = function (tab_name) {
+  var self = this;
+  var login = self.getUser().getLogin();
+  if (login === undefined) {
+    login = "new_user_" + (login_counter++);
+  }
+  return login.replace(".", "_") + tab_name.replace(" ", "_") + "_TAB";
+};
+
+EditUserDialog.prototype.createPrivilegesTab = function (tabMenuDiv, tabContentDiv) {
+  var self = this;
+  self.addTab({
+    tabMenuDiv: tabMenuDiv,
+    tabContentDiv: tabContentDiv,
+    name: "GLOBAL PRIVILEGES",
+    content: self.createPrivilegesTabContent()
+  });
+
+};
+
+EditUserDialog.prototype.addTab = function (params) {
+  var id = this.generateTabId(params.name);
+
+  var navLi = guiUtils.createTabMenuObject({
+    id: id,
+    name: params.name,
+    navigationBar: params.tabMenuDiv
+  });
+  params.tabMenuDiv.appendChild(navLi);
+
+  var contentDiv = guiUtils.createTabContentObject({
+    id: id,
+    navigationObject: navLi,
+    navigationBar: params.tabMenuDiv
+  });
+
+  $(contentDiv).css("overflow","auto");
+  if (params.content !== undefined) {
+    contentDiv.appendChild(params.content);
+  }
+
+  params.tabContentDiv.appendChild(contentDiv);
+};
+
+function getStringIfDefined(value) {
+  if (value === undefined) {
+    return "";
+  }
+  return xss(value);
+}
+
+EditUserDialog.prototype.createGeneralTabContent = function () {
+
+  var self = this;
+
+  var result = Functions.createElement({
+    type: "div",
+    style: "margin-top:10px;"
+  });
+
+  var table = Functions.createElement({
+    type: "table",
+    name: "detailsTable",
+    className: "display",
+    style: "width:100%"
+  });
+  result.appendChild(table);
+
+  var menuRow = Functions.createElement({
+    type: "div",
+    className: "minerva-menu-row",
+    style: "display:table-row; margin:10px"
+  });
+  result.appendChild(menuRow);
+
+  var saveUserButton = Functions.createElement({
+    type: "button",
+    name: "saveUser",
+    content: '<span class="ui-icon ui-icon-disk"></span>&nbsp;SAVE',
+    onclick: function () {
+      return self.onSaveClicked().then(function () {
+        return self.close();
+      }, GuiConnector.alert);
+    },
+    xss: false
+  });
+  var cancelButton = Functions.createElement({
+    type: "button",
+    name: "cancelProject",
+    content: '<span class="ui-icon ui-icon-cancel"></span>&nbsp;CANCEL',
+    onclick: function () {
+      return self.close();
+    },
+    xss: false
+  });
+  menuRow.appendChild(saveUserButton);
+  menuRow.appendChild(cancelButton);
+
+  return result;
+
+};
+
+EditUserDialog.prototype.createPrivilegesTabContent = function () {
+  var self = this;
+  var result = Functions.createElement({
+    type: "div",
+    style: "margin-top:10px;"
+  });
+  result.appendChild(self._createPrivilegesTable());
+  return result;
+};
+
+EditUserDialog.prototype._createPrivilegesTable = function () {
+  var result = Functions.createElement({
+    type: "div",
+    style: "margin-top:10px;"
+  });
+
+  var privilegesTable = Functions.createElement({
+    type: "table",
+    name: "privilegesTable",
+    className: "display",
+    style: "width:100%"
+  });
+  result.appendChild(privilegesTable);
+
+  return result;
+};
+
+
+EditUserDialog.prototype.createProjectsTab = function (tabMenuDiv, tabContentDiv) {
+  var self = this;
+  self.addTab({
+    tabMenuDiv: tabMenuDiv,
+    tabContentDiv: tabContentDiv,
+    name: "PROJECT PRIVILEGES",
+    content: self.createProjectsTabContent()
+  });
+};
+
+EditUserDialog.prototype.createProjectsTabContent = function () {
+  var self = this;
+  var result = Functions.createElement({
+    type: "div",
+    style: "margin-top:10px;"
+  });
+  result.appendChild(self._createProjectsTable());
+  return result;
+};
+
+EditUserDialog.prototype._createProjectsTable = function () {
+  var result = Functions.createElement({
+    type: "div",
+    style: "margin-top:10px;"
+  });
+
+  result.appendChild(Functions.createElement({
+    type: "div",
+    name: "defaultProjectsRow",
+    style: "width:100%"
+  }));
+
+  result.appendChild(Functions.createElement({
+    type: "table",
+    name: "projectsTable",
+    className: "display",
+    style: "width:100%"
+  }));
+
+  return result;
+};
+
+EditUserDialog.prototype.init = function () {
+  var self = this;
+
+  var detailsTable = $("[name=detailsTable]", self.getElement())[0];
+
+  var dataTable = $(detailsTable).DataTable({
+    columns: [{
+      title: "Name"
+    }, {
+      title: "Value"
+    }],
+    paging: false,
+    ordering: false,
+    searching: false,
+    bInfo: false
+  });
+  var data = [];
+
+  var user = self.getUser();
+
+  var readonly = '';
+  if (user.getLogin() !== undefined) {
+    readonly = ' readonly ';
+  }
+  data.push(['Login', '<input name="userLogin" value="' + getStringIfDefined(user.getLogin()) + '" ' + readonly + '/>']);
+  data.push(['Password', '<input type="password" name="userPassword" value=""/>']);
+  data.push(['Confirm password', '<input type="password" name="userPassword2" value=""/>']);
+  data.push(['Name', '<input name="userName" value="' + getStringIfDefined(user.getName()) + '"/>']);
+  data.push(['Surname', '<input name="userSurname" value="' + getStringIfDefined(user.getSurname()) + '"/>']);
+  data.push(['Email', '<input name="userEmail" value="' + getStringIfDefined(user.getEmail()) + '"/>']);
+
+  dataTable.clear().rows.add(data).draw();
+
+  return self.initProjectsTab().then(function () {
+    return self.refreshProjects();
+  }).then(function () {
+    return self.initPrivilegesTab();
+  }).then(function () {
+    $(window).trigger('resize');
+  });
+};
+
+EditUserDialog.prototype.initProjectsTab = function () {
+  var self = this;
+
+  var usersTable = $("[name=projectsTable]", self.getElement())[0];
+
+  var configuration;
+  return ServerConnector.getConfiguration().then(function (result) {
+    configuration = result;
+    return self.createUserPrivilegeColumns()
+  }).then(function (columns) {
+    $(usersTable).DataTable({
+      columns: columns
+    });
+    $(usersTable).on("click", "[name='project-privilege-checkbox']", function () {
+      var data = $(this).attr("data").split("-");
+      var privilegeType = data[0];
+      var objectId = data[1];
+      var value = $(this).is(":checked");
+      for (var i = 0; i < configuration.getPrivilegeTypes().length; i++) {
+        var privilege = configuration.getPrivilegeTypes()[i];
+        if (privilege.getName() === privilegeType) {
+          self.getUser().setPrivilege({type: privilege, value: value, objectId: objectId});
+        }
+      }
+    });
+
+    $("[name='defaultProjectsRow']", self.getElement()).on("click", "[name='project-privilege-checkbox']", function () {
+      var data = $(this).attr("data").split("-");
+      var privilegeType = data[0];
+      var objectId = data[1];
+      var value = $(this).is(":checked");
+      for (var i = 0; i < configuration.getPrivilegeTypes().length; i++) {
+        var privilege = configuration.getPrivilegeTypes()[i];
+        if (privilege.getName() === privilegeType) {
+          self.getUser().setPrivilege({type: privilege, value: value, objectId: objectId});
+        }
+      }
+    });
+
+  });
+};
+
+EditUserDialog.prototype.initPrivilegesTab = function () {
+  var self = this;
+
+  var usersTable = $("[name=privilegesTable]", self.getElement())[0];
+
+  return ServerConnector.getConfiguration().then(function (configuration) {
+    var columns = [{
+      title: "Name"
+    }, {
+      title: "Value"
+    }];
+    var dataTable = $(usersTable).DataTable({
+      columns: columns
+    });
+    var data = [];
+
+    for (var i = 0; i < configuration.getPrivilegeTypes().length; i++) {
+      var privilege = configuration.getPrivilegeTypes()[i];
+      if (privilege.getObjectType() === null) {
+        if (privilege.getValueType() === "boolean") {
+          var checked = "";
+          if (self.getUser().hasPrivilege(privilege)) {
+            checked = "checked"
+          }
+          data.push([
+            "<span>" + privilege.getCommonName() + "</span>",
+            "<input type='checkbox' name='privilege-checkbox' data='" + privilege.getName() + "' " + checked + " />"
+          ]);
+        } else if (privilege.getValueType() === "int") {
+          data.push([
+            "<span>" + privilege.getCommonName() + "</span>",
+            "<input name='privilege-int' data='" + privilege.getName() + "' value='" + self.getUser().getPrivilegeValue(privilege) + "' />"
+          ]);
+
+        }
+      }
+    }
+    dataTable.clear().rows.add(data).draw();
+    $(usersTable).on("click", "[name='privilege-checkbox']", function () {
+      var privilegeType = $(this).attr("data");
+      for (var i = 0; i < configuration.getPrivilegeTypes().length; i++) {
+        var privilege = configuration.getPrivilegeTypes()[i];
+        if (privilege.getName() === privilegeType) {
+          self.getUser().setPrivilege({type: privilege, value: $(this).is(":checked")});
+        }
+      }
+    });
+    $(usersTable).on("change", "[name='privilege-int']", function () {
+      var privilegeType = $(this).attr("data");
+      var value = $(this).val();
+      value = parseInt(value);
+      if (Functions.isInt(value)) {
+        for (var i = 0; i < configuration.getPrivilegeTypes().length; i++) {
+          var privilege = configuration.getPrivilegeTypes()[i];
+          if (privilege.getName() === privilegeType) {
+            self.getUser().setPrivilege({type: privilege, value: value});
+          }
+        }
+      }
+    });
+  });
+};
+
+EditUserDialog.prototype.refreshProjects = function () {
+  var self = this;
+  return ServerConnector.getProjects().then(function (projects) {
+    return self.setProjects(projects);
+  });
+};
+
+EditUserDialog.prototype.setProjects = function (projects) {
+  var self = this;
+  self._userByLogin = [];
+  return self.createUserPrivilegeColumns().then(function (columns) {
+    var dataTable = $("[name='projectsTable']", self.getElement()).DataTable();
+    var data = [], i;
+
+    var rowData = self.projectToTableRow(null, columns);
+    var defaultRow = $("[name='defaultProjectsRow']", self.getElement())[0];
+    defaultRow.innerHTML = "";
+    defaultRow.appendChild(Functions.createElement({
+      type: "span",
+      content: rowData[0],
+      xss: false
+    }));
+    defaultRow.appendChild(Functions.createElement({type: "br"}));
+    for (i = 1; i < columns.length; i++) {
+      defaultRow.appendChild(Functions.createElement({
+        type: "div",
+        content: rowData[i] + columns[i].title,
+        style: "float:left;padding:5px;",
+        xss: false
+      }));
+    }
+    defaultRow.appendChild(Functions.createElement({type: "br"}));
+    defaultRow.appendChild(Functions.createElement({type: "hr"}));
+    // data.push(rowData);
+    for (i = 0; i < projects.length; i++) {
+      var project = projects[i];
+      rowData = self.projectToTableRow(project, columns);
+      data.push(rowData);
+    }
+    dataTable.clear().rows.add(data).draw();
+  });
+};
+
+EditUserDialog.prototype.projectToTableRow = function (project, columns) {
+  var user = this.getUser();
+  var row = [];
+  var id = null;
+  var projectId = "<b>DEFAULT PRIVILEGE FOR NEW PROJECT</b>";
+  if (project !== null) {
+    id = project.getId();
+    projectId = project.getProjectId();
+  }
+
+  row[0] = "<span data='" + id + "'>" + projectId + "</span>";
+
+  for (var i = 1; i < columns.length; i++) {
+    var privilege = columns[i].privilegeType;
+    var checked = "";
+    if (user.hasPrivilege(privilege, id)) {
+      checked = "checked";
+    }
+    row.push("<input type='checkbox' name='project-privilege-checkbox' data='" + privilege.getName() + "-" + id + "' " + checked + " />");
+  }
+
+  return row;
+};
+
+
+EditUserDialog.prototype.destroy = function () {
+  var self = this;
+  var div = self.getElement();
+  var usersTable = $("[name=projectsTable]", div)[0];
+  if ($.fn.DataTable.isDataTable(usersTable)) {
+    $(usersTable).DataTable().destroy();
+  }
+
+  var privilegesTable = $("[name=privilegesTable]", div)[0];
+  if ($.fn.DataTable.isDataTable(privilegesTable)) {
+    $(privilegesTable).DataTable().destroy();
+  }
+
+  var detailsTable = $("[name=detailsTable]", div)[0];
+  if ($.fn.DataTable.isDataTable(detailsTable)) {
+    $(detailsTable).DataTable().destroy();
+  }
+
+
+  if ($(div).hasClass("ui-dialog-content")) {
+    $(div).dialog("destroy");
+  }
+};
+
+EditUserDialog.prototype.open = function () {
+  var self = this;
+  var div = self.getElement();
+  var title = self.getUser().getLogin();
+  if (title === undefined) {
+    title = "NEW USER";
+  }
+  if (!$(div).hasClass("ui-dialog-content")) {
+    $(div).dialog({
+      title: title,
+      width: window.innerWidth / 2,
+      height: window.innerHeight / 2
+    });
+  }
+  $(div).dialog("open");
+};
+
+EditUserDialog.prototype.onSaveClicked = function () {
+  var self = this;
+  var user = self.getUser();
+  return self.checkValidity().then(function () {
+    user.setLogin(self.getLogin());
+    user.setPassword(self.getPassword());
+    user.setEmail(self.getEmail());
+    user.setName(self.getName());
+    user.setSurname(self.getSurname());
+    if (self.getIsNewUser()) {
+      return ServerConnector.addUser(user);
+    } else {
+      return ServerConnector.updateUser(user);
+    }
+  }).then(function () {
+    return self.callListeners("onSave", user);
+  });
+};
+
+EditUserDialog.prototype.checkValidity = function () {
+  var self = this;
+  var isValid = true;
+  var error = "<b>Some data is missing.</b><ul>";
+  if (self.getPassword() !== self.getPassword2()) {
+    error += "<li>Password doesn't match</li>";
+    isValid = false;
+  }
+  if (self.getLogin() === "" || self.getLogin() === undefined || self.getLogin() === null) {
+    error += "<li>Login must not be empty</li>";
+    isValid = false;
+  }
+  var promise = Promise.resolve();
+  if (self.getUser().getLogin() !== self.getLogin()) {
+    promise = ServerConnector.getUser(self.getLogin()).then(function (remoteUser) {
+      if (remoteUser !== null) {
+        error += "<li>Login already used</li>";
+        isValid = false;
+      }
+    });
+  }
+  return promise.then(function () {
+    if (isValid) {
+      return Promise.resolve(true);
+    } else {
+      return Promise.reject(new ValidationError(error));
+    }
+  });
+};
+
+EditUserDialog.prototype.getPassword = function () {
+  var self = this;
+  return $("[name='userPassword']", self.getElement()).val();
+};
+EditUserDialog.prototype.getPassword2 = function () {
+  var self = this;
+  return $("[name='userPassword2']", self.getElement()).val();
+};
+
+EditUserDialog.prototype.getLogin = function () {
+  var self = this;
+  return $("[name='userLogin']", self.getElement()).val();
+};
+
+EditUserDialog.prototype.getEmail = function () {
+  var self = this;
+  return $("[name='userEmail']", self.getElement()).val();
+};
+EditUserDialog.prototype.getName = function () {
+  var self = this;
+  return $("[name='userName']", self.getElement()).val();
+};
+EditUserDialog.prototype.getSurname = function () {
+  var self = this;
+  return $("[name='userSurname']", self.getElement()).val();
+};
+
+
+EditUserDialog.prototype.close = function () {
+  var self = this;
+  $(self.getElement()).dialog("close");
+};
+
+EditUserDialog.prototype.createUserPrivilegeColumns = function () {
+  var self = this;
+
+  if (self._userPrivilegeColumns !== undefined) {
+    return Promise.resolve(self._userPrivilegeColumns);
+  }
+
+  return ServerConnector.getConfiguration().then(function (configuration) {
+    self._userPrivilegeColumns = [{
+      title: "ProjectId"
+    }];
+    var privilegeTypes = configuration.getPrivilegeTypes();
+    for (var i = 0; i < privilegeTypes.length; i++) {
+      var type = privilegeTypes[i];
+      if (type.getObjectType() === "Project") {
+        self._userPrivilegeColumns.push({
+          "title": type.getCommonName(),
+          privilegeType: type
+        });
+      }
+    }
+    return self._userPrivilegeColumns;
+  });
+
+};
+
+
+module.exports = EditUserDialog;
diff --git a/frontend-js/src/main/js/gui/admin/GenomeAdminPanel.js b/frontend-js/src/main/js/gui/admin/GenomeAdminPanel.js
index 7abf854ec353de6035bb7ca3caf24739982c2efd..afece10d70d1c7d0ee1dcb3574f75b270ccf6c8b 100644
--- a/frontend-js/src/main/js/gui/admin/GenomeAdminPanel.js
+++ b/frontend-js/src/main/js/gui/admin/GenomeAdminPanel.js
@@ -1,326 +1,326 @@
-"use strict";
-
-var AbstractAdminPanel = require('./AbstractAdminPanel');
-var EditGenomeDialog = require('./EditGenomeDialog');
-
-var Functions = require('../../Functions');
-var GuiConnector = require('../../GuiConnector');
-var PrivilegeType = require('../../map/data/PrivilegeType');
-var ReferenceGenome = require('../../map/data/ReferenceGenome');
-
-// noinspection JSUnusedLocalSymbols
-var logger = require('../../logger');
-
-var Promise = require('bluebird');
-
-/**
- *
- * @param {Configuration} params.configuration
- * @param {HTMLElement} params.element
- *
- * @constructor
- */
-function GenomeAdminPanel(params) {
-  params["panelName"] = "genomes";
-  AbstractAdminPanel.call(this, params);
-
-  var self = this;
-  $(self.getElement()).addClass("minerva-genome-tab");
-
-  self._createGui();
-}
-
-GenomeAdminPanel.prototype = Object.create(AbstractAdminPanel.prototype);
-GenomeAdminPanel.prototype.constructor = GenomeAdminPanel;
-
-/**
- *
- * @private
- */
-GenomeAdminPanel.prototype._createGui = function () {
-  var self = this;
-  var genomeDiv = Functions.createElement({
-    type: "div"
-  });
-  self.getElement().appendChild(genomeDiv);
-
-  genomeDiv.appendChild(self._createMenuRow());
-
-  var genomesTable = Functions.createElement({
-    type: "table",
-    name: "genomeTable",
-    className: "display",
-    style: "width:100%"
-  });
-  genomeDiv.appendChild(genomesTable);
-
-  // noinspection JSUnusedGlobalSymbols
-  $(genomesTable).DataTable({
-    columns: [{
-      title: 'Type'
-    }, {
-      title: 'Organism'
-    }, {
-      title: 'Version'
-    }, {
-      title: 'Progress'
-    }, {
-      title: 'Source'
-    }, {
-      title: 'Edit',
-      orderable: false
-    }, {
-      title: 'Remove',
-      orderable: false
-    }],
-    order: [[1, "asc"]]
-  });
-  self.bindUserGuiPreference({
-    jQueryObject: $(genomesTable),
-    event: 'length.dt',
-    preferenceName: 'admin-genome-datatable-length',
-    defaultValue: '10',
-    getter: function () {
-      return $(genomesTable).DataTable().page.len() + '';
-    },
-    setter: function (value) {
-      return $(genomesTable).DataTable().page.len(value).draw();
-    }
-  });
-
-  $(genomesTable).on("click", "[name='removeGenome']", function () {
-    var button = this;
-    return self.askConfirmRemoval({
-      title: "INFO",
-      content: "Do you really want to remove this genome?",
-      input: false
-    }).then(function (param) {
-      if (param.status) {
-        return self.getServerConnector().removeReferenceGenome({genomeId: $(button).attr("data")});
-      }
-    }).catch(GuiConnector.alert);
-  });
-
-  $(genomesTable).on("click", "[name='editGenome']", function () {
-    var button = this;
-    return self.showEditDialog(parseInt($(button).attr("data"))).catch(GuiConnector.alert);
-  });
-
-  genomeDiv.appendChild(self._createMenuRow());
-
-};
-
-/**
- *
- * @returns {HTMLElement}
- * @private
- */
-GenomeAdminPanel.prototype._createMenuRow = function () {
-  var self = this;
-  var menuRow = Functions.createElement({
-    type: "div",
-    className: "minerva-menu-row",
-    style: "display:table-row; margin:10px"
-  });
-
-  var addProjectButton = Functions.createElement({
-    type: "button",
-    name: "addGenome",
-    content: '<span class="ui-icon ui-icon-circle-plus"></span>&nbsp;ADD GENOME',
-    onclick: function () {
-      return self.onAddClicked().catch(GuiConnector.alert);
-    },
-    xss: false
-  });
-  var refreshButton = Functions.createElement({
-    type: "button",
-    name: "refreshGenomes",
-    content: '<span class="ui-icon ui-icon-refresh"></span>&nbsp;REFRESH',
-    onclick: function () {
-      return self.onRefreshClicked().catch(GuiConnector.alert);
-    },
-    xss: false
-  });
-  menuRow.appendChild(addProjectButton);
-  menuRow.appendChild(refreshButton);
-  return menuRow;
-};
-
-/**
- *
- * @returns {Promise}
- */
-GenomeAdminPanel.prototype.init = function () {
-  var self = this;
-  return AbstractAdminPanel.prototype.init.call(this).then(function () {
-    return self.getServerConnector().getLoggedUser();
-  }).then(function (user) {
-    if (user.hasPrivilege(self.getConfiguration().getPrivilegeType(PrivilegeType.MANAGE_GENOMES))) {
-      return self.onRefreshClicked();
-    } else {
-      self.disablePanel("You have no privilege to manage genomes");
-    }
-  });
-};
-
-/**
- *
- * @returns {Promise}
- */
-GenomeAdminPanel.prototype.onRefreshClicked = function () {
-  var self = this;
-  return self.getServerConnector().getReferenceGenomes().then(function (referenceGenomes) {
-    return self.setReferenceGenomes(referenceGenomes);
-  });
-};
-
-/**
- *
- * @param {ReferenceGenome[]} referenceGenomes
- *
- * @returns {Promise}
- *
- */
-GenomeAdminPanel.prototype.setReferenceGenomes = function (referenceGenomes) {
-  var self = this;
-
-  return self.getServerConnector().getLoggedUser().then(function (user) {
-
-    var dataTable = $("[name='genomeTable']", self.getElement()).DataTable();
-    var data = [];
-    var page = dataTable.page();
-
-    for (var i = 0; i < referenceGenomes.length; i++) {
-      var genome = referenceGenomes[i];
-      var rowData = self.genomeToTableRow(genome, user);
-      data.push(rowData);
-    }
-    //it should be simplified, but I couldn't make it work
-    dataTable.clear().rows.add(data).page(page).draw(false).page(page).draw(false);
-  })
-};
-
-/**
- *
- * @param {ReferenceGenome} genome
- * @param {User} user
- * @returns {Array}
- */
-GenomeAdminPanel.prototype.genomeToTableRow = function (genome, user) {
-  var self = this;
-  var row = [];
-
-  row[0] = genome.getType();
-  row[1] = self.getGuiUtils().createAnnotationLink(genome.getOrganism()).outerHTML;
-  row[2] = genome.getVersion();
-  row[3] = genome.getDownloadProgressStatus();
-  row[4] = genome.getSourceUrl();
-
-  var disabled = " disabled ";
-  if (user.hasPrivilege(self.getConfiguration().getPrivilegeType(PrivilegeType.MANAGE_GENOMES))) {
-    disabled = "";
-  }
-  row[5] = "<button name='editGenome' data='" + genome.getId() + "'" + disabled + "><i class='fa fa-edit' style='font-size:17px'></i></button>";
-  row[6] = "<button name='removeGenome' data='" + genome.getId() + "'" + disabled + "><i class='fa fa-trash-o' style='font-size:17px'></button>";
-  return row;
-};
-
-
-/**
- *
- * @returns {Promise}
- */
-GenomeAdminPanel.prototype.destroy = function () {
-  var self = this;
-  var table = $("[name='genomeTable']", self.getElement())[0];
-  if ($.fn.DataTable.isDataTable(table)) {
-    $(table).DataTable().destroy();
-  }
-  var promises = [];
-  for (var key in self._dialogs) {
-    if (self._dialogs.hasOwnProperty(key)) {
-      promises.push(self._dialogs[key].destroy());
-    }
-  }
-  promises.push(AbstractAdminPanel.prototype.destroy.call(self));
-
-  return Promise.all(promises);
-};
-
-/**
- *
- * @param {ReferenceGenome} [genome]
- * @returns {Promise}
- */
-GenomeAdminPanel.prototype.getDialog = function (genome) {
-  var self = this;
-  if (self._dialogs === undefined) {
-    self._dialogs = [];
-  }
-  var id = genome.getId();
-  var dialog = self._dialogs[id];
-  if (dialog === undefined) {
-    dialog = new EditGenomeDialog({
-      element: Functions.createElement({
-        type: "div"
-      }),
-      configuration: self.getConfiguration(),
-      referenceGenome: genome,
-      customMap: null,
-      serverConnector: self.getServerConnector()
-    });
-    self._dialogs[id] = dialog;
-    if (id === undefined) {
-      dialog.addListener("onSave", function () {
-        return self.onRefreshClicked();
-      });
-    }
-    return dialog.init().then(function () {
-      return dialog;
-    });
-  } else {
-    return Promise.resolve(dialog);
-  }
-};
-
-/**
- *
- * @param {number} id
- * @returns {Promise}
- */
-GenomeAdminPanel.prototype.showEditDialog = function (id) {
-  var self = this;
-  GuiConnector.showProcessing();
-  return self.getServerConnector().getReferenceGenome({genomeId: id}).then(function (referenceGenome) {
-    if (referenceGenome === null) {
-      referenceGenome = new ReferenceGenome();
-    }
-    return self.getDialog(referenceGenome);
-  }).then(function (dialog) {
-    dialog.open();
-    GuiConnector.hideProcessing();
-  }).catch(function (error) {
-    GuiConnector.hideProcessing();
-    return Promise.reject(error);
-  });
-};
-
-/**
- *
- * @returns {Promise}
- */
-GenomeAdminPanel.prototype.onAddClicked = function () {
-  var self = this;
-  GuiConnector.showProcessing();
-  var referenceGenome = new ReferenceGenome();
-  return self.getDialog(referenceGenome).then(function (dialog) {
-    dialog.open();
-    GuiConnector.hideProcessing();
-  }).catch(function (error) {
-    GuiConnector.hideProcessing();
-    return Promise.reject(error);
-  });
-};
-
-
-module.exports = GenomeAdminPanel;
+"use strict";
+
+var AbstractAdminPanel = require('./AbstractAdminPanel');
+var EditGenomeDialog = require('./EditGenomeDialog');
+
+var Functions = require('../../Functions');
+var GuiConnector = require('../../GuiConnector');
+var PrivilegeType = require('../../map/data/PrivilegeType');
+var ReferenceGenome = require('../../map/data/ReferenceGenome');
+
+// noinspection JSUnusedLocalSymbols
+var logger = require('../../logger');
+
+var Promise = require('bluebird');
+
+/**
+ *
+ * @param {Configuration} params.configuration
+ * @param {HTMLElement} params.element
+ *
+ * @constructor
+ */
+function GenomeAdminPanel(params) {
+  params["panelName"] = "genomes";
+  AbstractAdminPanel.call(this, params);
+
+  var self = this;
+  $(self.getElement()).addClass("minerva-genome-tab");
+
+  self._createGui();
+}
+
+GenomeAdminPanel.prototype = Object.create(AbstractAdminPanel.prototype);
+GenomeAdminPanel.prototype.constructor = GenomeAdminPanel;
+
+/**
+ *
+ * @private
+ */
+GenomeAdminPanel.prototype._createGui = function () {
+  var self = this;
+  var genomeDiv = Functions.createElement({
+    type: "div"
+  });
+  self.getElement().appendChild(genomeDiv);
+
+  genomeDiv.appendChild(self._createMenuRow());
+
+  var genomesTable = Functions.createElement({
+    type: "table",
+    name: "genomeTable",
+    className: "display",
+    style: "width:100%"
+  });
+  genomeDiv.appendChild(genomesTable);
+
+  // noinspection JSUnusedGlobalSymbols
+  $(genomesTable).DataTable({
+    columns: [{
+      title: 'Type'
+    }, {
+      title: 'Organism'
+    }, {
+      title: 'Version'
+    }, {
+      title: 'Progress'
+    }, {
+      title: 'Source'
+    }, {
+      title: 'Edit',
+      orderable: false
+    }, {
+      title: 'Remove',
+      orderable: false
+    }],
+    order: [[1, "asc"]]
+  });
+  self.bindUserGuiPreference({
+    jQueryObject: $(genomesTable),
+    event: 'length.dt',
+    preferenceName: 'admin-genome-datatable-length',
+    defaultValue: '10',
+    getter: function () {
+      return $(genomesTable).DataTable().page.len() + '';
+    },
+    setter: function (value) {
+      return $(genomesTable).DataTable().page.len(value).draw();
+    }
+  });
+
+  $(genomesTable).on("click", "[name='removeGenome']", function () {
+    var button = this;
+    return self.askConfirmRemoval({
+      title: "INFO",
+      content: "Do you really want to remove this genome?",
+      input: false
+    }).then(function (param) {
+      if (param.status) {
+        return self.getServerConnector().removeReferenceGenome({genomeId: $(button).attr("data")});
+      }
+    }).catch(GuiConnector.alert);
+  });
+
+  $(genomesTable).on("click", "[name='editGenome']", function () {
+    var button = this;
+    return self.showEditDialog(parseInt($(button).attr("data"))).catch(GuiConnector.alert);
+  });
+
+  genomeDiv.appendChild(self._createMenuRow());
+
+};
+
+/**
+ *
+ * @returns {HTMLElement}
+ * @private
+ */
+GenomeAdminPanel.prototype._createMenuRow = function () {
+  var self = this;
+  var menuRow = Functions.createElement({
+    type: "div",
+    className: "minerva-menu-row",
+    style: "display:table-row; margin:10px"
+  });
+
+  var addProjectButton = Functions.createElement({
+    type: "button",
+    name: "addGenome",
+    content: '<span class="ui-icon ui-icon-circle-plus"></span>&nbsp;ADD GENOME',
+    onclick: function () {
+      return self.onAddClicked().catch(GuiConnector.alert);
+    },
+    xss: false
+  });
+  var refreshButton = Functions.createElement({
+    type: "button",
+    name: "refreshGenomes",
+    content: '<span class="ui-icon ui-icon-refresh"></span>&nbsp;REFRESH',
+    onclick: function () {
+      return self.onRefreshClicked().catch(GuiConnector.alert);
+    },
+    xss: false
+  });
+  menuRow.appendChild(addProjectButton);
+  menuRow.appendChild(refreshButton);
+  return menuRow;
+};
+
+/**
+ *
+ * @returns {Promise}
+ */
+GenomeAdminPanel.prototype.init = function () {
+  var self = this;
+  return AbstractAdminPanel.prototype.init.call(this).then(function () {
+    return self.getServerConnector().getLoggedUser();
+  }).then(function (user) {
+    if (user.hasPrivilege(self.getConfiguration().getPrivilegeType(PrivilegeType.MANAGE_GENOMES))) {
+      return self.onRefreshClicked();
+    } else {
+      self.disablePanel("You have no privilege to manage genomes");
+    }
+  });
+};
+
+/**
+ *
+ * @returns {Promise}
+ */
+GenomeAdminPanel.prototype.onRefreshClicked = function () {
+  var self = this;
+  return self.getServerConnector().getReferenceGenomes().then(function (referenceGenomes) {
+    return self.setReferenceGenomes(referenceGenomes);
+  });
+};
+
+/**
+ *
+ * @param {ReferenceGenome[]} referenceGenomes
+ *
+ * @returns {Promise}
+ *
+ */
+GenomeAdminPanel.prototype.setReferenceGenomes = function (referenceGenomes) {
+  var self = this;
+
+  return self.getServerConnector().getLoggedUser().then(function (user) {
+
+    var dataTable = $("[name='genomeTable']", self.getElement()).DataTable();
+    var data = [];
+    var page = dataTable.page();
+
+    for (var i = 0; i < referenceGenomes.length; i++) {
+      var genome = referenceGenomes[i];
+      var rowData = self.genomeToTableRow(genome, user);
+      data.push(rowData);
+    }
+    //it should be simplified, but I couldn't make it work
+    dataTable.clear().rows.add(data).page(page).draw(false).page(page).draw(false);
+  })
+};
+
+/**
+ *
+ * @param {ReferenceGenome} genome
+ * @param {User} user
+ * @returns {Array}
+ */
+GenomeAdminPanel.prototype.genomeToTableRow = function (genome, user) {
+  var self = this;
+  var row = [];
+
+  row[0] = genome.getType();
+  row[1] = self.getGuiUtils().createAnnotationLink(genome.getOrganism()).outerHTML;
+  row[2] = genome.getVersion();
+  row[3] = genome.getDownloadProgressStatus();
+  row[4] = genome.getSourceUrl();
+
+  var disabled = " disabled ";
+  if (user.hasPrivilege(self.getConfiguration().getPrivilegeType(PrivilegeType.MANAGE_GENOMES))) {
+    disabled = "";
+  }
+  row[5] = "<button name='editGenome' data='" + genome.getId() + "'" + disabled + "><i class='fa fa-edit' style='font-size:17px'></i></button>";
+  row[6] = "<button name='removeGenome' data='" + genome.getId() + "'" + disabled + "><i class='fa fa-trash-o' style='font-size:17px'></button>";
+  return row;
+};
+
+
+/**
+ *
+ * @returns {Promise}
+ */
+GenomeAdminPanel.prototype.destroy = function () {
+  var self = this;
+  var table = $("[name='genomeTable']", self.getElement())[0];
+  if ($.fn.DataTable.isDataTable(table)) {
+    $(table).DataTable().destroy();
+  }
+  var promises = [];
+  for (var key in self._dialogs) {
+    if (self._dialogs.hasOwnProperty(key)) {
+      promises.push(self._dialogs[key].destroy());
+    }
+  }
+  promises.push(AbstractAdminPanel.prototype.destroy.call(self));
+
+  return Promise.all(promises);
+};
+
+/**
+ *
+ * @param {ReferenceGenome} [genome]
+ * @returns {Promise}
+ */
+GenomeAdminPanel.prototype.getDialog = function (genome) {
+  var self = this;
+  if (self._dialogs === undefined) {
+    self._dialogs = [];
+  }
+  var id = genome.getId();
+  var dialog = self._dialogs[id];
+  if (dialog === undefined) {
+    dialog = new EditGenomeDialog({
+      element: Functions.createElement({
+        type: "div"
+      }),
+      configuration: self.getConfiguration(),
+      referenceGenome: genome,
+      customMap: null,
+      serverConnector: self.getServerConnector()
+    });
+    self._dialogs[id] = dialog;
+    if (id === undefined) {
+      dialog.addListener("onSave", function () {
+        return self.onRefreshClicked();
+      });
+    }
+    return dialog.init().then(function () {
+      return dialog;
+    });
+  } else {
+    return Promise.resolve(dialog);
+  }
+};
+
+/**
+ *
+ * @param {number} id
+ * @returns {Promise}
+ */
+GenomeAdminPanel.prototype.showEditDialog = function (id) {
+  var self = this;
+  GuiConnector.showProcessing();
+  return self.getServerConnector().getReferenceGenome({genomeId: id}).then(function (referenceGenome) {
+    if (referenceGenome === null) {
+      referenceGenome = new ReferenceGenome();
+    }
+    return self.getDialog(referenceGenome);
+  }).then(function (dialog) {
+    dialog.open();
+    GuiConnector.hideProcessing();
+  }).catch(function (error) {
+    GuiConnector.hideProcessing();
+    return Promise.reject(error);
+  });
+};
+
+/**
+ *
+ * @returns {Promise}
+ */
+GenomeAdminPanel.prototype.onAddClicked = function () {
+  var self = this;
+  GuiConnector.showProcessing();
+  var referenceGenome = new ReferenceGenome();
+  return self.getDialog(referenceGenome).then(function (dialog) {
+    dialog.open();
+    GuiConnector.hideProcessing();
+  }).catch(function (error) {
+    GuiConnector.hideProcessing();
+    return Promise.reject(error);
+  });
+};
+
+
+module.exports = GenomeAdminPanel;
diff --git a/frontend-js/src/main/js/gui/admin/MapsAdminPanel.js b/frontend-js/src/main/js/gui/admin/MapsAdminPanel.js
index f09ccc985410b0478df811e8365d18119e36d6d6..e99f74c9480b6ddd4042797ff7550fbf2d400d5c 100644
--- a/frontend-js/src/main/js/gui/admin/MapsAdminPanel.js
+++ b/frontend-js/src/main/js/gui/admin/MapsAdminPanel.js
@@ -1,433 +1,433 @@
-"use strict";
-
-/* exported logger */
-
-var AbstractAdminPanel = require('./AbstractAdminPanel');
-var AddProjectDialog = require('./AddProjectDialog');
-var EditProjectDialog = require('./EditProjectDialog');
-var LogListDialog = require('./LogListDialog');
-var PrivilegeType = require('../../map/data/PrivilegeType');
-var UserPreferences = require('../../map/data/UserPreferences');
-
-// noinspection JSUnusedLocalSymbols
-var logger = require('../../logger');
-
-var Functions = require('../../Functions');
-var GuiConnector = require('../../GuiConnector');
-var Promise = require("bluebird");
-
-function MapsAdminPanel(params) {
-  var self = this;
-  AbstractAdminPanel.call(self, params);
-  self._createGui();
-
-  $(self.getElement()).addClass("minerva-projects-tab");
-
-}
-
-MapsAdminPanel.prototype = Object.create(AbstractAdminPanel.prototype);
-MapsAdminPanel.prototype.constructor = MapsAdminPanel;
-
-MapsAdminPanel.prototype._createGui = function () {
-  var self = this;
-  var projectsDiv = Functions.createElement({
-    type: "div"
-  });
-  self.getElement().appendChild(projectsDiv);
-
-  var dataDiv = Functions.createElement({
-    type: "div",
-    style: "display:table; width:100%"
-  });
-  projectsDiv.appendChild(dataDiv);
-
-  dataDiv.appendChild(self._createMenuRow());
-  dataDiv.appendChild(self._createProjectTableRow());
-  dataDiv.appendChild(self._createMenuRow());
-
-};
-
-MapsAdminPanel.prototype._createMenuRow = function () {
-  var self = this;
-  var menuRow = Functions.createElement({
-    type: "div",
-    className: "minerva-menu-row",
-    style: "display:table-row; margin:10px"
-  });
-
-  var addProjectButton = Functions.createElement({
-    type: "button",
-    name: "addProject",
-    content: '<span class="ui-icon ui-icon-circle-plus"></span>&nbsp;ADD PROJECT',
-    onclick: function () {
-      return self.onAddClicked().then(null, GuiConnector.alert);
-    },
-    xss: false
-  });
-  var refreshButton = Functions.createElement({
-    type: "button",
-    name: "refreshProject",
-    content: '<span class="ui-icon ui-icon-refresh"></span>&nbsp;REFRESH',
-    onclick: function () {
-      return self.onRefreshClicked().then(null, GuiConnector.alert);
-    },
-    xss: false
-  });
-  menuRow.appendChild(addProjectButton);
-  menuRow.appendChild(refreshButton);
-  return menuRow;
-};
-
-MapsAdminPanel.prototype._createProjectTableRow = function () {
-  var self = this;
-  var projectsRow = Functions.createElement({
-    type: "div",
-    style: "display:table-row; width:100%"
-  });
-
-  var projectsTable = Functions.createElement({
-    type: "table",
-    name: "projectsTable",
-    className: "display",
-    style: "width:100%"
-  });
-  projectsRow.appendChild(projectsTable);
-
-  $(projectsTable).DataTable({
-    columns: [{
-      title: 'ProjectId'
-    }, {
-      title: 'Name'
-    }, {
-      title: 'Disease'
-    }, {
-      title: 'Organism'
-    }, {
-      title: 'Status'
-    }, {
-      title: 'Edit'
-    }, {
-      title: 'Remove'
-    }]
-  });
-  self.bindUserGuiPreference({
-    jQueryObject: $(projectsTable),
-    event: 'length.dt',
-    preferenceName: 'admin-projects-datatable-length',
-    defaultValue: '10',
-    getter: function () {
-      return $(projectsTable).DataTable().page.len() + '';
-    },
-    setter: function (value) {
-      return $(projectsTable).DataTable().page.len(value).draw();
-    }
-  });
-
-  $(projectsTable).on("click", "[name='removeProject']", function () {
-    var button = this;
-    return self.askConfirmRemoval({
-      title: "INFO",
-      content: "Do you really want to remove '" + $(button).attr("data") + "' map?",
-      input: false
-    }).then(function (param) {
-      if (param.status) {
-        return self.removeProject($(button).attr("data"))
-      }
-    }).catch(GuiConnector.alert);
-  });
-
-  $(projectsTable).on("click", "[name='showEditDialog']", function () {
-    var button = this;
-    return self.showEditDialog($(button).attr("data")).then(null, GuiConnector.alert);
-  });
-  $(projectsTable).on("click", "[name='showErrors']", function () {
-    var button = this;
-    return self.showLogs($(button).attr("data"), 'error').then(null, GuiConnector.alert);
-  });
-  $(projectsTable).on("click", "[name='showWarnings']", function () {
-    var button = this;
-    return self.showLogs($(button).attr("data"), 'warning').then(null, GuiConnector.alert);
-  });
-
-  return projectsRow;
-};
-
-/**
- *
- * @returns {Promise}
- */
-MapsAdminPanel.prototype.init = function () {
-  var self = this;
-  return self.getServerConnector().getProjects().then(function (projects) {
-    return self.setProjects(projects);
-  });
-};
-
-/**
- *
- * @param {Project} project
- * @param {Array} [row]
- * @param {User} user
- * @returns {Array}
- */
-MapsAdminPanel.prototype.projectToTableRow = function (project, row, user) {
-  var self = this;
-  var disease = self.getHtmlStringLink(project.getDisease());
-  var organism = self.getHtmlStringLink(project.getOrganism());
-
-  if (row === undefined) {
-    row = [];
-  }
-  var projectId = project.getProjectId();
-  var formattedProjectId;
-  if (project.getStatus().toLowerCase() === "ok") {
-    formattedProjectId = "<a href='" + "index.xhtml?id=" + projectId + "' target='" + projectId + "'>" + projectId + "</a>";
-  } else {
-    formattedProjectId = projectId;
-  }
-  var status = project.getStatus();
-  if (project.hasErrors()) {
-    status += "<a name='showErrors' href='#' data='" + project.getProjectId() + "'>" +
-      "<i class='fa fa-exclamation-triangle' style='font-size:18px; font-weight:400; padding-right:10px;color:red'></i>" +
-      "</a>";
-  }
-  if (project.hasWarnings()) {
-    status += "<a name='showWarnings' href='#' data='" + project.getProjectId() + "'>" +
-      "<i class='fa fa-exclamation-triangle' style='font-size:18px; font-weight:400; padding-right:10px;color:black'></i>" +
-      "</a>";
-  }
-
-  row[0] = formattedProjectId;
-  row[1] = project.getName();
-  row[2] = disease;
-  row[3] = organism;
-  row[4] = status;
-
-  var disabled = " disabled ";
-  if (user.hasPrivilege(self.getConfiguration().getPrivilegeType(PrivilegeType.CONFIGURATION_MANAGE))) {
-    disabled = "";
-  }
-  row[5] = "<button name='showEditDialog' data='" + project.getProjectId() + "'" + disabled + "><i class='fa fa-edit' style='font-size:17px'></i></button>";
-  row[6] = "<button name='removeProject' data='" + project.getProjectId() + "'" + disabled + "><i class='fa fa-trash-o' style='font-size:17px'></button>";
-
-  return row;
-};
-
-MapsAdminPanel.prototype.getHtmlStringLink = function (annotation) {
-  var self = this;
-  if (annotation !== undefined && annotation !== null) {
-    var link = self.getGuiUtils().createAnnotationLink(annotation, true);
-    var tmp = document.createElement("div");
-    tmp.appendChild(link);
-    return tmp.innerHTML;
-  } else {
-    return "N/A";
-  }
-
-};
-
-/**
- *
- * @param {Project[]} projects
- * @returns {Promise}
- */
-MapsAdminPanel.prototype.setProjects = function (projects) {
-  var self = this;
-
-  return self.getServerConnector().getLoggedUser().then(function (user) {
-    var dataTable = $("[name='projectsTable']", self.getElement()).DataTable();
-    var data = [];
-    var page = dataTable.page();
-
-    for (var i = 0; i < projects.length; i++) {
-      var project = projects[i];
-      var rowData = self.projectToTableRow(project, undefined, user);
-      self.addUpdateListener(project, rowData);
-      data.push(rowData);
-    }
-    //it should be simplified, but I couldn't make it work
-    dataTable.clear().rows.add(data).page(page).draw(false).page(page).draw(false);
-  });
-};
-
-MapsAdminPanel.prototype.addUpdateListener = function (project, dataTableRow) {
-  var self = this;
-
-  var listenerName = "PROJECT_LIST_LISTENER";
-  var listeners = project.getListeners("onreload");
-  for (var i = 0; i < listeners.length; i++) {
-    if (listeners[i].listenerName === listenerName) {
-      project.removeListener("onreload", listeners[i]);
-    }
-  }
-  var listener = function () {
-    return self.getServerConnector().getLoggedUser().then(function (user) {
-      self.projectToTableRow(project, dataTableRow, user);
-      var row = $($("[name='projectsTable']", self.getElement())[0]).DataTable().row("#" + project.getProjectId());
-      if (row.length > 0) {
-        row.data(dataTableRow).draw();
-      }
-    });
-  };
-  listener.listenerName = listenerName;
-  project.addListener("onreload", listener);
-};
-
-MapsAdminPanel.prototype.onAddClicked = function () {
-  var self = this;
-  var dialog = self._addDialog;
-  if (dialog === undefined) {
-    dialog = new AddProjectDialog({
-      element: Functions.createElement({
-        type: "div"
-      }),
-      customMap: null,
-      configuration: self.getConfiguration(),
-      serverConnector: self.getServerConnector()
-    });
-    self._addDialog = dialog;
-    dialog.addListener("onProjectAdd", function () {
-      return self.onRefreshClicked()
-    });
-    return dialog.init().then(function () {
-      return dialog.open();
-    });
-  } else {
-    dialog.clear();
-    dialog.open();
-    return Promise.resolve();
-  }
-};
-
-MapsAdminPanel.prototype.destroy = function () {
-  var promises = [];
-  var self = this;
-  var dialog = self._addDialog;
-  if (dialog !== undefined) {
-    promises.push(dialog.destroy());
-  }
-  var table = $("[name='projectsTable']", self.getElement())[0];
-  if ($.fn.DataTable.isDataTable(table)) {
-    promises.push($(table).DataTable().destroy());
-  }
-
-  var key;
-  for (key in self._logDialogs) {
-    if (self._logDialogs.hasOwnProperty(key)) {
-      promises.push(self._logDialogs[key].destroy());
-    }
-  }
-  for (key in self._dialogs) {
-    if (self._dialogs.hasOwnProperty(key)) {
-      promises.push(self._dialogs[key].destroy());
-    }
-  }
-  return Promise.all(promises);
-};
-
-MapsAdminPanel.prototype.onRefreshClicked = function () {
-  var self = this;
-  return ServerConnector.getProjects(true).then(function (projects) {
-    return self.setProjects(projects);
-  }).then(function () {
-    return ServerConnector.getLoggedUser();
-  }).then(function (user) {
-    var privilege = self.getConfiguration().getPrivilegeType(PrivilegeType.USER_MANAGEMENT);
-    //we need to refresh users as well because of privileges
-    if (user.hasPrivilege(privilege)) {
-      return ServerConnector.getUsers(true);
-    } else {
-      return Promise.resolve();
-    }
-  });
-};
-
-MapsAdminPanel.prototype.getDialog = function (project) {
-  var self = this;
-  if (self._dialogs === undefined) {
-    self._dialogs = [];
-  }
-  var dialog = self._dialogs[project.getProjectId()];
-  if (dialog === undefined) {
-    dialog = new EditProjectDialog({
-      element: Functions.createElement({
-        type: "div"
-      }),
-      project: project,
-      configuration: self.getConfiguration(),
-      customMap: null
-    });
-    self._dialogs[project.getProjectId()] = dialog;
-    return dialog.init().then(function () {
-      return dialog.addListener("onSave", function () {
-        return self.onRefreshClicked()
-      });
-    }).then(function () {
-      return dialog;
-    });
-  } else {
-    return Promise.resolve(dialog);
-  }
-};
-
-MapsAdminPanel.prototype.getLogDialog = function (projectId, level) {
-  var self = this;
-  if (self._logDialogs === undefined) {
-    self._logDialogs = [];
-  }
-  var dialog = self._logDialogs[projectId + "-" + level];
-  if (dialog === undefined) {
-    dialog = new LogListDialog({
-      element: Functions.createElement({
-        type: "div"
-      }),
-      projectId: projectId,
-      customMap: null,
-      level: level
-    });
-    self._logDialogs[projectId + "-" + level] = dialog;
-    return dialog.init().then(function () {
-      return dialog;
-    });
-  } else {
-    return Promise.resolve(dialog);
-  }
-};
-
-MapsAdminPanel.prototype.showEditDialog = function (id) {
-  var self = this;
-  GuiConnector.showProcessing();
-  return ServerConnector.getProject(id).then(function (project) {
-    return self.getDialog(project);
-  }).then(function (dialog) {
-
-    dialog.open();
-    GuiConnector.hideProcessing();
-  }).then(null, function (error) {
-    GuiConnector.hideProcessing();
-    return Promise.reject(error);
-  });
-};
-
-MapsAdminPanel.prototype.showLogs = function (id, level) {
-  var self = this;
-  GuiConnector.showProcessing();
-  return self.getLogDialog(id, level).then(function (dialog) {
-    return dialog.open();
-  }).then(function () {
-    GuiConnector.hideProcessing();
-  }, function (error) {
-    GuiConnector.hideProcessing();
-    return Promise.reject(error);
-  });
-};
-
-
-MapsAdminPanel.prototype.removeProject = function (id) {
-  var self = this;
-  return ServerConnector.removeProject(id).then(function () {
-    return self.onRefreshClicked();
-  });
-};
-
-module.exports = MapsAdminPanel;
+"use strict";
+
+/* exported logger */
+
+var AbstractAdminPanel = require('./AbstractAdminPanel');
+var AddProjectDialog = require('./AddProjectDialog');
+var EditProjectDialog = require('./EditProjectDialog');
+var LogListDialog = require('./LogListDialog');
+var PrivilegeType = require('../../map/data/PrivilegeType');
+var UserPreferences = require('../../map/data/UserPreferences');
+
+// noinspection JSUnusedLocalSymbols
+var logger = require('../../logger');
+
+var Functions = require('../../Functions');
+var GuiConnector = require('../../GuiConnector');
+var Promise = require("bluebird");
+
+function MapsAdminPanel(params) {
+  var self = this;
+  AbstractAdminPanel.call(self, params);
+  self._createGui();
+
+  $(self.getElement()).addClass("minerva-projects-tab");
+
+}
+
+MapsAdminPanel.prototype = Object.create(AbstractAdminPanel.prototype);
+MapsAdminPanel.prototype.constructor = MapsAdminPanel;
+
+MapsAdminPanel.prototype._createGui = function () {
+  var self = this;
+  var projectsDiv = Functions.createElement({
+    type: "div"
+  });
+  self.getElement().appendChild(projectsDiv);
+
+  var dataDiv = Functions.createElement({
+    type: "div",
+    style: "display:table; width:100%"
+  });
+  projectsDiv.appendChild(dataDiv);
+
+  dataDiv.appendChild(self._createMenuRow());
+  dataDiv.appendChild(self._createProjectTableRow());
+  dataDiv.appendChild(self._createMenuRow());
+
+};
+
+MapsAdminPanel.prototype._createMenuRow = function () {
+  var self = this;
+  var menuRow = Functions.createElement({
+    type: "div",
+    className: "minerva-menu-row",
+    style: "display:table-row; margin:10px"
+  });
+
+  var addProjectButton = Functions.createElement({
+    type: "button",
+    name: "addProject",
+    content: '<span class="ui-icon ui-icon-circle-plus"></span>&nbsp;ADD PROJECT',
+    onclick: function () {
+      return self.onAddClicked().then(null, GuiConnector.alert);
+    },
+    xss: false
+  });
+  var refreshButton = Functions.createElement({
+    type: "button",
+    name: "refreshProject",
+    content: '<span class="ui-icon ui-icon-refresh"></span>&nbsp;REFRESH',
+    onclick: function () {
+      return self.onRefreshClicked().then(null, GuiConnector.alert);
+    },
+    xss: false
+  });
+  menuRow.appendChild(addProjectButton);
+  menuRow.appendChild(refreshButton);
+  return menuRow;
+};
+
+MapsAdminPanel.prototype._createProjectTableRow = function () {
+  var self = this;
+  var projectsRow = Functions.createElement({
+    type: "div",
+    style: "display:table-row; width:100%"
+  });
+
+  var projectsTable = Functions.createElement({
+    type: "table",
+    name: "projectsTable",
+    className: "display",
+    style: "width:100%"
+  });
+  projectsRow.appendChild(projectsTable);
+
+  $(projectsTable).DataTable({
+    columns: [{
+      title: 'ProjectId'
+    }, {
+      title: 'Name'
+    }, {
+      title: 'Disease'
+    }, {
+      title: 'Organism'
+    }, {
+      title: 'Status'
+    }, {
+      title: 'Edit'
+    }, {
+      title: 'Remove'
+    }]
+  });
+  self.bindUserGuiPreference({
+    jQueryObject: $(projectsTable),
+    event: 'length.dt',
+    preferenceName: 'admin-projects-datatable-length',
+    defaultValue: '10',
+    getter: function () {
+      return $(projectsTable).DataTable().page.len() + '';
+    },
+    setter: function (value) {
+      return $(projectsTable).DataTable().page.len(value).draw();
+    }
+  });
+
+  $(projectsTable).on("click", "[name='removeProject']", function () {
+    var button = this;
+    return self.askConfirmRemoval({
+      title: "INFO",
+      content: "Do you really want to remove '" + $(button).attr("data") + "' map?",
+      input: false
+    }).then(function (param) {
+      if (param.status) {
+        return self.removeProject($(button).attr("data"))
+      }
+    }).catch(GuiConnector.alert);
+  });
+
+  $(projectsTable).on("click", "[name='showEditDialog']", function () {
+    var button = this;
+    return self.showEditDialog($(button).attr("data")).then(null, GuiConnector.alert);
+  });
+  $(projectsTable).on("click", "[name='showErrors']", function () {
+    var button = this;
+    return self.showLogs($(button).attr("data"), 'error').then(null, GuiConnector.alert);
+  });
+  $(projectsTable).on("click", "[name='showWarnings']", function () {
+    var button = this;
+    return self.showLogs($(button).attr("data"), 'warning').then(null, GuiConnector.alert);
+  });
+
+  return projectsRow;
+};
+
+/**
+ *
+ * @returns {Promise}
+ */
+MapsAdminPanel.prototype.init = function () {
+  var self = this;
+  return self.getServerConnector().getProjects().then(function (projects) {
+    return self.setProjects(projects);
+  });
+};
+
+/**
+ *
+ * @param {Project} project
+ * @param {Array} [row]
+ * @param {User} user
+ * @returns {Array}
+ */
+MapsAdminPanel.prototype.projectToTableRow = function (project, row, user) {
+  var self = this;
+  var disease = self.getHtmlStringLink(project.getDisease());
+  var organism = self.getHtmlStringLink(project.getOrganism());
+
+  if (row === undefined) {
+    row = [];
+  }
+  var projectId = project.getProjectId();
+  var formattedProjectId;
+  if (project.getStatus().toLowerCase() === "ok") {
+    formattedProjectId = "<a href='" + "index.xhtml?id=" + projectId + "' target='" + projectId + "'>" + projectId + "</a>";
+  } else {
+    formattedProjectId = projectId;
+  }
+  var status = project.getStatus();
+  if (project.hasErrors()) {
+    status += "<a name='showErrors' href='#' data='" + project.getProjectId() + "'>" +
+      "<i class='fa fa-exclamation-triangle' style='font-size:18px; font-weight:400; padding-right:10px;color:red'></i>" +
+      "</a>";
+  }
+  if (project.hasWarnings()) {
+    status += "<a name='showWarnings' href='#' data='" + project.getProjectId() + "'>" +
+      "<i class='fa fa-exclamation-triangle' style='font-size:18px; font-weight:400; padding-right:10px;color:black'></i>" +
+      "</a>";
+  }
+
+  row[0] = formattedProjectId;
+  row[1] = project.getName();
+  row[2] = disease;
+  row[3] = organism;
+  row[4] = status;
+
+  var disabled = " disabled ";
+  if (user.hasPrivilege(self.getConfiguration().getPrivilegeType(PrivilegeType.CONFIGURATION_MANAGE))) {
+    disabled = "";
+  }
+  row[5] = "<button name='showEditDialog' data='" + project.getProjectId() + "'" + disabled + "><i class='fa fa-edit' style='font-size:17px'></i></button>";
+  row[6] = "<button name='removeProject' data='" + project.getProjectId() + "'" + disabled + "><i class='fa fa-trash-o' style='font-size:17px'></button>";
+
+  return row;
+};
+
+MapsAdminPanel.prototype.getHtmlStringLink = function (annotation) {
+  var self = this;
+  if (annotation !== undefined && annotation !== null) {
+    var link = self.getGuiUtils().createAnnotationLink(annotation, true);
+    var tmp = document.createElement("div");
+    tmp.appendChild(link);
+    return tmp.innerHTML;
+  } else {
+    return "N/A";
+  }
+
+};
+
+/**
+ *
+ * @param {Project[]} projects
+ * @returns {Promise}
+ */
+MapsAdminPanel.prototype.setProjects = function (projects) {
+  var self = this;
+
+  return self.getServerConnector().getLoggedUser().then(function (user) {
+    var dataTable = $("[name='projectsTable']", self.getElement()).DataTable();
+    var data = [];
+    var page = dataTable.page();
+
+    for (var i = 0; i < projects.length; i++) {
+      var project = projects[i];
+      var rowData = self.projectToTableRow(project, undefined, user);
+      self.addUpdateListener(project, rowData);
+      data.push(rowData);
+    }
+    //it should be simplified, but I couldn't make it work
+    dataTable.clear().rows.add(data).page(page).draw(false).page(page).draw(false);
+  });
+};
+
+MapsAdminPanel.prototype.addUpdateListener = function (project, dataTableRow) {
+  var self = this;
+
+  var listenerName = "PROJECT_LIST_LISTENER";
+  var listeners = project.getListeners("onreload");
+  for (var i = 0; i < listeners.length; i++) {
+    if (listeners[i].listenerName === listenerName) {
+      project.removeListener("onreload", listeners[i]);
+    }
+  }
+  var listener = function () {
+    return self.getServerConnector().getLoggedUser().then(function (user) {
+      self.projectToTableRow(project, dataTableRow, user);
+      var row = $($("[name='projectsTable']", self.getElement())[0]).DataTable().row("#" + project.getProjectId());
+      if (row.length > 0) {
+        row.data(dataTableRow).draw();
+      }
+    });
+  };
+  listener.listenerName = listenerName;
+  project.addListener("onreload", listener);
+};
+
+MapsAdminPanel.prototype.onAddClicked = function () {
+  var self = this;
+  var dialog = self._addDialog;
+  if (dialog === undefined) {
+    dialog = new AddProjectDialog({
+      element: Functions.createElement({
+        type: "div"
+      }),
+      customMap: null,
+      configuration: self.getConfiguration(),
+      serverConnector: self.getServerConnector()
+    });
+    self._addDialog = dialog;
+    dialog.addListener("onProjectAdd", function () {
+      return self.onRefreshClicked()
+    });
+    return dialog.init().then(function () {
+      return dialog.open();
+    });
+  } else {
+    dialog.clear();
+    dialog.open();
+    return Promise.resolve();
+  }
+};
+
+MapsAdminPanel.prototype.destroy = function () {
+  var promises = [];
+  var self = this;
+  var dialog = self._addDialog;
+  if (dialog !== undefined) {
+    promises.push(dialog.destroy());
+  }
+  var table = $("[name='projectsTable']", self.getElement())[0];
+  if ($.fn.DataTable.isDataTable(table)) {
+    promises.push($(table).DataTable().destroy());
+  }
+
+  var key;
+  for (key in self._logDialogs) {
+    if (self._logDialogs.hasOwnProperty(key)) {
+      promises.push(self._logDialogs[key].destroy());
+    }
+  }
+  for (key in self._dialogs) {
+    if (self._dialogs.hasOwnProperty(key)) {
+      promises.push(self._dialogs[key].destroy());
+    }
+  }
+  return Promise.all(promises);
+};
+
+MapsAdminPanel.prototype.onRefreshClicked = function () {
+  var self = this;
+  return ServerConnector.getProjects(true).then(function (projects) {
+    return self.setProjects(projects);
+  }).then(function () {
+    return ServerConnector.getLoggedUser();
+  }).then(function (user) {
+    var privilege = self.getConfiguration().getPrivilegeType(PrivilegeType.USER_MANAGEMENT);
+    //we need to refresh users as well because of privileges
+    if (user.hasPrivilege(privilege)) {
+      return ServerConnector.getUsers(true);
+    } else {
+      return Promise.resolve();
+    }
+  });
+};
+
+MapsAdminPanel.prototype.getDialog = function (project) {
+  var self = this;
+  if (self._dialogs === undefined) {
+    self._dialogs = [];
+  }
+  var dialog = self._dialogs[project.getProjectId()];
+  if (dialog === undefined) {
+    dialog = new EditProjectDialog({
+      element: Functions.createElement({
+        type: "div"
+      }),
+      project: project,
+      configuration: self.getConfiguration(),
+      customMap: null
+    });
+    self._dialogs[project.getProjectId()] = dialog;
+    return dialog.init().then(function () {
+      return dialog.addListener("onSave", function () {
+        return self.onRefreshClicked()
+      });
+    }).then(function () {
+      return dialog;
+    });
+  } else {
+    return Promise.resolve(dialog);
+  }
+};
+
+MapsAdminPanel.prototype.getLogDialog = function (projectId, level) {
+  var self = this;
+  if (self._logDialogs === undefined) {
+    self._logDialogs = [];
+  }
+  var dialog = self._logDialogs[projectId + "-" + level];
+  if (dialog === undefined) {
+    dialog = new LogListDialog({
+      element: Functions.createElement({
+        type: "div"
+      }),
+      projectId: projectId,
+      customMap: null,
+      level: level
+    });
+    self._logDialogs[projectId + "-" + level] = dialog;
+    return dialog.init().then(function () {
+      return dialog;
+    });
+  } else {
+    return Promise.resolve(dialog);
+  }
+};
+
+MapsAdminPanel.prototype.showEditDialog = function (id) {
+  var self = this;
+  GuiConnector.showProcessing();
+  return ServerConnector.getProject(id).then(function (project) {
+    return self.getDialog(project);
+  }).then(function (dialog) {
+
+    dialog.open();
+    GuiConnector.hideProcessing();
+  }).then(null, function (error) {
+    GuiConnector.hideProcessing();
+    return Promise.reject(error);
+  });
+};
+
+MapsAdminPanel.prototype.showLogs = function (id, level) {
+  var self = this;
+  GuiConnector.showProcessing();
+  return self.getLogDialog(id, level).then(function (dialog) {
+    return dialog.open();
+  }).then(function () {
+    GuiConnector.hideProcessing();
+  }, function (error) {
+    GuiConnector.hideProcessing();
+    return Promise.reject(error);
+  });
+};
+
+
+MapsAdminPanel.prototype.removeProject = function (id) {
+  var self = this;
+  return ServerConnector.removeProject(id).then(function () {
+    return self.onRefreshClicked();
+  });
+};
+
+module.exports = MapsAdminPanel;
diff --git a/frontend-js/src/main/js/gui/admin/UsersAdminPanel.js b/frontend-js/src/main/js/gui/admin/UsersAdminPanel.js
index 1bbc720da8c241f3792adc69edae5d5705e3f409..2eb25ce86ccf98dcca46ae0316b02f832fd6855b 100644
--- a/frontend-js/src/main/js/gui/admin/UsersAdminPanel.js
+++ b/frontend-js/src/main/js/gui/admin/UsersAdminPanel.js
@@ -1,404 +1,404 @@
-"use strict";
-
-var Promise = require('bluebird');
-
-var PrivilegeType = require('../../map/data/PrivilegeType');
-
-var AbstractAdminPanel = require('./AbstractAdminPanel');
-var EditUserDialog = require('./EditUserDialog');
-
-var User = require("../../map/data/User");
-
-var Functions = require('../../Functions');
-var GuiConnector = require('../../GuiConnector');
-// noinspection JSUnusedLocalSymbols
-var logger = require('../../logger');
-
-/**
- *
- * @param {Object} params
- *
- * @constructor
- * @extends AbstractAdminPanel
- */
-function UsersAdminPanel(params) {
-  var self = this;
-  AbstractAdminPanel.call(self, params);
-  self._createGui();
-  $(self.getElement()).addClass("minerva-users-tab");
-}
-
-UsersAdminPanel.prototype = Object.create(AbstractAdminPanel.prototype);
-UsersAdminPanel.prototype.constructor = UsersAdminPanel;
-
-/**
- *
- * @private
- */
-UsersAdminPanel.prototype._createGui = function () {
-  var self = this;
-  var usersDiv = Functions.createElement({
-    type: "div"
-  });
-  self.getElement().appendChild(usersDiv);
-
-  var dataDiv = Functions.createElement({
-    type: "div",
-    style: "display:table; width:100%"
-  });
-  usersDiv.appendChild(dataDiv);
-
-  dataDiv.appendChild(self._createMenuRow());
-  dataDiv.appendChild(self._createUsersTableRow());
-  dataDiv.appendChild(self._createMenuRow());
-
-};
-
-/**
- *
- * @returns {HTMLElement}
- * @private
- */
-UsersAdminPanel.prototype._createMenuRow = function () {
-  var self = this;
-  var menuRow = Functions.createElement({
-    type: "div",
-    className: "minerva-menu-row",
-    style: "display:table-row; margin:10px"
-  });
-
-  var addUserButton = Functions.createElement({
-    type: "button",
-    name: "addProject",
-    content: '<span class="ui-icon ui-icon-circle-plus"></span>&nbsp;ADD USER',
-    onclick: function () {
-      return self.onAddClicked().then(null, GuiConnector.alert);
-    },
-    xss: false
-  });
-  var refreshButton = Functions.createElement({
-    type: "button",
-    name: "refreshProject",
-    content: '<span class="ui-icon ui-icon-refresh"></span>&nbsp;REFRESH',
-    onclick: function () {
-      return self.onRefreshClicked().then(null, GuiConnector.alert);
-    },
-    xss: false
-  });
-  menuRow.appendChild(addUserButton);
-  menuRow.appendChild(refreshButton);
-  return menuRow;
-};
-
-/**
- *
- * @returns {HTMLElement}
- * @private
- */
-UsersAdminPanel.prototype._createUsersTableRow = function () {
-  var self = this;
-  var projectsRow = Functions.createElement({
-    type: "div",
-    style: "display:table-row; width:100%"
-  });
-
-  var usersTable = Functions.createElement({
-    type: "table",
-    name: "usersTable",
-    className: "display",
-    style: "width:100%"
-  });
-  projectsRow.appendChild(usersTable);
-
-  // noinspection JSCheckFunctionSignatures
-  $(usersTable).DataTable({
-    fnRowCallback: function (nRow, aData) {
-      nRow.setAttribute('id', aData[0]);
-    },
-    columns: [{
-      title: 'Login'
-    }, {
-      title: 'Name'
-    }, {
-      title: 'Surname'
-    }, {
-      title: 'Email'
-    }, {
-      title: 'Authentication'
-    }, {
-      title: 'Edit'
-    }, {
-      title: 'Remove'
-    }]
-  });
-
-  self.bindUserGuiPreference({
-    jQueryObject: $(usersTable),
-    event: 'length.dt',
-    preferenceName: 'admin-users-datatable-length',
-    defaultValue: '10',
-    getter: function () {
-      return $(usersTable).DataTable().page.len() + '';
-    },
-    setter: function (value) {
-      return $(usersTable).DataTable().page.len(value).draw();
-    }
-  });
-
-  $(usersTable).on("click", "[name='removeUser']", function () {
-    var button = this;
-    return self.askConfirmRemoval({
-      title: "INFO",
-      content: "Do you really want to remove '" + $(button).attr("data") + "'user?",
-      input: false
-    }).then(function (param) {
-      if (param.status) {
-        return self.removeUser($(button).attr("data"))
-      }
-    }).catch(GuiConnector.alert);
-  });
-
-  $(usersTable).on("click", "[name='ldap-auth']", function () {
-    var field = this;
-    var login = $(this).attr('data');
-    GuiConnector.showProcessing();
-    return self.getServerConnector().getUser(login).then(function (user) {
-      var newIsConnected = $('input:checked', field).val() === "LDAP";
-      var isConnected = user.isConnectedToLdap();
-      if (isConnected !== newIsConnected) {
-        user.setConnectedToLdap(newIsConnected);
-        return self.getServerConnector().updateUser(user);
-      }
-    }).catch(function (error) {
-      GuiConnector.alert(error);
-    }).finally(function(){
-      GuiConnector.hideProcessing();
-    });
-  });
-
-  $(usersTable).on("click", "[name='showEditDialog']", function () {
-    var button = this;
-    return self.showEditDialog($(button).attr("data")).then(null, GuiConnector.alert);
-  });
-
-  return projectsRow;
-};
-
-/**
- *
- * @param {String} login
- * @returns {Promise}
- */
-UsersAdminPanel.prototype.showEditDialog = function (login) {
-  var self = this;
-  GuiConnector.showProcessing();
-  return self.getServerConnector().getUser(login).then(function (user) {
-    return self.getDialog(user);
-  }).then(function (dialog) {
-    dialog.open();
-    GuiConnector.hideProcessing();
-  }).then(null, function (error) {
-    GuiConnector.hideProcessing();
-    return Promise.reject(error);
-  });
-};
-
-/**
- *
- * @param {User} user
- * @returns {Promise}
- */
-UsersAdminPanel.prototype.getDialog = function (user) {
-  var self = this;
-  if (self._dialogs === undefined) {
-    self._dialogs = [];
-  }
-  var dialog = self._dialogs[user.getLogin()];
-  if (dialog === undefined) {
-    dialog = new EditUserDialog({
-      element: Functions.createElement({
-        type: "div"
-      }),
-      user: user,
-      customMap: null
-    });
-    self._dialogs[user.getLogin()] = dialog;
-    if (user.getLogin() === undefined) {
-      dialog.addListener("onSave", function () {
-        return self.onRefreshClicked();
-      });
-    }
-    return dialog.init().then(function () {
-      return dialog;
-    });
-  } else {
-    return Promise.resolve(dialog);
-  }
-};
-
-/**
- *
- * @returns {Promise}
- */
-UsersAdminPanel.prototype.init = function () {
-  var self = this;
-  return AbstractAdminPanel.prototype.init.call(this).then(function () {
-    return self.getServerConnector().getLoggedUser();
-  }).then(function (user) {
-    var privilege = self.getConfiguration().getPrivilegeType(PrivilegeType.USER_MANAGEMENT);
-    if (user.hasPrivilege(privilege)) {
-      return self.getServerConnector().getUsers().then(function (users) {
-        return self.setUsers(users);
-      });
-    } else {
-      self.disablePanel("You have no privilege to manage users");
-    }
-  });
-};
-
-/**
- *
- * @param {User[]} users
- */
-UsersAdminPanel.prototype.setUsers = function (users) {
-  var self = this;
-  var dataTable = $($("[name='usersTable']", self.getElement())[0]).DataTable();
-  var page = dataTable.page();
-  var data = [];
-  for (var i = 0; i < users.length; i++) {
-    var user = users[i];
-    var rowData = self.userToTableRow(user);
-    self.addUpdateListener(user, rowData);
-    data.push(rowData);
-  }
-  //it should be simplified, but I couldn't make it work
-  dataTable.clear().rows.add(data).page(page).draw(false).page(page).draw(false);
-};
-
-
-/**
- *
- * @param {User} user
- * @param {Array} dataTableRow
- */
-UsersAdminPanel.prototype.addUpdateListener = function (user, dataTableRow) {
-  var self = this;
-
-  var listenerName = "USER_LIST_LISTENER";
-  var listeners = user.getListeners("onreload");
-  for (var i = 0; i < listeners.length; i++) {
-    if (listeners[i].listenerName === listenerName) {
-      user.removeListener("onreload", listeners[i]);
-    }
-  }
-  var listener = function () {
-    var login = user.getLogin().replace(".", "\\.");
-    self.userToTableRow(user, dataTableRow);
-    var row = $($("[name='usersTable']", self.getElement())[0]).DataTable().row("#" + login);
-    if (row.length > 0) {
-      row.data(dataTableRow).draw();
-    }
-
-  };
-  listener.listenerName = listenerName;
-  user.addListener("onreload", listener);
-};
-
-/**
- *
- * @param {User} user
- * @param {Array} [row]
- * @returns {Array}
- */
-UsersAdminPanel.prototype.userToTableRow = function (user, row) {
-  if (row === undefined) {
-    row = [];
-  }
-
-  row[0] = user.getLogin();
-  row[1] = user.getName();
-  row[2] = user.getSurname();
-  row[3] = user.getEmail();
-  var ldapFieldId = 'ldap-auth-' + user.getLogin();
-  if (user.isConnectedToLdap()) {
-    row[4] = "<fieldset name='ldap-auth' id='" + ldapFieldId + "' data='" + user.getLogin() + "'> <input type='radio' name='" + ldapFieldId + "' value='LOCAL'> LOCAL <input type='radio' name='" + ldapFieldId + "' checked value='LDAP'> LDAP </fieldset>";
-  } else {
-    if (user.isLdapAccountAvailable()) {
-      row[4] = "<fieldset name='ldap-auth' id='" + ldapFieldId + "' data='" + user.getLogin() + "'> <input type='radio' name='" + ldapFieldId + "' value='LOCAL' checked> LOCAL <input type='radio' name='" + ldapFieldId + "' value='LDAP'> LDAP </fieldset>";
-      // row[4] = "LOCAL <button name='connectLdap' data='" + user.getLogin() + "'>CONNECT LDAP</button>"
-    } else {
-      row[4] = "<fieldset name='ldap-auth' id='" + ldapFieldId + "' data='" + user.getLogin() + "'> <input type='radio' name='" + ldapFieldId + "' value='LOCAL' checked> LOCAL</fieldset>";
-    }
-  }
-
-  row[5] = "<button name='showEditDialog' data='" + user.getLogin() + "'><i class='fa fa-edit' style='font-size:17px'></i></button>";
-  row[6] = "<button name='removeUser' data='" + user.getLogin() + "'><i class='fa fa-trash-o' style='font-size:17px'></i></button>";
-
-  return row;
-};
-
-/**
- *
- * @returns {Promise}
- */
-UsersAdminPanel.prototype.onRefreshClicked = function () {
-  var self = this;
-  return self.getServerConnector().getUsers(true).then(function (users) {
-    return self.setUsers(users);
-  });
-};
-
-
-/**
- *
- */
-UsersAdminPanel.prototype.destroy = function () {
-  var self = this;
-  var table = $("[name='usersTable']", self.getElement())[0];
-  if ($.fn.DataTable.isDataTable(table)) {
-    $(table).DataTable().destroy();
-  }
-
-  for (var key in self._dialogs) {
-    if (self._dialogs.hasOwnProperty(key)) {
-      self._dialogs[key].destroy();
-    }
-  }
-};
-
-/**
- *
- * @returns {Promise}
- */
-UsersAdminPanel.prototype.onAddClicked = function () {
-  var self = this;
-  var user = new User({});
-  GuiConnector.showProcessing();
-  return self.getDialog(user).then(function (dialog) {
-    dialog.open();
-    GuiConnector.hideProcessing();
-  }).then(null, function (error) {
-    GuiConnector.hideProcessing();
-    return Promise.reject(error);
-  });
-};
-
-/**
- *
- * @param {string} login
- * @returns {Promise}
- */
-UsersAdminPanel.prototype.removeUser = function (login) {
-  var self = this;
-  GuiConnector.showProcessing();
-  return self.getServerConnector().removeUser(login).then(function () {
-    return self.onRefreshClicked();
-  }).then(function () {
-    GuiConnector.hideProcessing();
-  }).then(null, function (error) {
-    GuiConnector.hideProcessing();
-    return Promise.reject(error);
-  });
-};
-
-module.exports = UsersAdminPanel;
+"use strict";
+
+var Promise = require('bluebird');
+
+var PrivilegeType = require('../../map/data/PrivilegeType');
+
+var AbstractAdminPanel = require('./AbstractAdminPanel');
+var EditUserDialog = require('./EditUserDialog');
+
+var User = require("../../map/data/User");
+
+var Functions = require('../../Functions');
+var GuiConnector = require('../../GuiConnector');
+// noinspection JSUnusedLocalSymbols
+var logger = require('../../logger');
+
+/**
+ *
+ * @param {Object} params
+ *
+ * @constructor
+ * @extends AbstractAdminPanel
+ */
+function UsersAdminPanel(params) {
+  var self = this;
+  AbstractAdminPanel.call(self, params);
+  self._createGui();
+  $(self.getElement()).addClass("minerva-users-tab");
+}
+
+UsersAdminPanel.prototype = Object.create(AbstractAdminPanel.prototype);
+UsersAdminPanel.prototype.constructor = UsersAdminPanel;
+
+/**
+ *
+ * @private
+ */
+UsersAdminPanel.prototype._createGui = function () {
+  var self = this;
+  var usersDiv = Functions.createElement({
+    type: "div"
+  });
+  self.getElement().appendChild(usersDiv);
+
+  var dataDiv = Functions.createElement({
+    type: "div",
+    style: "display:table; width:100%"
+  });
+  usersDiv.appendChild(dataDiv);
+
+  dataDiv.appendChild(self._createMenuRow());
+  dataDiv.appendChild(self._createUsersTableRow());
+  dataDiv.appendChild(self._createMenuRow());
+
+};
+
+/**
+ *
+ * @returns {HTMLElement}
+ * @private
+ */
+UsersAdminPanel.prototype._createMenuRow = function () {
+  var self = this;
+  var menuRow = Functions.createElement({
+    type: "div",
+    className: "minerva-menu-row",
+    style: "display:table-row; margin:10px"
+  });
+
+  var addUserButton = Functions.createElement({
+    type: "button",
+    name: "addProject",
+    content: '<span class="ui-icon ui-icon-circle-plus"></span>&nbsp;ADD USER',
+    onclick: function () {
+      return self.onAddClicked().then(null, GuiConnector.alert);
+    },
+    xss: false
+  });
+  var refreshButton = Functions.createElement({
+    type: "button",
+    name: "refreshProject",
+    content: '<span class="ui-icon ui-icon-refresh"></span>&nbsp;REFRESH',
+    onclick: function () {
+      return self.onRefreshClicked().then(null, GuiConnector.alert);
+    },
+    xss: false
+  });
+  menuRow.appendChild(addUserButton);
+  menuRow.appendChild(refreshButton);
+  return menuRow;
+};
+
+/**
+ *
+ * @returns {HTMLElement}
+ * @private
+ */
+UsersAdminPanel.prototype._createUsersTableRow = function () {
+  var self = this;
+  var projectsRow = Functions.createElement({
+    type: "div",
+    style: "display:table-row; width:100%"
+  });
+
+  var usersTable = Functions.createElement({
+    type: "table",
+    name: "usersTable",
+    className: "display",
+    style: "width:100%"
+  });
+  projectsRow.appendChild(usersTable);
+
+  // noinspection JSCheckFunctionSignatures
+  $(usersTable).DataTable({
+    fnRowCallback: function (nRow, aData) {
+      nRow.setAttribute('id', aData[0]);
+    },
+    columns: [{
+      title: 'Login'
+    }, {
+      title: 'Name'
+    }, {
+      title: 'Surname'
+    }, {
+      title: 'Email'
+    }, {
+      title: 'Authentication'
+    }, {
+      title: 'Edit'
+    }, {
+      title: 'Remove'
+    }]
+  });
+
+  self.bindUserGuiPreference({
+    jQueryObject: $(usersTable),
+    event: 'length.dt',
+    preferenceName: 'admin-users-datatable-length',
+    defaultValue: '10',
+    getter: function () {
+      return $(usersTable).DataTable().page.len() + '';
+    },
+    setter: function (value) {
+      return $(usersTable).DataTable().page.len(value).draw();
+    }
+  });
+
+  $(usersTable).on("click", "[name='removeUser']", function () {
+    var button = this;
+    return self.askConfirmRemoval({
+      title: "INFO",
+      content: "Do you really want to remove '" + $(button).attr("data") + "'user?",
+      input: false
+    }).then(function (param) {
+      if (param.status) {
+        return self.removeUser($(button).attr("data"))
+      }
+    }).catch(GuiConnector.alert);
+  });
+
+  $(usersTable).on("click", "[name='ldap-auth']", function () {
+    var field = this;
+    var login = $(this).attr('data');
+    GuiConnector.showProcessing();
+    return self.getServerConnector().getUser(login).then(function (user) {
+      var newIsConnected = $('input:checked', field).val() === "LDAP";
+      var isConnected = user.isConnectedToLdap();
+      if (isConnected !== newIsConnected) {
+        user.setConnectedToLdap(newIsConnected);
+        return self.getServerConnector().updateUser(user);
+      }
+    }).catch(function (error) {
+      GuiConnector.alert(error);
+    }).finally(function(){
+      GuiConnector.hideProcessing();
+    });
+  });
+
+  $(usersTable).on("click", "[name='showEditDialog']", function () {
+    var button = this;
+    return self.showEditDialog($(button).attr("data")).then(null, GuiConnector.alert);
+  });
+
+  return projectsRow;
+};
+
+/**
+ *
+ * @param {String} login
+ * @returns {Promise}
+ */
+UsersAdminPanel.prototype.showEditDialog = function (login) {
+  var self = this;
+  GuiConnector.showProcessing();
+  return self.getServerConnector().getUser(login).then(function (user) {
+    return self.getDialog(user);
+  }).then(function (dialog) {
+    dialog.open();
+    GuiConnector.hideProcessing();
+  }).then(null, function (error) {
+    GuiConnector.hideProcessing();
+    return Promise.reject(error);
+  });
+};
+
+/**
+ *
+ * @param {User} user
+ * @returns {Promise}
+ */
+UsersAdminPanel.prototype.getDialog = function (user) {
+  var self = this;
+  if (self._dialogs === undefined) {
+    self._dialogs = [];
+  }
+  var dialog = self._dialogs[user.getLogin()];
+  if (dialog === undefined) {
+    dialog = new EditUserDialog({
+      element: Functions.createElement({
+        type: "div"
+      }),
+      user: user,
+      customMap: null
+    });
+    self._dialogs[user.getLogin()] = dialog;
+    if (user.getLogin() === undefined) {
+      dialog.addListener("onSave", function () {
+        return self.onRefreshClicked();
+      });
+    }
+    return dialog.init().then(function () {
+      return dialog;
+    });
+  } else {
+    return Promise.resolve(dialog);
+  }
+};
+
+/**
+ *
+ * @returns {Promise}
+ */
+UsersAdminPanel.prototype.init = function () {
+  var self = this;
+  return AbstractAdminPanel.prototype.init.call(this).then(function () {
+    return self.getServerConnector().getLoggedUser();
+  }).then(function (user) {
+    var privilege = self.getConfiguration().getPrivilegeType(PrivilegeType.USER_MANAGEMENT);
+    if (user.hasPrivilege(privilege)) {
+      return self.getServerConnector().getUsers().then(function (users) {
+        return self.setUsers(users);
+      });
+    } else {
+      self.disablePanel("You have no privilege to manage users");
+    }
+  });
+};
+
+/**
+ *
+ * @param {User[]} users
+ */
+UsersAdminPanel.prototype.setUsers = function (users) {
+  var self = this;
+  var dataTable = $($("[name='usersTable']", self.getElement())[0]).DataTable();
+  var page = dataTable.page();
+  var data = [];
+  for (var i = 0; i < users.length; i++) {
+    var user = users[i];
+    var rowData = self.userToTableRow(user);
+    self.addUpdateListener(user, rowData);
+    data.push(rowData);
+  }
+  //it should be simplified, but I couldn't make it work
+  dataTable.clear().rows.add(data).page(page).draw(false).page(page).draw(false);
+};
+
+
+/**
+ *
+ * @param {User} user
+ * @param {Array} dataTableRow
+ */
+UsersAdminPanel.prototype.addUpdateListener = function (user, dataTableRow) {
+  var self = this;
+
+  var listenerName = "USER_LIST_LISTENER";
+  var listeners = user.getListeners("onreload");
+  for (var i = 0; i < listeners.length; i++) {
+    if (listeners[i].listenerName === listenerName) {
+      user.removeListener("onreload", listeners[i]);
+    }
+  }
+  var listener = function () {
+    var login = user.getLogin().replace(".", "\\.");
+    self.userToTableRow(user, dataTableRow);
+    var row = $($("[name='usersTable']", self.getElement())[0]).DataTable().row("#" + login);
+    if (row.length > 0) {
+      row.data(dataTableRow).draw();
+    }
+
+  };
+  listener.listenerName = listenerName;
+  user.addListener("onreload", listener);
+};
+
+/**
+ *
+ * @param {User} user
+ * @param {Array} [row]
+ * @returns {Array}
+ */
+UsersAdminPanel.prototype.userToTableRow = function (user, row) {
+  if (row === undefined) {
+    row = [];
+  }
+
+  row[0] = user.getLogin();
+  row[1] = user.getName();
+  row[2] = user.getSurname();
+  row[3] = user.getEmail();
+  var ldapFieldId = 'ldap-auth-' + user.getLogin();
+  if (user.isConnectedToLdap()) {
+    row[4] = "<fieldset name='ldap-auth' id='" + ldapFieldId + "' data='" + user.getLogin() + "'> <input type='radio' name='" + ldapFieldId + "' value='LOCAL'> LOCAL <input type='radio' name='" + ldapFieldId + "' checked value='LDAP'> LDAP </fieldset>";
+  } else {
+    if (user.isLdapAccountAvailable()) {
+      row[4] = "<fieldset name='ldap-auth' id='" + ldapFieldId + "' data='" + user.getLogin() + "'> <input type='radio' name='" + ldapFieldId + "' value='LOCAL' checked> LOCAL <input type='radio' name='" + ldapFieldId + "' value='LDAP'> LDAP </fieldset>";
+      // row[4] = "LOCAL <button name='connectLdap' data='" + user.getLogin() + "'>CONNECT LDAP</button>"
+    } else {
+      row[4] = "<fieldset name='ldap-auth' id='" + ldapFieldId + "' data='" + user.getLogin() + "'> <input type='radio' name='" + ldapFieldId + "' value='LOCAL' checked> LOCAL</fieldset>";
+    }
+  }
+
+  row[5] = "<button name='showEditDialog' data='" + user.getLogin() + "'><i class='fa fa-edit' style='font-size:17px'></i></button>";
+  row[6] = "<button name='removeUser' data='" + user.getLogin() + "'><i class='fa fa-trash-o' style='font-size:17px'></i></button>";
+
+  return row;
+};
+
+/**
+ *
+ * @returns {Promise}
+ */
+UsersAdminPanel.prototype.onRefreshClicked = function () {
+  var self = this;
+  return self.getServerConnector().getUsers(true).then(function (users) {
+    return self.setUsers(users);
+  });
+};
+
+
+/**
+ *
+ */
+UsersAdminPanel.prototype.destroy = function () {
+  var self = this;
+  var table = $("[name='usersTable']", self.getElement())[0];
+  if ($.fn.DataTable.isDataTable(table)) {
+    $(table).DataTable().destroy();
+  }
+
+  for (var key in self._dialogs) {
+    if (self._dialogs.hasOwnProperty(key)) {
+      self._dialogs[key].destroy();
+    }
+  }
+};
+
+/**
+ *
+ * @returns {Promise}
+ */
+UsersAdminPanel.prototype.onAddClicked = function () {
+  var self = this;
+  var user = new User({});
+  GuiConnector.showProcessing();
+  return self.getDialog(user).then(function (dialog) {
+    dialog.open();
+    GuiConnector.hideProcessing();
+  }).then(null, function (error) {
+    GuiConnector.hideProcessing();
+    return Promise.reject(error);
+  });
+};
+
+/**
+ *
+ * @param {string} login
+ * @returns {Promise}
+ */
+UsersAdminPanel.prototype.removeUser = function (login) {
+  var self = this;
+  GuiConnector.showProcessing();
+  return self.getServerConnector().removeUser(login).then(function () {
+    return self.onRefreshClicked();
+  }).then(function () {
+    GuiConnector.hideProcessing();
+  }).then(null, function (error) {
+    GuiConnector.hideProcessing();
+    return Promise.reject(error);
+  });
+};
+
+module.exports = UsersAdminPanel;
diff --git a/frontend-js/src/main/js/gui/admin/ZipEntry.js b/frontend-js/src/main/js/gui/admin/ZipEntry.js
index c3891a3a013e1b131353649c320471edd8671b7c..d774a223327fec74db0eb7ebedf9b6b8b7183cc5 100644
--- a/frontend-js/src/main/js/gui/admin/ZipEntry.js
+++ b/frontend-js/src/main/js/gui/admin/ZipEntry.js
@@ -1,37 +1,37 @@
-"use strict";
-
-var types = ["IMAGE", "OVERLAY", "MAP"];
-
-function ZipEntry(params) {
-  var self = this;
-  self.setType(params.type);
-  self.setFilename(params.filename);
-  self.setData(params.data);
-}
-
-ZipEntry.prototype.setType = function (type) {
-  if (types.indexOf(type) === -1) {
-    throw new Error("Unknown ZipEntryType: " + type + ".")
-  }
-  this._type = type;
-};
-ZipEntry.prototype.getType = function () {
-  return this._type;
-};
-
-ZipEntry.prototype.setFilename = function (filename) {
-  this._filename = filename;
-};
-
-ZipEntry.prototype.getFilename = function () {
-  return this._filename;
-};
-
-ZipEntry.prototype.setData = function (data) {
-  this._data = data;
-};
-ZipEntry.prototype.getData = function () {
-  return this._data;
-};
-
-module.exports = ZipEntry;
+"use strict";
+
+var types = ["IMAGE", "OVERLAY", "MAP"];
+
+function ZipEntry(params) {
+  var self = this;
+  self.setType(params.type);
+  self.setFilename(params.filename);
+  self.setData(params.data);
+}
+
+ZipEntry.prototype.setType = function (type) {
+  if (types.indexOf(type) === -1) {
+    throw new Error("Unknown ZipEntryType: " + type + ".")
+  }
+  this._type = type;
+};
+ZipEntry.prototype.getType = function () {
+  return this._type;
+};
+
+ZipEntry.prototype.setFilename = function (filename) {
+  this._filename = filename;
+};
+
+ZipEntry.prototype.getFilename = function () {
+  return this._filename;
+};
+
+ZipEntry.prototype.setData = function (data) {
+  this._data = data;
+};
+ZipEntry.prototype.getData = function () {
+  return this._data;
+};
+
+module.exports = ZipEntry;
diff --git a/frontend-js/src/main/js/gui/export/AbstractExportPanel.js b/frontend-js/src/main/js/gui/export/AbstractExportPanel.js
index d18f91310c421d3350a7b9e44e19123f6639fe51..b38d50a2c1329bda595a51ee73c1b9ac68f410f6 100644
--- a/frontend-js/src/main/js/gui/export/AbstractExportPanel.js
+++ b/frontend-js/src/main/js/gui/export/AbstractExportPanel.js
@@ -1,453 +1,453 @@
-"use strict";
-
-/* exported logger */
-
-var Panel = require('../Panel');
-
-var GuiConnector = require('../../GuiConnector');
-var logger = require('../../logger');
-var Functions = require('../../Functions');
-var DualListbox = require('dual-listbox').DualListbox;
-var Promise = require("bluebird");
-
-function AbstractExportPanel(params) {
-  params.scrollable = true;
-  Panel.call(this, params);
-
-}
-
-AbstractExportPanel.prototype = Object.create(Panel.prototype);
-AbstractExportPanel.prototype.constructor = AbstractExportPanel;
-
-AbstractExportPanel.prototype.init = function () {
-
-};
-
-function compareSimple(val1, val2) {
-  if (val1 < val2) {
-    return -1;
-  } else if (val1 > val2) {
-    return 1;
-  } else {
-    return 0;
-  }
-}
-
-AbstractExportPanel.prototype._createMiriamTypeDiv = function (annotations) {
-  var self = this;
-  var typeDiv = Functions.createElement({
-    type: "div",
-    name: "miriamSelectDiv",
-    className: "minerva-export-dual-listbox-container"
-  });
-  typeDiv.appendChild(Functions.createElement({
-    type: "h4",
-    content: " Annotations:"
-  }));
-
-  var selectElement = Functions.createElement({
-    type: "select",
-    className: "minerva-multi-select"
-  });
-  typeDiv.appendChild(selectElement);
-
-  function compare(entry1, entry2) {
-    if ((entry1.count === 0 && entry2.count === 0) || (entry1.count !== 0 && entry2.count !== 0)) {
-      return compareSimple(entry1.miriamType.getCommonName(), entry2.miriamType.getCommonName());
-    } else {
-      return compareSimple(-entry1.count, -entry2.count);
-    }
-  }
-
-  annotations.sort(compare);
-
-  for (var i = 0; i < annotations.length; i++) {
-    var miriamType = annotations[i].miriamType;
-    var count = annotations[i].count;
-
-    var option = new Option();
-    option.value = miriamType.getName();
-    if (count > 0) {
-      option.innerHTML = "<div class='minerva-multi-select-special'>" + miriamType.getCommonName() + " (" + count
-        + ")</div>";
-    } else {
-      option.innerHTML = "<div >" + miriamType.getCommonName() + "</div>";
-    }
-    selectElement.appendChild(option);
-  }
-
-  self.setMiriamTypesDualListbox(self.createDualListbox(selectElement));
-  return typeDiv;
-};
-
-AbstractExportPanel.prototype.createDualListbox = function (selectElement) {
-  return new DualListbox(selectElement, {
-    availableTitle: 'Available',
-    selectedTitle: 'Used',
-    addButtonText: '>',
-    removeButtonText: '<',
-    addAllButtonText: '>>',
-    removeAllButtonText: '<<'
-  });
-};
-
-AbstractExportPanel.prototype._createSelectTypeDiv = function (elementTypes) {
-  var typeDiv = Functions.createElement({
-    type: "div",
-    name: "typeSelectDiv"
-  });
-  typeDiv.appendChild(Functions.createElement({
-    type: "h4",
-    content: " TYPE:"
-  }));
-  var choicesContainer = Functions.createElement({
-    type: "ul",
-    className: "minerva-checkbox-grid"
-  });
-  typeDiv.appendChild(choicesContainer);
-  var i;
-  var toBeExcluded = [];
-  for (i = 0; i < elementTypes.length; i++) {
-    toBeExcluded[elementTypes[i].parentClass] = true;
-  }
-  var processedNames = [];
-  for (i = 0; i < elementTypes.length; i++) {
-    var elementType = elementTypes[i];
-    var name = elementType.name;
-    if (processedNames[name] === undefined && toBeExcluded[elementType.className] === undefined) {
-      processedNames[name] = true;
-      var row = Functions.createElement({
-        type: "li",
-        content: "<div class=\"checkbox\"><label> <input type=\"checkbox\" name=\"" + name + "\" value=\"" + name + "\" />" + name + "</label></div>",
-        xss: false
-      });
-      choicesContainer.appendChild(row);
-    }
-  }
-  choicesContainer.appendChild(Functions.createElement({
-    type: "li",
-    content: "<div class=\"checkbox\"><label> <input type=\"checkbox\" name=\"ALL\" value=\"ALL\" />ALL</label></div>",
-    xss: false
-  }));
-  return typeDiv;
-};
-
-AbstractExportPanel.prototype.getSelectedTypes = function () {
-  var self = this;
-
-  var div = $("div[name='typeSelectDiv']", $(self.getElement()))[0];
-  var result = [];
-  var selectedAll = false;
-  $(":checked", $(div)).each(function (index, element) {
-    if (element.value === "ALL") {
-      selectedAll = true;
-    }
-    result.push(element.value);
-  });
-  if (selectedAll) {
-    return ServerConnector.getConfiguration().then(function (configuration) {
-      return configuration.getSimpleElementTypeNames();
-    });
-  }
-
-  return Promise.resolve(result);
-};
-
-AbstractExportPanel.prototype.setMiriamTypesDualListbox = function (dualListbox) {
-  this._miriamTypesDualListbox = dualListbox;
-};
-AbstractExportPanel.prototype.getMiriamTypesDualListbox = function () {
-  return this._miriamTypesDualListbox;
-};
-
-AbstractExportPanel.prototype._createSelectColumnDiv = function (columnTypes) {
-  var columnDiv = Functions.createElement({
-    type: "div",
-    name: "columnSelectDiv"
-  });
-  columnDiv.appendChild(Functions.createElement({
-    type: "h4",
-    content: " COLUMN:"
-  }));
-  var choicesContainer = Functions.createElement({
-    type: "ul",
-    className: "minerva-checkbox-grid"
-  });
-
-  columnDiv.appendChild(choicesContainer);
-  for (var i = 0; i < columnTypes.length; i++) {
-    var columnType = columnTypes[i];
-    var row = Functions.createElement({
-      type: "li",
-      content: "<div class=\"checkbox\"><label> <input type=\"checkbox\" name=\"column_" + columnType.columnName
-      + "\" value=\"" + columnType.columnName + "\" />" + columnType.name + "</label></div>",
-      xss: false
-    });
-    choicesContainer.appendChild(row);
-  }
-  choicesContainer.appendChild(Functions.createElement({
-    type: "li",
-    content: "<div class=\"checkbox\"><label> <input type=\"checkbox\" name=\"ALL\" value=\"ALL\" />ALL</label></div>",
-    xss: false
-  }));
-  return columnDiv;
-};
-
-AbstractExportPanel.prototype.getSelectedMiriamTypes = function () {
-  var self = this;
-  return ServerConnector.getConfiguration().then(function (configuration) {
-    var selected = self.getMiriamTypesDualListbox().selected;
-    var result = [];
-    for (var i = 0; i < selected.length; i++) {
-      var miriamType = configuration.getMiriamTypeByName(selected[i].dataset.id);
-      result.push(miriamType);
-    }
-    return result;
-  });
-};
-
-AbstractExportPanel.prototype.getSelectedColumns = function () {
-  var self = this;
-
-  var div = $("div[name='columnSelectDiv']", $(self.getElement()))[0];
-  var selectedColumnMap = [];
-  var selectedAll = false;
-  $(":checked", $(div)).each(function (index, element) {
-    if (element.value === "ALL") {
-      selectedAll = true;
-    }
-    selectedColumnMap[element.value] = true;
-  });
-  var columnTypes = self.getAllColumns();
-
-  if (selectedAll) {
-    return Promise.resolve(columnTypes);
-  }
-
-  var result = [];
-
-  for (var i = 0; i < columnTypes.length; i++) {
-    var columnType = columnTypes[i];
-    if (selectedColumnMap[columnType.columnName] === true) {
-      result.push(columnType);
-    }
-  }
-  return Promise.resolve(result);
-};
-
-AbstractExportPanel.prototype._getCompartmentNames = function () {
-  var self = this;
-  var compartments = [];
-  return self._getAllCompartments().then(function (result) {
-
-    var addedNames = [];
-    for (var i = 0; i < result.length; i++) {
-      if (addedNames[result[i].getName()] === undefined) {
-        compartments.push(result[i].getName());
-        addedNames[result[i].getName()] = true;
-      }
-    }
-    compartments.sort(compareSimple);
-    return compartments;
-  });
-};
-
-AbstractExportPanel.prototype.getModels = function () {
-  return this.getProject().getModels();
-};
-
-AbstractExportPanel.prototype._getAllCompartments = function () {
-  var self = this;
-  var compartments = [];
-
-  var models = self.getModels();
-
-  var promises = [];
-  for (var i = 0; i < models.length; i++) {
-    promises.push(models[i].getCompartments());
-  }
-
-  return Promise.all(promises).then(function (result) {
-    for (var i = 0; i < result.length; i++) {
-      var modelCompartments = result[i];
-      for (var j = 0; j < modelCompartments.length; j++) {
-        compartments.push(modelCompartments[j]);
-      }
-    }
-    return compartments;
-  });
-};
-
-AbstractExportPanel.prototype._createDownloadButton = function () {
-  var self = this;
-  var downloadDiv = Functions.createElement({
-    type: "div",
-    name: "downloadDiv",
-    style: "clear:both; padding: 10px;"
-  });
-  var button = Functions.createElement({
-    type: "button",
-    name: "downloadButton",
-    content: " Download",
-    onclick: function () {
-      GuiConnector.showProcessing();
-      return self.createResponseString().then(function (result) {
-        var blob = new Blob([result], {
-          type: "text/plain;charset=utf-8"
-        });
-        var FileSaver = require("file-saver");
-        return FileSaver.saveAs(blob, self.getSaveFilename());
-      }).then(function () {
-        GuiConnector.hideProcessing();
-      }, function (error) {
-        GuiConnector.hideProcessing();
-        GuiConnector.alert(error);
-      });
-    }
-  });
-  downloadDiv.appendChild(button);
-
-  return downloadDiv;
-};
-
-AbstractExportPanel.prototype.getSaveFilename = function () {
-  var self = this;
-  return self.getProject().getProjectId() + "-" + self.getPanelName() + ".txt";
-};
-
-AbstractExportPanel.prototype._createSelectIncludedCompartmentDiv = function () {
-  var self = this;
-  var typeDiv = Functions.createElement({
-    type: "div",
-    name: "includedCompartmentSelectDiv",
-    className: "minerva-export-dual-listbox-container"
-  });
-  typeDiv.appendChild(Functions.createElement({
-    type: "h4",
-    content: " Included compartment/pathways:"
-  }));
-
-  return self._getCompartmentNames().then(function (compartmentNames) {
-
-    var selectElement = Functions.createElement({
-      type: "select",
-      className: "minerva-multi-select"
-    });
-    typeDiv.appendChild(selectElement);
-
-    for (var i = 0; i < compartmentNames.length; i++) {
-      var name = compartmentNames[i];
-
-      var option = new Option();
-      option.value = name;
-      option.innerHTML = "<div >" + name + "</div>";
-      selectElement.appendChild(option);
-    }
-    self.setIncludedCompartmentsDualListbox(self.createDualListbox(selectElement));
-    return typeDiv;
-  });
-};
-
-AbstractExportPanel.prototype._createSelectExcludedCompartmentDiv = function () {
-  var self = this;
-  var typeDiv = Functions.createElement({
-    type: "div",
-    name: "excludedCompartmentSelectDiv",
-    className: "minerva-export-dual-listbox-container"
-  });
-  typeDiv.appendChild(Functions.createElement({
-    type: "h4",
-    content: " Excluded compartment/pathways:"
-  }));
-
-  return self._getCompartmentNames().then(function (compartmentNames) {
-
-    var selectElement = Functions.createElement({
-      type: "select",
-      className: "minerva-multi-select"
-    });
-    typeDiv.appendChild(selectElement);
-
-    for (var i = 0; i < compartmentNames.length; i++) {
-      var name = compartmentNames[i];
-
-      var option = new Option();
-      option.value = name;
-      option.innerHTML = "<div >" + name + "</div>";
-      selectElement.appendChild(option);
-    }
-    self.setExcludedCompartmentsDualListbox(self.createDualListbox(selectElement));
-    return typeDiv;
-  });
-};
-
-AbstractExportPanel.prototype.setIncludedCompartmentsDualListbox = function (dualListbox) {
-  this._includedCompartmentsDualListbox = dualListbox;
-};
-AbstractExportPanel.prototype.getIncludedCompartmentsDualListbox = function () {
-  return this._includedCompartmentsDualListbox;
-};
-
-AbstractExportPanel.prototype.getSelectedIncludedCompartments = function () {
-  var self = this;
-  var list = self.getIncludedCompartmentsDualListbox().selected;
-  var names = [];
-  var result = [];
-  for (var i = 0; i < list.length; i++) {
-    var element = list[i];
-    names[element.dataset.id] = true;
-  }
-  return self._getAllCompartments().then(function (compartments) {
-    for (var i = 0; i < compartments.length; i++) {
-      var compartment = compartments[i];
-      if (names[compartment.getName()]) {
-        result.push(compartment);
-      }
-    }
-    return result;
-  });
-};
-
-AbstractExportPanel.prototype.setExcludedCompartmentsDualListbox = function (dualListbox) {
-  this._excludedCompartmentsDualListbox = dualListbox;
-};
-AbstractExportPanel.prototype.getExcludedCompartmentsDualListbox = function () {
-  return this._excludedCompartmentsDualListbox;
-};
-
-AbstractExportPanel.prototype.getSelectedExcludedCompartments = function () {
-  var self = this;
-  var list = self.getExcludedCompartmentsDualListbox().selected;
-  var names = [];
-  var result = [];
-  for (var i = 0; i < list.length; i++) {
-    var element = list[i];
-    names[element.dataset.id] = true;
-  }
-  return self._getAllCompartments().then(function (compartments) {
-    for (var i = 0; i < compartments.length; i++) {
-      var compartment = compartments[i];
-      if (names[compartment.getName()]) {
-        result.push(compartment);
-      }
-    }
-    return result;
-  });
-};
-
-AbstractExportPanel.prototype.createResponseHeader = function (columns, miriamTypes) {
-  var stringBuilder = [];
-  var i;
-  for (i = 0; i < columns.length; i++) {
-    var column = columns[i];
-    stringBuilder.push(column.name);
-  }
-  for (i = 0; i < miriamTypes.length; i++) {
-    var miriamType = miriamTypes[i];
-    stringBuilder.push(miriamType.getCommonName());
-  }
-  return stringBuilder.join("\t");
-
-};
-
-module.exports = AbstractExportPanel;
+"use strict";
+
+/* exported logger */
+
+var Panel = require('../Panel');
+
+var GuiConnector = require('../../GuiConnector');
+var logger = require('../../logger');
+var Functions = require('../../Functions');
+var DualListbox = require('dual-listbox').DualListbox;
+var Promise = require("bluebird");
+
+function AbstractExportPanel(params) {
+  params.scrollable = true;
+  Panel.call(this, params);
+
+}
+
+AbstractExportPanel.prototype = Object.create(Panel.prototype);
+AbstractExportPanel.prototype.constructor = AbstractExportPanel;
+
+AbstractExportPanel.prototype.init = function () {
+
+};
+
+function compareSimple(val1, val2) {
+  if (val1 < val2) {
+    return -1;
+  } else if (val1 > val2) {
+    return 1;
+  } else {
+    return 0;
+  }
+}
+
+AbstractExportPanel.prototype._createMiriamTypeDiv = function (annotations) {
+  var self = this;
+  var typeDiv = Functions.createElement({
+    type: "div",
+    name: "miriamSelectDiv",
+    className: "minerva-export-dual-listbox-container"
+  });
+  typeDiv.appendChild(Functions.createElement({
+    type: "h4",
+    content: " Annotations:"
+  }));
+
+  var selectElement = Functions.createElement({
+    type: "select",
+    className: "minerva-multi-select"
+  });
+  typeDiv.appendChild(selectElement);
+
+  function compare(entry1, entry2) {
+    if ((entry1.count === 0 && entry2.count === 0) || (entry1.count !== 0 && entry2.count !== 0)) {
+      return compareSimple(entry1.miriamType.getCommonName(), entry2.miriamType.getCommonName());
+    } else {
+      return compareSimple(-entry1.count, -entry2.count);
+    }
+  }
+
+  annotations.sort(compare);
+
+  for (var i = 0; i < annotations.length; i++) {
+    var miriamType = annotations[i].miriamType;
+    var count = annotations[i].count;
+
+    var option = new Option();
+    option.value = miriamType.getName();
+    if (count > 0) {
+      option.innerHTML = "<div class='minerva-multi-select-special'>" + miriamType.getCommonName() + " (" + count
+        + ")</div>";
+    } else {
+      option.innerHTML = "<div >" + miriamType.getCommonName() + "</div>";
+    }
+    selectElement.appendChild(option);
+  }
+
+  self.setMiriamTypesDualListbox(self.createDualListbox(selectElement));
+  return typeDiv;
+};
+
+AbstractExportPanel.prototype.createDualListbox = function (selectElement) {
+  return new DualListbox(selectElement, {
+    availableTitle: 'Available',
+    selectedTitle: 'Used',
+    addButtonText: '>',
+    removeButtonText: '<',
+    addAllButtonText: '>>',
+    removeAllButtonText: '<<'
+  });
+};
+
+AbstractExportPanel.prototype._createSelectTypeDiv = function (elementTypes) {
+  var typeDiv = Functions.createElement({
+    type: "div",
+    name: "typeSelectDiv"
+  });
+  typeDiv.appendChild(Functions.createElement({
+    type: "h4",
+    content: " TYPE:"
+  }));
+  var choicesContainer = Functions.createElement({
+    type: "ul",
+    className: "minerva-checkbox-grid"
+  });
+  typeDiv.appendChild(choicesContainer);
+  var i;
+  var toBeExcluded = [];
+  for (i = 0; i < elementTypes.length; i++) {
+    toBeExcluded[elementTypes[i].parentClass] = true;
+  }
+  var processedNames = [];
+  for (i = 0; i < elementTypes.length; i++) {
+    var elementType = elementTypes[i];
+    var name = elementType.name;
+    if (processedNames[name] === undefined && toBeExcluded[elementType.className] === undefined) {
+      processedNames[name] = true;
+      var row = Functions.createElement({
+        type: "li",
+        content: "<div class=\"checkbox\"><label> <input type=\"checkbox\" name=\"" + name + "\" value=\"" + name + "\" />" + name + "</label></div>",
+        xss: false
+      });
+      choicesContainer.appendChild(row);
+    }
+  }
+  choicesContainer.appendChild(Functions.createElement({
+    type: "li",
+    content: "<div class=\"checkbox\"><label> <input type=\"checkbox\" name=\"ALL\" value=\"ALL\" />ALL</label></div>",
+    xss: false
+  }));
+  return typeDiv;
+};
+
+AbstractExportPanel.prototype.getSelectedTypes = function () {
+  var self = this;
+
+  var div = $("div[name='typeSelectDiv']", $(self.getElement()))[0];
+  var result = [];
+  var selectedAll = false;
+  $(":checked", $(div)).each(function (index, element) {
+    if (element.value === "ALL") {
+      selectedAll = true;
+    }
+    result.push(element.value);
+  });
+  if (selectedAll) {
+    return ServerConnector.getConfiguration().then(function (configuration) {
+      return configuration.getSimpleElementTypeNames();
+    });
+  }
+
+  return Promise.resolve(result);
+};
+
+AbstractExportPanel.prototype.setMiriamTypesDualListbox = function (dualListbox) {
+  this._miriamTypesDualListbox = dualListbox;
+};
+AbstractExportPanel.prototype.getMiriamTypesDualListbox = function () {
+  return this._miriamTypesDualListbox;
+};
+
+AbstractExportPanel.prototype._createSelectColumnDiv = function (columnTypes) {
+  var columnDiv = Functions.createElement({
+    type: "div",
+    name: "columnSelectDiv"
+  });
+  columnDiv.appendChild(Functions.createElement({
+    type: "h4",
+    content: " COLUMN:"
+  }));
+  var choicesContainer = Functions.createElement({
+    type: "ul",
+    className: "minerva-checkbox-grid"
+  });
+
+  columnDiv.appendChild(choicesContainer);
+  for (var i = 0; i < columnTypes.length; i++) {
+    var columnType = columnTypes[i];
+    var row = Functions.createElement({
+      type: "li",
+      content: "<div class=\"checkbox\"><label> <input type=\"checkbox\" name=\"column_" + columnType.columnName
+      + "\" value=\"" + columnType.columnName + "\" />" + columnType.name + "</label></div>",
+      xss: false
+    });
+    choicesContainer.appendChild(row);
+  }
+  choicesContainer.appendChild(Functions.createElement({
+    type: "li",
+    content: "<div class=\"checkbox\"><label> <input type=\"checkbox\" name=\"ALL\" value=\"ALL\" />ALL</label></div>",
+    xss: false
+  }));
+  return columnDiv;
+};
+
+AbstractExportPanel.prototype.getSelectedMiriamTypes = function () {
+  var self = this;
+  return ServerConnector.getConfiguration().then(function (configuration) {
+    var selected = self.getMiriamTypesDualListbox().selected;
+    var result = [];
+    for (var i = 0; i < selected.length; i++) {
+      var miriamType = configuration.getMiriamTypeByName(selected[i].dataset.id);
+      result.push(miriamType);
+    }
+    return result;
+  });
+};
+
+AbstractExportPanel.prototype.getSelectedColumns = function () {
+  var self = this;
+
+  var div = $("div[name='columnSelectDiv']", $(self.getElement()))[0];
+  var selectedColumnMap = [];
+  var selectedAll = false;
+  $(":checked", $(div)).each(function (index, element) {
+    if (element.value === "ALL") {
+      selectedAll = true;
+    }
+    selectedColumnMap[element.value] = true;
+  });
+  var columnTypes = self.getAllColumns();
+
+  if (selectedAll) {
+    return Promise.resolve(columnTypes);
+  }
+
+  var result = [];
+
+  for (var i = 0; i < columnTypes.length; i++) {
+    var columnType = columnTypes[i];
+    if (selectedColumnMap[columnType.columnName] === true) {
+      result.push(columnType);
+    }
+  }
+  return Promise.resolve(result);
+};
+
+AbstractExportPanel.prototype._getCompartmentNames = function () {
+  var self = this;
+  var compartments = [];
+  return self._getAllCompartments().then(function (result) {
+
+    var addedNames = [];
+    for (var i = 0; i < result.length; i++) {
+      if (addedNames[result[i].getName()] === undefined) {
+        compartments.push(result[i].getName());
+        addedNames[result[i].getName()] = true;
+      }
+    }
+    compartments.sort(compareSimple);
+    return compartments;
+  });
+};
+
+AbstractExportPanel.prototype.getModels = function () {
+  return this.getProject().getModels();
+};
+
+AbstractExportPanel.prototype._getAllCompartments = function () {
+  var self = this;
+  var compartments = [];
+
+  var models = self.getModels();
+
+  var promises = [];
+  for (var i = 0; i < models.length; i++) {
+    promises.push(models[i].getCompartments());
+  }
+
+  return Promise.all(promises).then(function (result) {
+    for (var i = 0; i < result.length; i++) {
+      var modelCompartments = result[i];
+      for (var j = 0; j < modelCompartments.length; j++) {
+        compartments.push(modelCompartments[j]);
+      }
+    }
+    return compartments;
+  });
+};
+
+AbstractExportPanel.prototype._createDownloadButton = function () {
+  var self = this;
+  var downloadDiv = Functions.createElement({
+    type: "div",
+    name: "downloadDiv",
+    style: "clear:both; padding: 10px;"
+  });
+  var button = Functions.createElement({
+    type: "button",
+    name: "downloadButton",
+    content: " Download",
+    onclick: function () {
+      GuiConnector.showProcessing();
+      return self.createResponseString().then(function (result) {
+        var blob = new Blob([result], {
+          type: "text/plain;charset=utf-8"
+        });
+        var FileSaver = require("file-saver");
+        return FileSaver.saveAs(blob, self.getSaveFilename());
+      }).then(function () {
+        GuiConnector.hideProcessing();
+      }, function (error) {
+        GuiConnector.hideProcessing();
+        GuiConnector.alert(error);
+      });
+    }
+  });
+  downloadDiv.appendChild(button);
+
+  return downloadDiv;
+};
+
+AbstractExportPanel.prototype.getSaveFilename = function () {
+  var self = this;
+  return self.getProject().getProjectId() + "-" + self.getPanelName() + ".txt";
+};
+
+AbstractExportPanel.prototype._createSelectIncludedCompartmentDiv = function () {
+  var self = this;
+  var typeDiv = Functions.createElement({
+    type: "div",
+    name: "includedCompartmentSelectDiv",
+    className: "minerva-export-dual-listbox-container"
+  });
+  typeDiv.appendChild(Functions.createElement({
+    type: "h4",
+    content: " Included compartment/pathways:"
+  }));
+
+  return self._getCompartmentNames().then(function (compartmentNames) {
+
+    var selectElement = Functions.createElement({
+      type: "select",
+      className: "minerva-multi-select"
+    });
+    typeDiv.appendChild(selectElement);
+
+    for (var i = 0; i < compartmentNames.length; i++) {
+      var name = compartmentNames[i];
+
+      var option = new Option();
+      option.value = name;
+      option.innerHTML = "<div >" + name + "</div>";
+      selectElement.appendChild(option);
+    }
+    self.setIncludedCompartmentsDualListbox(self.createDualListbox(selectElement));
+    return typeDiv;
+  });
+};
+
+AbstractExportPanel.prototype._createSelectExcludedCompartmentDiv = function () {
+  var self = this;
+  var typeDiv = Functions.createElement({
+    type: "div",
+    name: "excludedCompartmentSelectDiv",
+    className: "minerva-export-dual-listbox-container"
+  });
+  typeDiv.appendChild(Functions.createElement({
+    type: "h4",
+    content: " Excluded compartment/pathways:"
+  }));
+
+  return self._getCompartmentNames().then(function (compartmentNames) {
+
+    var selectElement = Functions.createElement({
+      type: "select",
+      className: "minerva-multi-select"
+    });
+    typeDiv.appendChild(selectElement);
+
+    for (var i = 0; i < compartmentNames.length; i++) {
+      var name = compartmentNames[i];
+
+      var option = new Option();
+      option.value = name;
+      option.innerHTML = "<div >" + name + "</div>";
+      selectElement.appendChild(option);
+    }
+    self.setExcludedCompartmentsDualListbox(self.createDualListbox(selectElement));
+    return typeDiv;
+  });
+};
+
+AbstractExportPanel.prototype.setIncludedCompartmentsDualListbox = function (dualListbox) {
+  this._includedCompartmentsDualListbox = dualListbox;
+};
+AbstractExportPanel.prototype.getIncludedCompartmentsDualListbox = function () {
+  return this._includedCompartmentsDualListbox;
+};
+
+AbstractExportPanel.prototype.getSelectedIncludedCompartments = function () {
+  var self = this;
+  var list = self.getIncludedCompartmentsDualListbox().selected;
+  var names = [];
+  var result = [];
+  for (var i = 0; i < list.length; i++) {
+    var element = list[i];
+    names[element.dataset.id] = true;
+  }
+  return self._getAllCompartments().then(function (compartments) {
+    for (var i = 0; i < compartments.length; i++) {
+      var compartment = compartments[i];
+      if (names[compartment.getName()]) {
+        result.push(compartment);
+      }
+    }
+    return result;
+  });
+};
+
+AbstractExportPanel.prototype.setExcludedCompartmentsDualListbox = function (dualListbox) {
+  this._excludedCompartmentsDualListbox = dualListbox;
+};
+AbstractExportPanel.prototype.getExcludedCompartmentsDualListbox = function () {
+  return this._excludedCompartmentsDualListbox;
+};
+
+AbstractExportPanel.prototype.getSelectedExcludedCompartments = function () {
+  var self = this;
+  var list = self.getExcludedCompartmentsDualListbox().selected;
+  var names = [];
+  var result = [];
+  for (var i = 0; i < list.length; i++) {
+    var element = list[i];
+    names[element.dataset.id] = true;
+  }
+  return self._getAllCompartments().then(function (compartments) {
+    for (var i = 0; i < compartments.length; i++) {
+      var compartment = compartments[i];
+      if (names[compartment.getName()]) {
+        result.push(compartment);
+      }
+    }
+    return result;
+  });
+};
+
+AbstractExportPanel.prototype.createResponseHeader = function (columns, miriamTypes) {
+  var stringBuilder = [];
+  var i;
+  for (i = 0; i < columns.length; i++) {
+    var column = columns[i];
+    stringBuilder.push(column.name);
+  }
+  for (i = 0; i < miriamTypes.length; i++) {
+    var miriamType = miriamTypes[i];
+    stringBuilder.push(miriamType.getCommonName());
+  }
+  return stringBuilder.join("\t");
+
+};
+
+module.exports = AbstractExportPanel;
diff --git a/frontend-js/src/main/js/gui/export/ElementExportPanel.js b/frontend-js/src/main/js/gui/export/ElementExportPanel.js
index 2d0c3028e9ba97c227f248d7ab5ee0ee3f58d0b6..5b1b0ae483623095bea32f795bee918fc822d26c 100644
--- a/frontend-js/src/main/js/gui/export/ElementExportPanel.js
+++ b/frontend-js/src/main/js/gui/export/ElementExportPanel.js
@@ -1,215 +1,215 @@
-"use strict";
-
-/* exported logger */
-
-var AbstractExportPanel = require('./AbstractExportPanel');
-var GuiMessageError = require('../GuiMessageError');
-
-var logger = require('../../logger');
-
-var Promise = require("bluebird");
-
-function ElementExportPanel(params) {
-  params.panelName = "elementExport";
-  AbstractExportPanel.call(this, params);
-}
-
-ElementExportPanel.prototype = Object.create(AbstractExportPanel.prototype);
-ElementExportPanel.prototype.constructor = ElementExportPanel;
-
-ElementExportPanel.prototype.init = function () {
-  var self = this;
-  var element = self.getElement();
-  var configuration;
-  return ServerConnector.getConfiguration().then(function (result) {
-    configuration = result;
-    var typeDiv = self._createSelectTypeDiv(configuration.getElementTypes());
-    element.appendChild(typeDiv);
-    element.appendChild(self._createSelectColumnDiv(self.getAllColumns()));
-    return ServerConnector.getProjectStatistics(self.getProject().getProjectId());
-  }).then(function (statistics) {
-    return self._createMiriamTypeDiv(statistics.getElementAnnotations());
-  }).then(function (div) {
-    element.appendChild(div);
-    return self._createSelectIncludedCompartmentDiv();
-  }).then(function (div) {
-    element.appendChild(div);
-    return self._createSelectExcludedCompartmentDiv();
-  }).then(function (div) {
-    element.appendChild(div);
-    element.appendChild(self._createDownloadButton());
-  }).then(function () {
-    $(window).trigger('resize');
-  });
-};
-
-ElementExportPanel.prototype.createResponseString = function () {
-  var self = this;
-  var types, miriamTypes;
-  var includedCompartmentIds = [];
-  var excludedCompartmentIds = [];
-  var models = self.getProject().getModels();
-
-  var elements = [];
-  return self.getSelectedTypes().then(function (result) {
-    if (result.length === 0) {
-      return Promise.reject(new GuiMessageError("You must select at least one type"));
-    }
-    types = result;
-    return self.getSelectedIncludedCompartments();
-  }).then(function (result) {
-    result.forEach(function (compartment) {
-      includedCompartmentIds.push(compartment.getId());
-    });
-    return self.getSelectedExcludedCompartments();
-  }).then(function (result) {
-    result.forEach(function (compartment) {
-      excludedCompartmentIds.push(compartment.getId());
-    });
-
-    var promises = [];
-    for (var i = 0; i < models.length; i++) {
-      promises.push(models[i].getAliases({
-        type: types,
-        complete: true,
-        includedCompartmentIds: includedCompartmentIds,
-        excludedCompartmentIds: excludedCompartmentIds
-      }));
-    }
-    return Promise.all(promises);
-  }).then(function (aliasesByModel) {
-    for (var i = 0; i < aliasesByModel.length; i++) {
-      for (var j = 0; j < aliasesByModel[i].length; j++) {
-        elements.push(aliasesByModel[i][j]);
-      }
-    }
-
-    return self.getSelectedMiriamTypes();
-  }).then(function (result) {
-    miriamTypes = result;
-    return self.getSelectedColumns();
-  }).then(function (selectedColumns) {
-    if (selectedColumns.length === 0) {
-      return Promise.reject(new GuiMessageError("You must select at least one column"));
-    }
-
-    var rows = [];
-    rows.push(self.createResponseHeader(selectedColumns, miriamTypes));
-    for (var i = 0; i < elements.length; i++) {
-      rows.push(self.createResponseRow(elements[i], selectedColumns, miriamTypes));
-    }
-    return rows.join("\n");
-  });
-};
-
-ElementExportPanel.prototype.createResponseRow = function (alias, columns, miriamTypes) {
-  var stringBuilder = [];
-  var i, value;
-  for (i = 0; i < columns.length; i++) {
-    var column = columns[i];
-    value = alias[column.method]();
-    if (column.formatFunction !== undefined) {
-      value = column.formatFunction(value);
-    }
-    if (value instanceof String || typeof value === "string") {
-      value = value.replace(/[\n\r]/g, ' ');
-    }
-    stringBuilder.push(value);
-  }
-  for (i = 0; i < miriamTypes.length; i++) {
-    value = "";
-    var miriamType = miriamTypes[i];
-    var references = alias.getReferences();
-    for (var j = 0; j < references.length; j++) {
-      var reference = references[j];
-      if (reference.getType() === miriamType.getName()) {
-        value += reference.getResource() + ",";
-      }
-    }
-    stringBuilder.push(value);
-  }
-  return stringBuilder.join("\t");
-};
-
-ElementExportPanel.prototype.getAllColumns = function () {
-  return [{
-    "columnName": "id",
-    "method": "getId",
-    "name": "Id"
-  }, {
-    "columnName": "name",
-    "method": "getName",
-    "name": "Name"
-  }, {
-    "columnName": "description",
-    "method": "getDescription",
-    "name": "Description"
-  }, {
-    "columnName": "modelId",
-    "method": "getModelId",
-    "name": "Model"
-  }, {
-    "columnName": "type",
-    "method": "getType",
-    "name": "Type"
-  }, {
-    "columnName": "complexId",
-    "method": "getComplexId",
-    "name": "Complex"
-  }, {
-    "columnName": "compartmentId",
-    "method": "getCompartmentId",
-    "name": "Compartment"
-  }, {
-    "columnName": "charge",
-    "method": "getCharge",
-    "name": "Charge"
-  }, {
-    "columnName": "symbol",
-    "method": "getSymbol",
-    "name": "Symbol"
-  }, {
-    "columnName": "fullName",
-    "method": "getFullName",
-    "name": "Full name"
-  }, {
-    "columnName": "abbreviation",
-    "method": "getAbbreviation",
-    "name": "Abbreviation"
-  }, {
-    "columnName": "formula",
-    "method": "getFormula",
-    "name": "Formula"
-  }, {
-    "columnName": "synonyms",
-    "method": "getSynonyms",
-    "name": "Synonyms"
-  }, {
-    "columnName": "formerSymbols",
-    "method": "getFormerSymbols",
-    "name": "Former symbols"
-  }, {
-    "columnName": "references",
-    "method": "getReferences",
-    "name": "References",
-    "formatFunction": function (references) {
-      var stringBuilder = [];
-      for (var i = 0; i < references.length; i++) {
-        var reference = references[i];
-        stringBuilder.push(reference.getType() + ":" + reference.getResource());
-      }
-      return stringBuilder.join(",");
-    }
-  }, {
-    "columnName": "linkedSubmodelId",
-    "method": "getLinkedSubmodelId",
-    "name": "Linked submodel"
-  }, {
-    "columnName": "elementId",
-    "method": "getElementId",
-    "name": "Element external id"
-  }];
-};
-
-
-module.exports = ElementExportPanel;
+"use strict";
+
+/* exported logger */
+
+var AbstractExportPanel = require('./AbstractExportPanel');
+var GuiMessageError = require('../GuiMessageError');
+
+var logger = require('../../logger');
+
+var Promise = require("bluebird");
+
+function ElementExportPanel(params) {
+  params.panelName = "elementExport";
+  AbstractExportPanel.call(this, params);
+}
+
+ElementExportPanel.prototype = Object.create(AbstractExportPanel.prototype);
+ElementExportPanel.prototype.constructor = ElementExportPanel;
+
+ElementExportPanel.prototype.init = function () {
+  var self = this;
+  var element = self.getElement();
+  var configuration;
+  return ServerConnector.getConfiguration().then(function (result) {
+    configuration = result;
+    var typeDiv = self._createSelectTypeDiv(configuration.getElementTypes());
+    element.appendChild(typeDiv);
+    element.appendChild(self._createSelectColumnDiv(self.getAllColumns()));
+    return ServerConnector.getProjectStatistics(self.getProject().getProjectId());
+  }).then(function (statistics) {
+    return self._createMiriamTypeDiv(statistics.getElementAnnotations());
+  }).then(function (div) {
+    element.appendChild(div);
+    return self._createSelectIncludedCompartmentDiv();
+  }).then(function (div) {
+    element.appendChild(div);
+    return self._createSelectExcludedCompartmentDiv();
+  }).then(function (div) {
+    element.appendChild(div);
+    element.appendChild(self._createDownloadButton());
+  }).then(function () {
+    $(window).trigger('resize');
+  });
+};
+
+ElementExportPanel.prototype.createResponseString = function () {
+  var self = this;
+  var types, miriamTypes;
+  var includedCompartmentIds = [];
+  var excludedCompartmentIds = [];
+  var models = self.getProject().getModels();
+
+  var elements = [];
+  return self.getSelectedTypes().then(function (result) {
+    if (result.length === 0) {
+      return Promise.reject(new GuiMessageError("You must select at least one type"));
+    }
+    types = result;
+    return self.getSelectedIncludedCompartments();
+  }).then(function (result) {
+    result.forEach(function (compartment) {
+      includedCompartmentIds.push(compartment.getId());
+    });
+    return self.getSelectedExcludedCompartments();
+  }).then(function (result) {
+    result.forEach(function (compartment) {
+      excludedCompartmentIds.push(compartment.getId());
+    });
+
+    var promises = [];
+    for (var i = 0; i < models.length; i++) {
+      promises.push(models[i].getAliases({
+        type: types,
+        complete: true,
+        includedCompartmentIds: includedCompartmentIds,
+        excludedCompartmentIds: excludedCompartmentIds
+      }));
+    }
+    return Promise.all(promises);
+  }).then(function (aliasesByModel) {
+    for (var i = 0; i < aliasesByModel.length; i++) {
+      for (var j = 0; j < aliasesByModel[i].length; j++) {
+        elements.push(aliasesByModel[i][j]);
+      }
+    }
+
+    return self.getSelectedMiriamTypes();
+  }).then(function (result) {
+    miriamTypes = result;
+    return self.getSelectedColumns();
+  }).then(function (selectedColumns) {
+    if (selectedColumns.length === 0) {
+      return Promise.reject(new GuiMessageError("You must select at least one column"));
+    }
+
+    var rows = [];
+    rows.push(self.createResponseHeader(selectedColumns, miriamTypes));
+    for (var i = 0; i < elements.length; i++) {
+      rows.push(self.createResponseRow(elements[i], selectedColumns, miriamTypes));
+    }
+    return rows.join("\n");
+  });
+};
+
+ElementExportPanel.prototype.createResponseRow = function (alias, columns, miriamTypes) {
+  var stringBuilder = [];
+  var i, value;
+  for (i = 0; i < columns.length; i++) {
+    var column = columns[i];
+    value = alias[column.method]();
+    if (column.formatFunction !== undefined) {
+      value = column.formatFunction(value);
+    }
+    if (value instanceof String || typeof value === "string") {
+      value = value.replace(/[\n\r]/g, ' ');
+    }
+    stringBuilder.push(value);
+  }
+  for (i = 0; i < miriamTypes.length; i++) {
+    value = "";
+    var miriamType = miriamTypes[i];
+    var references = alias.getReferences();
+    for (var j = 0; j < references.length; j++) {
+      var reference = references[j];
+      if (reference.getType() === miriamType.getName()) {
+        value += reference.getResource() + ",";
+      }
+    }
+    stringBuilder.push(value);
+  }
+  return stringBuilder.join("\t");
+};
+
+ElementExportPanel.prototype.getAllColumns = function () {
+  return [{
+    "columnName": "id",
+    "method": "getId",
+    "name": "Id"
+  }, {
+    "columnName": "name",
+    "method": "getName",
+    "name": "Name"
+  }, {
+    "columnName": "description",
+    "method": "getDescription",
+    "name": "Description"
+  }, {
+    "columnName": "modelId",
+    "method": "getModelId",
+    "name": "Model"
+  }, {
+    "columnName": "type",
+    "method": "getType",
+    "name": "Type"
+  }, {
+    "columnName": "complexId",
+    "method": "getComplexId",
+    "name": "Complex"
+  }, {
+    "columnName": "compartmentId",
+    "method": "getCompartmentId",
+    "name": "Compartment"
+  }, {
+    "columnName": "charge",
+    "method": "getCharge",
+    "name": "Charge"
+  }, {
+    "columnName": "symbol",
+    "method": "getSymbol",
+    "name": "Symbol"
+  }, {
+    "columnName": "fullName",
+    "method": "getFullName",
+    "name": "Full name"
+  }, {
+    "columnName": "abbreviation",
+    "method": "getAbbreviation",
+    "name": "Abbreviation"
+  }, {
+    "columnName": "formula",
+    "method": "getFormula",
+    "name": "Formula"
+  }, {
+    "columnName": "synonyms",
+    "method": "getSynonyms",
+    "name": "Synonyms"
+  }, {
+    "columnName": "formerSymbols",
+    "method": "getFormerSymbols",
+    "name": "Former symbols"
+  }, {
+    "columnName": "references",
+    "method": "getReferences",
+    "name": "References",
+    "formatFunction": function (references) {
+      var stringBuilder = [];
+      for (var i = 0; i < references.length; i++) {
+        var reference = references[i];
+        stringBuilder.push(reference.getType() + ":" + reference.getResource());
+      }
+      return stringBuilder.join(",");
+    }
+  }, {
+    "columnName": "linkedSubmodelId",
+    "method": "getLinkedSubmodelId",
+    "name": "Linked submodel"
+  }, {
+    "columnName": "elementId",
+    "method": "getElementId",
+    "name": "Element external id"
+  }];
+};
+
+
+module.exports = ElementExportPanel;
diff --git a/frontend-js/src/main/js/gui/export/GraphicsExportPanel.js b/frontend-js/src/main/js/gui/export/GraphicsExportPanel.js
index 4b3c3d2a124e6b5914054439155c7d1d54084b6b..9976880791a52ebec5572738f01d8372ac865f19 100644
--- a/frontend-js/src/main/js/gui/export/GraphicsExportPanel.js
+++ b/frontend-js/src/main/js/gui/export/GraphicsExportPanel.js
@@ -1,159 +1,159 @@
-"use strict";
-
-/* exported logger */
-
-var AbstractExportPanel = require('./AbstractExportPanel');
-var Functions = require('../../Functions');
-var GuiConnector = require('../../GuiConnector');
-
-var logger = require('../../logger');
-var xss = require('xss');
-
-function GraphicsExportPanel(params) {
-  params.panelName = "graphicsExport";
-  AbstractExportPanel.call(this, params);
-}
-
-GraphicsExportPanel.prototype = Object.create(AbstractExportPanel.prototype);
-GraphicsExportPanel.prototype.constructor = GraphicsExportPanel;
-
-GraphicsExportPanel.prototype.init = function () {
-  var self = this;
-  var element = self.getElement();
-  var configuration;
-  element.appendChild(self._createSelectProjectDiv());
-  return ServerConnector.getConfiguration().then(function (result) {
-    configuration = result;
-    element.appendChild(self._createSelectGraphicsFormatDiv(configuration.getImageConverters()));
-    element.appendChild(self._createDownloadButton());
-  }).then(function () {
-    $(window).trigger('resize');
-  });
-};
-
-GraphicsExportPanel.prototype._createSelectProjectDiv = function () {
-  var self = this;
-  var typeDiv = Functions.createElement({
-    type: "div",
-    name: "modelSelectDiv"
-  });
-  typeDiv.appendChild(Functions.createElement({
-    type: "h4",
-    content: "(Sub)map:"
-  }));
-
-  var choicesContainer = Functions.createElement({
-    type: "ul"
-  });
-  typeDiv.appendChild(choicesContainer);
-
-  var models = self.getModels();
-
-  for (var i = 0; i < models.length; i++) {
-    var model = models[i];
-    var checkedString = "";
-    if (i === 0) {
-      checkedString = ' checked="checked" ';
-    }
-    var modelName = xss(model.getName());
-    var row = Functions.createElement({
-      type: "li",
-      content: '<div><label> <input type="radio" name="model" value="' + model.getId() + '"' + checkedString + '/>'
-      + modelName + '</label></div>',
-      xss: false
-    });
-    choicesContainer.appendChild(row);
-  }
-
-  return typeDiv;
-};
-
-GraphicsExportPanel.prototype._createSelectGraphicsFormatDiv = function (formats) {
-  var typeDiv = Functions.createElement({
-    type: "div",
-    name: "formatSelectDiv"
-  });
-  typeDiv.appendChild(Functions.createElement({
-    type: "h4",
-    content: "Format:"
-  }));
-
-  var choicesContainer = Functions.createElement({
-    type: "ul"
-  });
-  typeDiv.appendChild(choicesContainer);
-
-  for (var i = 0; i < formats.length; i++) {
-    var format = formats[i];
-    var checkedString = "";
-    if (i === 0) {
-      checkedString = ' checked="checked" ';
-    }
-    var row = Functions.createElement({
-      type: "li",
-      content: '<div><label> <input type="radio" name="format" value="' + format.handler + '"' + checkedString + '/>'
-      + format.name + '</label></div>',
-      xss: false
-
-    });
-    choicesContainer.appendChild(row);
-  }
-
-  return typeDiv;
-};
-
-GraphicsExportPanel.prototype.getSubmapId = function () {
-  var self = this;
-  var div = $("div[name='modelSelectDiv']", $(self.getElement()))[0];
-  var id = null;
-  $(":checked", $(div)).each(function (index, element) {
-    id = element.value;
-  });
-  return id;
-};
-GraphicsExportPanel.prototype.getFormatHandler = function () {
-  var self = this;
-  var div = $("div[name='formatSelectDiv']", $(self.getElement()))[0];
-  var format = null;
-  $(":checked", $(div)).each(function (index, element) {
-    format = element.value;
-  });
-  return format;
-};
-
-GraphicsExportPanel.prototype._createDownloadButton = function () {
-  var self = this;
-  var downloadDiv = Functions.createElement({
-    type: "div",
-    name: "downloadDiv",
-    style: "clear:both; padding: 10px;"
-  });
-  var button = Functions.createElement({
-    type: "button",
-    name: "downloadButton",
-    content: " Download",
-    onclick: function () {
-      var identifier = null;
-      var defaultOverlayName = "Network";
-      for (var i = 0; i < self.getProject().getDataOverlays().length; i++) {
-        var overlay = self.getProject().getDataOverlays()[i];
-        if (identifier === null || overlay.getName() === defaultOverlayName) {
-          identifier = overlay.getId();
-        }
-      }
-
-      return ServerConnector.getImageDownloadUrl({
-        modelId: self.getSubmapId(),
-        backgroundOverlayId: identifier,
-        handlerClass: self.getFormatHandler()
-      }).then(function (url) {
-        return self.downloadFile(url);
-      }).then(null, GuiConnector.alert);
-    }
-  });
-  downloadDiv.appendChild(button);
-
-  return downloadDiv;
-};
-
-module.exports = GraphicsExportPanel;
+"use strict";
+
+/* exported logger */
+
+var AbstractExportPanel = require('./AbstractExportPanel');
+var Functions = require('../../Functions');
+var GuiConnector = require('../../GuiConnector');
+
+var logger = require('../../logger');
+var xss = require('xss');
+
+function GraphicsExportPanel(params) {
+  params.panelName = "graphicsExport";
+  AbstractExportPanel.call(this, params);
+}
+
+GraphicsExportPanel.prototype = Object.create(AbstractExportPanel.prototype);
+GraphicsExportPanel.prototype.constructor = GraphicsExportPanel;
+
+GraphicsExportPanel.prototype.init = function () {
+  var self = this;
+  var element = self.getElement();
+  var configuration;
+  element.appendChild(self._createSelectProjectDiv());
+  return ServerConnector.getConfiguration().then(function (result) {
+    configuration = result;
+    element.appendChild(self._createSelectGraphicsFormatDiv(configuration.getImageConverters()));
+    element.appendChild(self._createDownloadButton());
+  }).then(function () {
+    $(window).trigger('resize');
+  });
+};
+
+GraphicsExportPanel.prototype._createSelectProjectDiv = function () {
+  var self = this;
+  var typeDiv = Functions.createElement({
+    type: "div",
+    name: "modelSelectDiv"
+  });
+  typeDiv.appendChild(Functions.createElement({
+    type: "h4",
+    content: "(Sub)map:"
+  }));
+
+  var choicesContainer = Functions.createElement({
+    type: "ul"
+  });
+  typeDiv.appendChild(choicesContainer);
+
+  var models = self.getModels();
+
+  for (var i = 0; i < models.length; i++) {
+    var model = models[i];
+    var checkedString = "";
+    if (i === 0) {
+      checkedString = ' checked="checked" ';
+    }
+    var modelName = xss(model.getName());
+    var row = Functions.createElement({
+      type: "li",
+      content: '<div><label> <input type="radio" name="model" value="' + model.getId() + '"' + checkedString + '/>'
+      + modelName + '</label></div>',
+      xss: false
+    });
+    choicesContainer.appendChild(row);
+  }
+
+  return typeDiv;
+};
+
+GraphicsExportPanel.prototype._createSelectGraphicsFormatDiv = function (formats) {
+  var typeDiv = Functions.createElement({
+    type: "div",
+    name: "formatSelectDiv"
+  });
+  typeDiv.appendChild(Functions.createElement({
+    type: "h4",
+    content: "Format:"
+  }));
+
+  var choicesContainer = Functions.createElement({
+    type: "ul"
+  });
+  typeDiv.appendChild(choicesContainer);
+
+  for (var i = 0; i < formats.length; i++) {
+    var format = formats[i];
+    var checkedString = "";
+    if (i === 0) {
+      checkedString = ' checked="checked" ';
+    }
+    var row = Functions.createElement({
+      type: "li",
+      content: '<div><label> <input type="radio" name="format" value="' + format.handler + '"' + checkedString + '/>'
+      + format.name + '</label></div>',
+      xss: false
+
+    });
+    choicesContainer.appendChild(row);
+  }
+
+  return typeDiv;
+};
+
+GraphicsExportPanel.prototype.getSubmapId = function () {
+  var self = this;
+  var div = $("div[name='modelSelectDiv']", $(self.getElement()))[0];
+  var id = null;
+  $(":checked", $(div)).each(function (index, element) {
+    id = element.value;
+  });
+  return id;
+};
+GraphicsExportPanel.prototype.getFormatHandler = function () {
+  var self = this;
+  var div = $("div[name='formatSelectDiv']", $(self.getElement()))[0];
+  var format = null;
+  $(":checked", $(div)).each(function (index, element) {
+    format = element.value;
+  });
+  return format;
+};
+
+GraphicsExportPanel.prototype._createDownloadButton = function () {
+  var self = this;
+  var downloadDiv = Functions.createElement({
+    type: "div",
+    name: "downloadDiv",
+    style: "clear:both; padding: 10px;"
+  });
+  var button = Functions.createElement({
+    type: "button",
+    name: "downloadButton",
+    content: " Download",
+    onclick: function () {
+      var identifier = null;
+      var defaultOverlayName = "Network";
+      for (var i = 0; i < self.getProject().getDataOverlays().length; i++) {
+        var overlay = self.getProject().getDataOverlays()[i];
+        if (identifier === null || overlay.getName() === defaultOverlayName) {
+          identifier = overlay.getId();
+        }
+      }
+
+      return ServerConnector.getImageDownloadUrl({
+        modelId: self.getSubmapId(),
+        backgroundOverlayId: identifier,
+        handlerClass: self.getFormatHandler()
+      }).then(function (url) {
+        return self.downloadFile(url);
+      }).then(null, GuiConnector.alert);
+    }
+  });
+  downloadDiv.appendChild(button);
+
+  return downloadDiv;
+};
+
+module.exports = GraphicsExportPanel;
diff --git a/frontend-js/src/main/js/gui/export/NetworkExportPanel.js b/frontend-js/src/main/js/gui/export/NetworkExportPanel.js
index d34f0b40a9b60d9e9e6368ae5e63b0cd9bcb718e..1543fafae775f649c2e207e4251c34681a63ce7f 100644
--- a/frontend-js/src/main/js/gui/export/NetworkExportPanel.js
+++ b/frontend-js/src/main/js/gui/export/NetworkExportPanel.js
@@ -1,251 +1,251 @@
-"use strict";
-
-/* exported logger */
-
-var AbstractExportPanel = require('./AbstractExportPanel');
-
-var Promise = require("bluebird");
-var logger = require('../../logger');
-var GuiMessageError = require('../GuiMessageError');
-
-
-function NetworkExportPanel(params) {
-  params.panelName = "networkExport";
-  AbstractExportPanel.call(this, params);
-}
-
-NetworkExportPanel.prototype = Object.create(AbstractExportPanel.prototype);
-NetworkExportPanel.prototype.constructor = NetworkExportPanel;
-
-NetworkExportPanel.prototype.init = function () {
-
-  var self = this;
-  var element = self.getElement();
-  var configuration;
-  return ServerConnector.getConfiguration().then(function (result) {
-    configuration = result;
-    var typeDiv = self._createSelectTypeDiv(configuration.getElementTypes());
-    element.appendChild(typeDiv);
-    element.appendChild(self._createSelectColumnDiv(self.getAllColumns()));
-    return ServerConnector.getProjectStatistics(self.getProject().getProjectId());
-  }).then(function (statistics) {
-    return self._createMiriamTypeDiv(statistics.getReactionAnnotations());
-  }).then(function (div) {
-    element.appendChild(div);
-    return self._createSelectIncludedCompartmentDiv();
-  }).then(function (div) {
-    element.appendChild(div);
-    return self._createSelectExcludedCompartmentDiv();
-  }).then(function (div) {
-    element.appendChild(div);
-    element.appendChild(self._createDownloadButton());
-  }).then(function () {
-    $(window).trigger('resize');
-  });
-
-};
-
-NetworkExportPanel.prototype.getAllColumns = function () {
-  return [{
-    "columnName": "elements",
-    "method": "getElements",
-    "name": "Elements",
-    "formatFunction": function (elements, reaction, elementIds) {
-      var stringBuilder = [];
-      var type;
-      var elementFormat = function (element) {
-        if (elementIds[element.getAlias().getId()]) {
-          stringBuilder.push(type + ":" + element.getAlias().getId());
-        }
-      };
-      type = "REACTANT";
-      reaction.getReactants().forEach(elementFormat);
-      type = "PRODUCT";
-      reaction.getProducts().forEach(elementFormat);
-      type = "MODIFIER";
-      reaction.getModifiers().forEach(elementFormat);
-
-      return stringBuilder.join(",");
-    }
-  }, {
-    "columnName": "id",
-    "method": "getId",
-    "name": "Id"
-  }, {
-    "columnName": "description",
-    "method": "getDescription",
-    "name": "Description"
-  }, {
-    "columnName": "modelId",
-    "method": "getModelId",
-    "name": "Model"
-  }, {
-    "columnName": "type",
-    "method": "getType",
-    "name": "Type"
-  }, {
-    "columnName": "symbol",
-    "method": "getSymbol",
-    "name": "Symbol"
-  }, {
-    "columnName": "abbreviation",
-    "method": "getAbbreviation",
-    "name": "Abbreviation"
-  }, {
-    "columnName": "formula",
-    "method": "getFormula",
-    "name": "Formula"
-  }, {
-    "columnName": "synonyms",
-    "method": "getSynonyms",
-    "name": "Synonyms"
-  }, {
-    "columnName": "references",
-    "method": "getReferences",
-    "name": "References",
-    "formatFunction": function (references) {
-      var stringBuilder = [];
-      for (var i = 0; i < references.length; i++) {
-        var reference = references[i];
-        stringBuilder.push(reference.getType() + ":" + reference.getResource());
-      }
-      return stringBuilder.join(",");
-    }
-  }, {
-    "columnName": "reactionId",
-    "method": "getReactionId",
-    "name": "Element external id"
-  }, {
-    "columnName": "mechanicalConfidenceScore",
-    "method": "getMechanicalConfidenceScore",
-    "name": "Mechanical Confidence Score"
-  }, {
-    "columnName": "lowerBound",
-    "method": "getLowerBound",
-    "name": "Lower Bound"
-  }, {
-    "columnName": "upperBound",
-    "method": "getUpperBound",
-    "name": "Upper Bound"
-  }, {
-    "columnName": "geneProteinReaction",
-    "method": "getGeneProteinReaction",
-    "name": "Gene Protein Reaction"
-  }, {
-    "columnName": "subsystem",
-    "method": "getSubsystem",
-    "name": "Subsystem"
-  }];
-};
-
-function matchReaction(reaction, elementIds) {
-  var count = 0;
-  reaction.getElements().forEach(function (element) {
-    if (elementIds[element.getId()]) {
-      count++;
-    }
-  });
-  return count > 1;
-}
-
-NetworkExportPanel.prototype.createResponseString = function () {
-  var self = this;
-  var types, miriamTypes;
-  var includedCompartmentIds = [];
-  var excludedCompartmentIds = [];
-  var models = self.getProject().getModels();
-
-  var elementIds = [];
-  var reactions = [];
-  return self.getSelectedTypes().then(function (result) {
-    if (result.length === 0) {
-      return Promise.reject(new GuiMessageError("You must select at least one type"));
-    }
-    types = result;
-    return self.getSelectedIncludedCompartments();
-  }).then(function (result) {
-    result.forEach(function (compartment) {
-      includedCompartmentIds.push(compartment.getId());
-    });
-    return self.getSelectedExcludedCompartments();
-  }).then(function (result) {
-    result.forEach(function (compartment) {
-      excludedCompartmentIds.push(compartment.getId());
-    });
-
-    var promises = [];
-    for (var i = 0; i < models.length; i++) {
-      promises.push(models[i].getAliases({
-        type: types,
-        complete: true,
-        includedCompartmentIds: includedCompartmentIds,
-        excludedCompartmentIds: excludedCompartmentIds
-      }));
-    }
-    return Promise.all(promises);
-  }).then(function (aliasesByModel) {
-    var promises = [];
-    for (var i = 0; i < models.length; i++) {
-      promises.push(models[i].getReactionsForElements(aliasesByModel[i], true));
-      for (var j = 0; j < aliasesByModel[i].length; j++) {
-        elementIds[aliasesByModel[i][j].getId()] = true;
-      }
-    }
-    return Promise.all(promises);
-  }).then(function (reactionsByModel) {
-    for (var i = 0; i < models.length; i++) {
-      for (var j = 0; j < reactionsByModel[i].length; j++) {
-        var reaction = reactionsByModel[i][j];
-        if (matchReaction(reaction, elementIds)) {
-          reactions.push(reaction);
-        }
-      }
-    }
-    return self.getSelectedMiriamTypes();
-  }).then(function (result) {
-    miriamTypes = result;
-    return self.getSelectedColumns();
-  }).then(function (selectedColumns) {
-    if (selectedColumns.length === 0) {
-      return Promise.reject(new GuiMessageError("You must select at least one column"));
-    }
-
-    var rows = [];
-    rows.push(self.createResponseHeader(selectedColumns, miriamTypes));
-    for (var i = 0; i < reactions.length; i++) {
-      rows.push(self.createResponseRow(reactions[i], selectedColumns, miriamTypes, elementIds));
-    }
-    return rows.join("\n");
-  });
-};
-
-NetworkExportPanel.prototype.createResponseRow = function (reaction, columns, miriamTypes, elementIds) {
-  var stringBuilder = [];
-  var i, value;
-  for (i = 0; i < columns.length; i++) {
-    var column = columns[i];
-    value = reaction[column.method]();
-    if (column.formatFunction !== undefined) {
-      value = column.formatFunction(value, reaction, elementIds);
-    }
-    if (value instanceof String || typeof value === "string") {
-      value = value.replace(/[\n\r]/g, ' ');
-    }
-    stringBuilder.push(value);
-  }
-  for (i = 0; i < miriamTypes.length; i++) {
-    value = "";
-    var miriamType = miriamTypes[i];
-    var references = reaction.getReferences();
-    for (var j = 0; j < references.length; j++) {
-      var reference = references[j];
-      if (reference.getType() === miriamType.getName()) {
-        value += reference.getResource() + ",";
-      }
-    }
-    stringBuilder.push(value);
-  }
-  return stringBuilder.join("\t");
-};
-
-module.exports = NetworkExportPanel;
+"use strict";
+
+/* exported logger */
+
+var AbstractExportPanel = require('./AbstractExportPanel');
+
+var Promise = require("bluebird");
+var logger = require('../../logger');
+var GuiMessageError = require('../GuiMessageError');
+
+
+function NetworkExportPanel(params) {
+  params.panelName = "networkExport";
+  AbstractExportPanel.call(this, params);
+}
+
+NetworkExportPanel.prototype = Object.create(AbstractExportPanel.prototype);
+NetworkExportPanel.prototype.constructor = NetworkExportPanel;
+
+NetworkExportPanel.prototype.init = function () {
+
+  var self = this;
+  var element = self.getElement();
+  var configuration;
+  return ServerConnector.getConfiguration().then(function (result) {
+    configuration = result;
+    var typeDiv = self._createSelectTypeDiv(configuration.getElementTypes());
+    element.appendChild(typeDiv);
+    element.appendChild(self._createSelectColumnDiv(self.getAllColumns()));
+    return ServerConnector.getProjectStatistics(self.getProject().getProjectId());
+  }).then(function (statistics) {
+    return self._createMiriamTypeDiv(statistics.getReactionAnnotations());
+  }).then(function (div) {
+    element.appendChild(div);
+    return self._createSelectIncludedCompartmentDiv();
+  }).then(function (div) {
+    element.appendChild(div);
+    return self._createSelectExcludedCompartmentDiv();
+  }).then(function (div) {
+    element.appendChild(div);
+    element.appendChild(self._createDownloadButton());
+  }).then(function () {
+    $(window).trigger('resize');
+  });
+
+};
+
+NetworkExportPanel.prototype.getAllColumns = function () {
+  return [{
+    "columnName": "elements",
+    "method": "getElements",
+    "name": "Elements",
+    "formatFunction": function (elements, reaction, elementIds) {
+      var stringBuilder = [];
+      var type;
+      var elementFormat = function (element) {
+        if (elementIds[element.getAlias().getId()]) {
+          stringBuilder.push(type + ":" + element.getAlias().getId());
+        }
+      };
+      type = "REACTANT";
+      reaction.getReactants().forEach(elementFormat);
+      type = "PRODUCT";
+      reaction.getProducts().forEach(elementFormat);
+      type = "MODIFIER";
+      reaction.getModifiers().forEach(elementFormat);
+
+      return stringBuilder.join(",");
+    }
+  }, {
+    "columnName": "id",
+    "method": "getId",
+    "name": "Id"
+  }, {
+    "columnName": "description",
+    "method": "getDescription",
+    "name": "Description"
+  }, {
+    "columnName": "modelId",
+    "method": "getModelId",
+    "name": "Model"
+  }, {
+    "columnName": "type",
+    "method": "getType",
+    "name": "Type"
+  }, {
+    "columnName": "symbol",
+    "method": "getSymbol",
+    "name": "Symbol"
+  }, {
+    "columnName": "abbreviation",
+    "method": "getAbbreviation",
+    "name": "Abbreviation"
+  }, {
+    "columnName": "formula",
+    "method": "getFormula",
+    "name": "Formula"
+  }, {
+    "columnName": "synonyms",
+    "method": "getSynonyms",
+    "name": "Synonyms"
+  }, {
+    "columnName": "references",
+    "method": "getReferences",
+    "name": "References",
+    "formatFunction": function (references) {
+      var stringBuilder = [];
+      for (var i = 0; i < references.length; i++) {
+        var reference = references[i];
+        stringBuilder.push(reference.getType() + ":" + reference.getResource());
+      }
+      return stringBuilder.join(",");
+    }
+  }, {
+    "columnName": "reactionId",
+    "method": "getReactionId",
+    "name": "Element external id"
+  }, {
+    "columnName": "mechanicalConfidenceScore",
+    "method": "getMechanicalConfidenceScore",
+    "name": "Mechanical Confidence Score"
+  }, {
+    "columnName": "lowerBound",
+    "method": "getLowerBound",
+    "name": "Lower Bound"
+  }, {
+    "columnName": "upperBound",
+    "method": "getUpperBound",
+    "name": "Upper Bound"
+  }, {
+    "columnName": "geneProteinReaction",
+    "method": "getGeneProteinReaction",
+    "name": "Gene Protein Reaction"
+  }, {
+    "columnName": "subsystem",
+    "method": "getSubsystem",
+    "name": "Subsystem"
+  }];
+};
+
+function matchReaction(reaction, elementIds) {
+  var count = 0;
+  reaction.getElements().forEach(function (element) {
+    if (elementIds[element.getId()]) {
+      count++;
+    }
+  });
+  return count > 1;
+}
+
+NetworkExportPanel.prototype.createResponseString = function () {
+  var self = this;
+  var types, miriamTypes;
+  var includedCompartmentIds = [];
+  var excludedCompartmentIds = [];
+  var models = self.getProject().getModels();
+
+  var elementIds = [];
+  var reactions = [];
+  return self.getSelectedTypes().then(function (result) {
+    if (result.length === 0) {
+      return Promise.reject(new GuiMessageError("You must select at least one type"));
+    }
+    types = result;
+    return self.getSelectedIncludedCompartments();
+  }).then(function (result) {
+    result.forEach(function (compartment) {
+      includedCompartmentIds.push(compartment.getId());
+    });
+    return self.getSelectedExcludedCompartments();
+  }).then(function (result) {
+    result.forEach(function (compartment) {
+      excludedCompartmentIds.push(compartment.getId());
+    });
+
+    var promises = [];
+    for (var i = 0; i < models.length; i++) {
+      promises.push(models[i].getAliases({
+        type: types,
+        complete: true,
+        includedCompartmentIds: includedCompartmentIds,
+        excludedCompartmentIds: excludedCompartmentIds
+      }));
+    }
+    return Promise.all(promises);
+  }).then(function (aliasesByModel) {
+    var promises = [];
+    for (var i = 0; i < models.length; i++) {
+      promises.push(models[i].getReactionsForElements(aliasesByModel[i], true));
+      for (var j = 0; j < aliasesByModel[i].length; j++) {
+        elementIds[aliasesByModel[i][j].getId()] = true;
+      }
+    }
+    return Promise.all(promises);
+  }).then(function (reactionsByModel) {
+    for (var i = 0; i < models.length; i++) {
+      for (var j = 0; j < reactionsByModel[i].length; j++) {
+        var reaction = reactionsByModel[i][j];
+        if (matchReaction(reaction, elementIds)) {
+          reactions.push(reaction);
+        }
+      }
+    }
+    return self.getSelectedMiriamTypes();
+  }).then(function (result) {
+    miriamTypes = result;
+    return self.getSelectedColumns();
+  }).then(function (selectedColumns) {
+    if (selectedColumns.length === 0) {
+      return Promise.reject(new GuiMessageError("You must select at least one column"));
+    }
+
+    var rows = [];
+    rows.push(self.createResponseHeader(selectedColumns, miriamTypes));
+    for (var i = 0; i < reactions.length; i++) {
+      rows.push(self.createResponseRow(reactions[i], selectedColumns, miriamTypes, elementIds));
+    }
+    return rows.join("\n");
+  });
+};
+
+NetworkExportPanel.prototype.createResponseRow = function (reaction, columns, miriamTypes, elementIds) {
+  var stringBuilder = [];
+  var i, value;
+  for (i = 0; i < columns.length; i++) {
+    var column = columns[i];
+    value = reaction[column.method]();
+    if (column.formatFunction !== undefined) {
+      value = column.formatFunction(value, reaction, elementIds);
+    }
+    if (value instanceof String || typeof value === "string") {
+      value = value.replace(/[\n\r]/g, ' ');
+    }
+    stringBuilder.push(value);
+  }
+  for (i = 0; i < miriamTypes.length; i++) {
+    value = "";
+    var miriamType = miriamTypes[i];
+    var references = reaction.getReferences();
+    for (var j = 0; j < references.length; j++) {
+      var reference = references[j];
+      if (reference.getType() === miriamType.getName()) {
+        value += reference.getResource() + ",";
+      }
+    }
+    stringBuilder.push(value);
+  }
+  return stringBuilder.join("\t");
+};
+
+module.exports = NetworkExportPanel;
diff --git a/frontend-js/src/main/js/gui/leftPanel/AbstractDbPanel.js b/frontend-js/src/main/js/gui/leftPanel/AbstractDbPanel.js
index 53abb947aab7dd1e45d4decba0233d025d9b5e3d..b6ead02a0d361ed46a2d7ee86733b8deb993d8e1 100644
--- a/frontend-js/src/main/js/gui/leftPanel/AbstractDbPanel.js
+++ b/frontend-js/src/main/js/gui/leftPanel/AbstractDbPanel.js
@@ -1,426 +1,426 @@
-"use strict";
-
-/* exported logger */
-
-var Promise = require("bluebird");
-
-var GuiConnector = require('../../GuiConnector');
-var Panel = require('../Panel');
-var PanelControlElementType = require('../PanelControlElementType');
-
-var logger = require('../../logger');
-var Functions = require('../../Functions');
-
-/**
- *
- * @param {string} params.placeholder
- * @param {string} params.panelName
- * @constructor
- * @extends Panel
- */
-function AbstractDbPanel(params) {
-  Panel.call(this, params);
-  var self = this;
-
-  this._initializeGui(params.placeholder);
-  this.setOverlayDb(self.getMap().getOverlayByName(params.panelName));
-  this._createEventHandlers();
-
-  this._tabIdCount = 0;
-
-}
-
-AbstractDbPanel.prototype = Object.create(Panel.prototype);
-AbstractDbPanel.prototype.constructor = AbstractDbPanel;
-
-AbstractDbPanel.prototype._createEventHandlers = function () {
-  var self = this;
-  var searchButton = self.getControlElement(PanelControlElementType.SEARCH_BUTTON);
-  var searchInput = self.getControlElement(PanelControlElementType.SEARCH_INPUT);
-
-  var searchByQuery = function () {
-    var busyImage = $("[name=busyImage]", self.getElement());
-    busyImage.show();
-    return self.searchByQuery().finally(function () {
-      busyImage.hide();
-    });
-  };
-
-  searchButton.onclick = searchByQuery;
-  searchInput.onkeypress = function (event) {
-    if (event.keyCode === 13) {
-      return searchByQuery().then(null, GuiConnector.alert);
-    }
-  };
-
-  $(searchInput).typeahead({
-    minLength: 1,
-    hint: true,
-    highlight: true
-  }, {
-    source: function (query, callback) {
-      callback(self.getAutocomplete(query.toLowerCase()));
-    }
-  });
-
-  $(searchInput).on('typeahead:select', function () {
-    searchByQuery();
-  });
-
-  self.getOverlayDb().addListener("onSearch", function () {
-    return self.refreshSearchResults();
-  });
-
-  self.getOverlayDb().addListener("onClear", function () {
-    searchInput.value = "";
-  });
-
-};
-
-AbstractDbPanel.prototype._initializeGui = function (placeholder) {
-  var searchQueryDiv = Functions.createElement({
-    type: "div",
-    name: "searchQuery",
-    className: "searchPanel"
-  });
-  this.getElement().appendChild(searchQueryDiv);
-  this.setControlElement(PanelControlElementType.SEARCH_DIV, searchQueryDiv);
-
-  var busyImage = Functions.createElement({
-    type: "img",
-    name: "busyImage",
-    style: "display:block;position: absolute;margin-left: 80px;z-index: 10;display:none",
-    src: "resources/images/icons/ajax-loader.gif"
-  });
-  searchQueryDiv.appendChild(busyImage);
-
-  var searchLabel = Functions.createElement({
-    type: "div",
-    name: "searchLabel",
-    content: "SEARCH:"
-  });
-  searchQueryDiv.appendChild(searchLabel);
-  this.setControlElement(PanelControlElementType.SEARCH_LABEL, searchLabel);
-
-  var searchInputDiv = Functions.createElement({
-    type: "table"
-  });
-  searchQueryDiv.appendChild(searchInputDiv);
-
-  var searchInputRow = Functions.createElement({
-    type: "tr"
-  });
-  searchInputDiv.appendChild(searchInputRow);
-
-  var searchInputCell = Functions.createElement({
-    type: "td"
-  });
-  searchInputRow.appendChild(searchInputCell);
-
-  var searchInput = Functions.createElement({
-    type: "input",
-    name: "searchInput",
-    className: "input-field typeahead"
-  });
-  if (placeholder !== undefined) {
-    searchInput.placeholder = placeholder;
-  }
-  searchInputCell.appendChild(searchInput);
-  this.setControlElement(PanelControlElementType.SEARCH_INPUT, searchInput);
-
-  var searchButtonCell = Functions.createElement({
-    type: "td"
-  });
-  searchInputRow.appendChild(searchButtonCell);
-
-  var searchButton = Functions.createElement({
-    type: "a",
-    content: '<img src="resources/images/icons/search.png"/>',
-    xss: false
-  });
-  searchButton.href = "#";
-  searchButtonCell.appendChild(searchButton);
-  this.setControlElement(PanelControlElementType.SEARCH_BUTTON, searchButton);
-
-  var searchResultsDiv = Functions.createElement({
-    type: "div",
-    name: "searchResults",
-    className: "tabbable boxed parentTabs"
-  });
-  this.getElement().appendChild(searchResultsDiv);
-  this.setControlElement(PanelControlElementType.SEARCH_RESULTS_DIV, searchResultsDiv);
-
-  var searchResultsNavTabDiv = Functions.createElement({
-    type: "ul",
-    className: "nav nav-tabs",
-    content: '<li class="active"><a href="#set1"/></li>',
-    xss: false
-  });
-  searchResultsDiv.appendChild(searchResultsNavTabDiv);
-  this.setControlElement(PanelControlElementType.SEARCH_RESULTS_NAV_TAB, searchResultsNavTabDiv);
-
-  var searchResultsContentTabDiv = Functions.createElement({
-    type: "div",
-    className: "tab-content",
-    content: '<div class="tab-pane fade active in" name="set1" id="set1"/>',
-    xss: false
-  });
-  searchResultsDiv.appendChild(searchResultsContentTabDiv);
-  this.setControlElement(PanelControlElementType.SEARCH_RESULTS_CONTENT_TAB, searchResultsContentTabDiv);
-
-};
-
-AbstractDbPanel.prototype.setOverlayDb = function (overlayDb) {
-  if (overlayDb === undefined) {
-    throw new Error("Undefined overlayDb for panel: " + this.getPanelName());
-  }
-  this._overlayDb = overlayDb;
-};
-
-/**
- *
- * @returns {AbstractDbOverlay}
- */
-AbstractDbPanel.prototype.getOverlayDb = function () {
-  return this._overlayDb;
-};
-
-AbstractDbPanel.prototype.clearResults = function () {
-  var navElement = this.getControlElement(PanelControlElementType.SEARCH_RESULTS_NAV_TAB);
-  while (navElement.firstChild) {
-    navElement.removeChild(navElement.firstChild);
-  }
-
-  var contentElement = this.getControlElement(PanelControlElementType.SEARCH_RESULTS_CONTENT_TAB);
-  while (contentElement.firstChild) {
-    contentElement.removeChild(contentElement.firstChild);
-  }
-};
-
-AbstractDbPanel.prototype.refreshSearchResults = function () {
-  var self = this;
-  self.clearResults();
-  var searchDb = self.getOverlayDb();
-  var queries = searchDb.getQueries();
-
-  var promises = [];
-  for (var i = 0; i < queries.length; i++) {
-    promises.push(searchDb.getElementsByQuery(queries[i]));
-  }
-  return Promise.all(promises).then(function (results) {
-    return Promise.each(queries, function(query, index){
-      return self.addResultTab(query, results[index]);
-    });
-  }).then(function(){
-    self.onresize();
-  });
-};
-
-AbstractDbPanel.prototype.getAutocomplete = function () {
-  logger.warn("Get autocomplete not implemented");
-};
-
-AbstractDbPanel.prototype.searchByQuery = function () {
-  throw new Error("searchByQuery is not implemented");
-};
-
-AbstractDbPanel.prototype.addResultTab = function (query, elements) {
-  var self = this;
-  var name = JSON.parse(query).query;
-
-  var tabId = this.getPanelName() + "Tab_" + this._tabIdCount;
-  this._tabIdCount++;
-
-  var navElement = this.getControlElement(PanelControlElementType.SEARCH_RESULTS_NAV_TAB);
-  var contentElement = this.getControlElement(PanelControlElementType.SEARCH_RESULTS_CONTENT_TAB);
-  var navClass = '';
-  var contentClass = 'tab-pane';
-  if (navElement.children.length === 0) {
-    navClass = "active";
-    contentClass = "tab-pane active";
-  }
-
-  var navLi = document.createElement("li");
-  navLi.className = navClass;
-
-  var navLink = Functions.createElement({
-    type: "a",
-    href: "#" + tabId,
-    onclick: function () {
-      $(this).tab('show');
-    }
-  });
-  if (name !== undefined) {
-    if (name.length > 12) {
-      name = name.substring(0, 10) + "...";
-    }
-    navLink.innerHTML = name;
-  }
-  navLi.appendChild(navLink);
-  if (query.name !== undefined) {
-    navLink.innerHTML = query.name;
-  }
-  navElement.appendChild(navLi);
-
-  var contentDiv = document.createElement("div");
-  contentDiv.className = "pre-scrollable " + contentClass;
-  contentDiv.style.maxHeight = "10px";
-
-  contentDiv.id = tabId;
-
-  contentElement.appendChild(contentDiv);
-
-  contentDiv.appendChild(this.createPreamble(elements.element));
-
-  var tableDiv = document.createElement("table");
-  tableDiv.className = "table table-bordered";
-  contentDiv.appendChild(tableDiv);
-  var tableBody = document.createElement("tbody");
-  tableDiv.appendChild(tableBody);
-
-  return Promise.each(elements, function (entry) {
-    var element = entry.element;
-    var icon = entry.icon;
-    return self.createTableElement(element, icon).then(function (div) {
-      return tableBody.appendChild(div);
-    });
-  });
-};
-
-/**
- *
- * @returns {Promise<HTMLTableRowElement>}
- */
-AbstractDbPanel.prototype.createTableElement = function () {
-  throw new Error("Not implemented");
-};
-
-/**
- *
- * @param {Target} target
- * @param {string} icon
- * @returns {Promise<HTMLTableRowElement>}
- */
-AbstractDbPanel.prototype.createTargetRow = function (target, icon) {
-  var self = this;
-  var guiUtils = self.getGuiUtils();
-  var result = document.createElement("tr");
-  var iconColumn = document.createElement("td");
-  iconColumn.style.width = "20px";
-  iconColumn.style.verticalAlign = "middle";
-  iconColumn.style.textAlign = "center";
-  result.appendChild(iconColumn);
-  var submaps = [];
-  var i;
-  if (target.getTargetElements().length > 0) {
-    var submapAddedIds = [];
-    iconColumn.appendChild(guiUtils.createIcon(icon));
-    var checkbox = document.createElement('input');
-    checkbox.type = "checkbox";
-    checkbox.checked = target.isVisible();
-    checkbox.onclick = function () {
-      target.setIsVisible(!target.isVisible());
-      self.getOverlayDb().callListeners("onTargetVisibilityChange");
-    };
-
-    iconColumn.appendChild(checkbox);
-    var elements = target.getTargetElements();
-    for (i = 0; i < elements.length; i++) {
-      var elementId = elements[i].getModelId();
-      if (elementId !== self.getMap().getId() && !submapAddedIds[elementId]) {
-        submaps.push(elementId);
-        submapAddedIds[elementId] = true;
-      }
-    }
-  }
-
-  var descColumn = document.createElement("td");
-  result.appendChild(descColumn);
-
-  descColumn.appendChild(guiUtils.createParamLine("Name: ", target.getName()));
-  descColumn.appendChild(guiUtils.createAnnotations("Elements: ", target.getTargetParticipants(), {
-    showType: false,
-    inline: true,
-    groupAnnotations: false
-  }));
-  descColumn.appendChild(guiUtils.createAnnotations("References: ", target.getReferences(), {
-    showType: false,
-    groupAnnotations: false
-  }));
-  if (submaps.length > 0) {
-    descColumn.appendChild(guiUtils.createLabel("Available in submaps: "));
-    for (i = 0; i < submaps.length; i++) {
-      var model = self.getMap().getSubmapById(submaps[i]).getModel();
-      var onclick = (function () {
-        var id = model.getId();
-        return function () {
-          self.getMap().openSubmap(id);
-        };
-      }());
-      var button = Functions.createElement({
-        type: "button",
-        className: "minerva-open-submap-button",
-        content: model.getName(),
-        onclick: onclick
-      });
-      descColumn.appendChild(button);
-    }
-  }
-  return Promise.resolve(result);
-};
-
-AbstractDbPanel.prototype.computeAutocompleteDictionary = function (queries) {
-  var result = {};
-
-  var i, j, k, mainString, substring, list;
-  //compute dict for prefixes
-  for (i = 0; i < queries.length; i++) {
-    mainString = queries[i].toLowerCase();
-    for (j = 0; j < mainString.length; j++) {
-      substring = mainString.substring(0, j + 1);
-      if (result[substring] !== undefined) {
-        continue;
-      }
-
-      list = [];
-      for (k = 0; k < 5; k++) {
-        if (k + i >= queries.length) {
-          break;
-        } else if (queries[k + i].toLowerCase().indexOf(substring.toLowerCase()) === 0) {
-          list.push(queries[k + i]);
-        }
-      }
-
-      result[substring] = list;
-    }
-  }
-
-  //and now we add substring from inside
-  for (i = 0; i < queries.length; i++) {
-    mainString = queries[i].toLowerCase();
-    for (var startSubstring = 1; startSubstring < mainString.length; startSubstring++) {
-      for (var endSubstring = startSubstring + 1; endSubstring <= mainString.length; endSubstring++) {
-        substring = mainString.substring(startSubstring, endSubstring);
-        if (mainString.indexOf(substring) !== 0) {
-          if (result[substring] === undefined) {
-            result[substring] = [];
-          }
-          if (result[substring].length < 5) {
-            var found = false;
-            for (k = 0; k < result[substring].length; k++) {
-              found |= result[substring][k] === mainString;
-            }
-            if (!found) {
-              result[substring].push(mainString);
-            }
-          }
-        }
-      }
-    }
-  }
-
-  return result;
-};
-
-
-module.exports = AbstractDbPanel;
+"use strict";
+
+/* exported logger */
+
+var Promise = require("bluebird");
+
+var GuiConnector = require('../../GuiConnector');
+var Panel = require('../Panel');
+var PanelControlElementType = require('../PanelControlElementType');
+
+var logger = require('../../logger');
+var Functions = require('../../Functions');
+
+/**
+ *
+ * @param {string} params.placeholder
+ * @param {string} params.panelName
+ * @constructor
+ * @extends Panel
+ */
+function AbstractDbPanel(params) {
+  Panel.call(this, params);
+  var self = this;
+
+  this._initializeGui(params.placeholder);
+  this.setOverlayDb(self.getMap().getOverlayByName(params.panelName));
+  this._createEventHandlers();
+
+  this._tabIdCount = 0;
+
+}
+
+AbstractDbPanel.prototype = Object.create(Panel.prototype);
+AbstractDbPanel.prototype.constructor = AbstractDbPanel;
+
+AbstractDbPanel.prototype._createEventHandlers = function () {
+  var self = this;
+  var searchButton = self.getControlElement(PanelControlElementType.SEARCH_BUTTON);
+  var searchInput = self.getControlElement(PanelControlElementType.SEARCH_INPUT);
+
+  var searchByQuery = function () {
+    var busyImage = $("[name=busyImage]", self.getElement());
+    busyImage.show();
+    return self.searchByQuery().finally(function () {
+      busyImage.hide();
+    });
+  };
+
+  searchButton.onclick = searchByQuery;
+  searchInput.onkeypress = function (event) {
+    if (event.keyCode === 13) {
+      return searchByQuery().then(null, GuiConnector.alert);
+    }
+  };
+
+  $(searchInput).typeahead({
+    minLength: 1,
+    hint: true,
+    highlight: true
+  }, {
+    source: function (query, callback) {
+      callback(self.getAutocomplete(query.toLowerCase()));
+    }
+  });
+
+  $(searchInput).on('typeahead:select', function () {
+    searchByQuery();
+  });
+
+  self.getOverlayDb().addListener("onSearch", function () {
+    return self.refreshSearchResults();
+  });
+
+  self.getOverlayDb().addListener("onClear", function () {
+    searchInput.value = "";
+  });
+
+};
+
+AbstractDbPanel.prototype._initializeGui = function (placeholder) {
+  var searchQueryDiv = Functions.createElement({
+    type: "div",
+    name: "searchQuery",
+    className: "searchPanel"
+  });
+  this.getElement().appendChild(searchQueryDiv);
+  this.setControlElement(PanelControlElementType.SEARCH_DIV, searchQueryDiv);
+
+  var busyImage = Functions.createElement({
+    type: "img",
+    name: "busyImage",
+    style: "display:block;position: absolute;margin-left: 80px;z-index: 10;display:none",
+    src: "resources/images/icons/ajax-loader.gif"
+  });
+  searchQueryDiv.appendChild(busyImage);
+
+  var searchLabel = Functions.createElement({
+    type: "div",
+    name: "searchLabel",
+    content: "SEARCH:"
+  });
+  searchQueryDiv.appendChild(searchLabel);
+  this.setControlElement(PanelControlElementType.SEARCH_LABEL, searchLabel);
+
+  var searchInputDiv = Functions.createElement({
+    type: "table"
+  });
+  searchQueryDiv.appendChild(searchInputDiv);
+
+  var searchInputRow = Functions.createElement({
+    type: "tr"
+  });
+  searchInputDiv.appendChild(searchInputRow);
+
+  var searchInputCell = Functions.createElement({
+    type: "td"
+  });
+  searchInputRow.appendChild(searchInputCell);
+
+  var searchInput = Functions.createElement({
+    type: "input",
+    name: "searchInput",
+    className: "input-field typeahead"
+  });
+  if (placeholder !== undefined) {
+    searchInput.placeholder = placeholder;
+  }
+  searchInputCell.appendChild(searchInput);
+  this.setControlElement(PanelControlElementType.SEARCH_INPUT, searchInput);
+
+  var searchButtonCell = Functions.createElement({
+    type: "td"
+  });
+  searchInputRow.appendChild(searchButtonCell);
+
+  var searchButton = Functions.createElement({
+    type: "a",
+    content: '<img src="resources/images/icons/search.png"/>',
+    xss: false
+  });
+  searchButton.href = "#";
+  searchButtonCell.appendChild(searchButton);
+  this.setControlElement(PanelControlElementType.SEARCH_BUTTON, searchButton);
+
+  var searchResultsDiv = Functions.createElement({
+    type: "div",
+    name: "searchResults",
+    className: "tabbable boxed parentTabs"
+  });
+  this.getElement().appendChild(searchResultsDiv);
+  this.setControlElement(PanelControlElementType.SEARCH_RESULTS_DIV, searchResultsDiv);
+
+  var searchResultsNavTabDiv = Functions.createElement({
+    type: "ul",
+    className: "nav nav-tabs",
+    content: '<li class="active"><a href="#set1"/></li>',
+    xss: false
+  });
+  searchResultsDiv.appendChild(searchResultsNavTabDiv);
+  this.setControlElement(PanelControlElementType.SEARCH_RESULTS_NAV_TAB, searchResultsNavTabDiv);
+
+  var searchResultsContentTabDiv = Functions.createElement({
+    type: "div",
+    className: "tab-content",
+    content: '<div class="tab-pane fade active in" name="set1" id="set1"/>',
+    xss: false
+  });
+  searchResultsDiv.appendChild(searchResultsContentTabDiv);
+  this.setControlElement(PanelControlElementType.SEARCH_RESULTS_CONTENT_TAB, searchResultsContentTabDiv);
+
+};
+
+AbstractDbPanel.prototype.setOverlayDb = function (overlayDb) {
+  if (overlayDb === undefined) {
+    throw new Error("Undefined overlayDb for panel: " + this.getPanelName());
+  }
+  this._overlayDb = overlayDb;
+};
+
+/**
+ *
+ * @returns {AbstractDbOverlay}
+ */
+AbstractDbPanel.prototype.getOverlayDb = function () {
+  return this._overlayDb;
+};
+
+AbstractDbPanel.prototype.clearResults = function () {
+  var navElement = this.getControlElement(PanelControlElementType.SEARCH_RESULTS_NAV_TAB);
+  while (navElement.firstChild) {
+    navElement.removeChild(navElement.firstChild);
+  }
+
+  var contentElement = this.getControlElement(PanelControlElementType.SEARCH_RESULTS_CONTENT_TAB);
+  while (contentElement.firstChild) {
+    contentElement.removeChild(contentElement.firstChild);
+  }
+};
+
+AbstractDbPanel.prototype.refreshSearchResults = function () {
+  var self = this;
+  self.clearResults();
+  var searchDb = self.getOverlayDb();
+  var queries = searchDb.getQueries();
+
+  var promises = [];
+  for (var i = 0; i < queries.length; i++) {
+    promises.push(searchDb.getElementsByQuery(queries[i]));
+  }
+  return Promise.all(promises).then(function (results) {
+    return Promise.each(queries, function(query, index){
+      return self.addResultTab(query, results[index]);
+    });
+  }).then(function(){
+    self.onresize();
+  });
+};
+
+AbstractDbPanel.prototype.getAutocomplete = function () {
+  logger.warn("Get autocomplete not implemented");
+};
+
+AbstractDbPanel.prototype.searchByQuery = function () {
+  throw new Error("searchByQuery is not implemented");
+};
+
+AbstractDbPanel.prototype.addResultTab = function (query, elements) {
+  var self = this;
+  var name = JSON.parse(query).query;
+
+  var tabId = this.getPanelName() + "Tab_" + this._tabIdCount;
+  this._tabIdCount++;
+
+  var navElement = this.getControlElement(PanelControlElementType.SEARCH_RESULTS_NAV_TAB);
+  var contentElement = this.getControlElement(PanelControlElementType.SEARCH_RESULTS_CONTENT_TAB);
+  var navClass = '';
+  var contentClass = 'tab-pane';
+  if (navElement.children.length === 0) {
+    navClass = "active";
+    contentClass = "tab-pane active";
+  }
+
+  var navLi = document.createElement("li");
+  navLi.className = navClass;
+
+  var navLink = Functions.createElement({
+    type: "a",
+    href: "#" + tabId,
+    onclick: function () {
+      $(this).tab('show');
+    }
+  });
+  if (name !== undefined) {
+    if (name.length > 12) {
+      name = name.substring(0, 10) + "...";
+    }
+    navLink.innerHTML = name;
+  }
+  navLi.appendChild(navLink);
+  if (query.name !== undefined) {
+    navLink.innerHTML = query.name;
+  }
+  navElement.appendChild(navLi);
+
+  var contentDiv = document.createElement("div");
+  contentDiv.className = "pre-scrollable " + contentClass;
+  contentDiv.style.maxHeight = "10px";
+
+  contentDiv.id = tabId;
+
+  contentElement.appendChild(contentDiv);
+
+  contentDiv.appendChild(this.createPreamble(elements.element));
+
+  var tableDiv = document.createElement("table");
+  tableDiv.className = "table table-bordered";
+  contentDiv.appendChild(tableDiv);
+  var tableBody = document.createElement("tbody");
+  tableDiv.appendChild(tableBody);
+
+  return Promise.each(elements, function (entry) {
+    var element = entry.element;
+    var icon = entry.icon;
+    return self.createTableElement(element, icon).then(function (div) {
+      return tableBody.appendChild(div);
+    });
+  });
+};
+
+/**
+ *
+ * @returns {Promise<HTMLTableRowElement>}
+ */
+AbstractDbPanel.prototype.createTableElement = function () {
+  throw new Error("Not implemented");
+};
+
+/**
+ *
+ * @param {Target} target
+ * @param {string} icon
+ * @returns {Promise<HTMLTableRowElement>}
+ */
+AbstractDbPanel.prototype.createTargetRow = function (target, icon) {
+  var self = this;
+  var guiUtils = self.getGuiUtils();
+  var result = document.createElement("tr");
+  var iconColumn = document.createElement("td");
+  iconColumn.style.width = "20px";
+  iconColumn.style.verticalAlign = "middle";
+  iconColumn.style.textAlign = "center";
+  result.appendChild(iconColumn);
+  var submaps = [];
+  var i;
+  if (target.getTargetElements().length > 0) {
+    var submapAddedIds = [];
+    iconColumn.appendChild(guiUtils.createIcon(icon));
+    var checkbox = document.createElement('input');
+    checkbox.type = "checkbox";
+    checkbox.checked = target.isVisible();
+    checkbox.onclick = function () {
+      target.setIsVisible(!target.isVisible());
+      self.getOverlayDb().callListeners("onTargetVisibilityChange");
+    };
+
+    iconColumn.appendChild(checkbox);
+    var elements = target.getTargetElements();
+    for (i = 0; i < elements.length; i++) {
+      var elementId = elements[i].getModelId();
+      if (elementId !== self.getMap().getId() && !submapAddedIds[elementId]) {
+        submaps.push(elementId);
+        submapAddedIds[elementId] = true;
+      }
+    }
+  }
+
+  var descColumn = document.createElement("td");
+  result.appendChild(descColumn);
+
+  descColumn.appendChild(guiUtils.createParamLine("Name: ", target.getName()));
+  descColumn.appendChild(guiUtils.createAnnotations("Elements: ", target.getTargetParticipants(), {
+    showType: false,
+    inline: true,
+    groupAnnotations: false
+  }));
+  descColumn.appendChild(guiUtils.createAnnotations("References: ", target.getReferences(), {
+    showType: false,
+    groupAnnotations: false
+  }));
+  if (submaps.length > 0) {
+    descColumn.appendChild(guiUtils.createLabel("Available in submaps: "));
+    for (i = 0; i < submaps.length; i++) {
+      var model = self.getMap().getSubmapById(submaps[i]).getModel();
+      var onclick = (function () {
+        var id = model.getId();
+        return function () {
+          self.getMap().openSubmap(id);
+        };
+      }());
+      var button = Functions.createElement({
+        type: "button",
+        className: "minerva-open-submap-button",
+        content: model.getName(),
+        onclick: onclick
+      });
+      descColumn.appendChild(button);
+    }
+  }
+  return Promise.resolve(result);
+};
+
+AbstractDbPanel.prototype.computeAutocompleteDictionary = function (queries) {
+  var result = {};
+
+  var i, j, k, mainString, substring, list;
+  //compute dict for prefixes
+  for (i = 0; i < queries.length; i++) {
+    mainString = queries[i].toLowerCase();
+    for (j = 0; j < mainString.length; j++) {
+      substring = mainString.substring(0, j + 1);
+      if (result[substring] !== undefined) {
+        continue;
+      }
+
+      list = [];
+      for (k = 0; k < 5; k++) {
+        if (k + i >= queries.length) {
+          break;
+        } else if (queries[k + i].toLowerCase().indexOf(substring.toLowerCase()) === 0) {
+          list.push(queries[k + i]);
+        }
+      }
+
+      result[substring] = list;
+    }
+  }
+
+  //and now we add substring from inside
+  for (i = 0; i < queries.length; i++) {
+    mainString = queries[i].toLowerCase();
+    for (var startSubstring = 1; startSubstring < mainString.length; startSubstring++) {
+      for (var endSubstring = startSubstring + 1; endSubstring <= mainString.length; endSubstring++) {
+        substring = mainString.substring(startSubstring, endSubstring);
+        if (mainString.indexOf(substring) !== 0) {
+          if (result[substring] === undefined) {
+            result[substring] = [];
+          }
+          if (result[substring].length < 5) {
+            var found = false;
+            for (k = 0; k < result[substring].length; k++) {
+              found |= result[substring][k] === mainString;
+            }
+            if (!found) {
+              result[substring].push(mainString);
+            }
+          }
+        }
+      }
+    }
+  }
+
+  return result;
+};
+
+
+module.exports = AbstractDbPanel;
diff --git a/frontend-js/src/main/js/gui/leftPanel/ChemicalPanel.js b/frontend-js/src/main/js/gui/leftPanel/ChemicalPanel.js
index 579599f37bf08ff04d7f457a460cc08dd3077123..3a72aec79e68944c957934608a452687ff4752a3 100644
--- a/frontend-js/src/main/js/gui/leftPanel/ChemicalPanel.js
+++ b/frontend-js/src/main/js/gui/leftPanel/ChemicalPanel.js
@@ -1,121 +1,121 @@
-"use strict";
-
-var Promise = require("bluebird");
-
-/* exported logger */
-// noinspection JSUnusedLocalSymbols
-var logger = require('../../logger');
-
-var AbstractDbPanel = require('./AbstractDbPanel');
-var PanelControlElementType = require('../PanelControlElementType');
-
-/**
- *
- * @param params
- * @constructor
- * @extends AbstractDbPanel
- */
-function ChemicalPanel(params) {
-  var self = this;
-  params.panelName = "chemical";
-  params.placeholder = "full chemical name (CTD)";
-
-
-  AbstractDbPanel.call(self, params);
-
-  if (self.getMap().getProject().getDisease() === undefined) {
-    self.disablePanel("The Comparative Toxicogenomics Database (CTD) requires a disease context. " +
-      "Choose an appropriate MeSH code and provide it in the via the Admin section of this MINERVA platform. " +
-      "See User Manual for more details ");
-  } else {
-    self.getControlElement(PanelControlElementType.SEARCH_LABEL).innerHTML = "SEARCH FOR TARGETS OF:";
-  }
-}
-
-ChemicalPanel.prototype = Object.create(AbstractDbPanel.prototype);
-ChemicalPanel.prototype.constructor = ChemicalPanel;
-
-ChemicalPanel.prototype.createPreamble = function (chemical) {
-  var self = this;
-  var guiUtils = self.getGuiUtils();
-  var result = document.createElement("div");
-  if (chemical === undefined || chemical.getName() === undefined) {
-    result.appendChild(guiUtils.createLabel("NOT FOUND"));
-  } else {
-    result.appendChild(guiUtils.createParamLine("Chemical: ", chemical.getName()));
-    result.appendChild(guiUtils.createParamLine("Description: ", chemical.getDescription()));
-    result.appendChild(guiUtils.createArrayParamLine("Synonyms: ", chemical.getSynonyms()));
-    result.appendChild(guiUtils.createParamLine("Direct Evidence: ", chemical.getDirectEvidence()));
-    result.appendChild(guiUtils
-      .createAnnotations("Direct Evidence Publications: ", chemical.getDirectEvidenceReferences(), {groupAnnotations: false}));
-    result.appendChild(guiUtils.createAnnotations("Sources: ", chemical.getReferences()));
-    result.appendChild(guiUtils.createNewLine());
-  }
-
-  return result;
-};
-
-ChemicalPanel.prototype.createTableElement = function (target, icon) {
-  return this.createTargetRow(target, icon);
-};
-
-ChemicalPanel.prototype.searchByQuery = function () {
-  var self = this;
-  var query = self.getControlElement(PanelControlElementType.SEARCH_INPUT).value;
-
-  return self.getOverlayDb().searchByQuery(query);
-};
-
-ChemicalPanel.prototype.init = function () {
-  var self = this;
-  return self.getToolTipForAnnotation(self.getProject().getDisease()).then(function (toolTip) {
-    self.setHelpTip(toolTip);
-    var query = ServerConnector.getSessionData().getChemicalQuery();
-    if (query !== undefined) {
-      return self.getOverlayDb().searchByEncodedQuery(query);
-    }
-  });
-};
-
-ChemicalPanel.prototype.destroy = function () {
-  return Promise.resolve();
-};
-
-ChemicalPanel.prototype.getAutocomplete = function (query) {
-  if (this._searchAutocomplete === undefined) {
-    this.refreshSearchAutocomplete();
-    return [];
-  }
-
-  return this._searchAutocomplete[query];
-};
-
-ChemicalPanel.prototype.refreshSearchAutocomplete = function () {
-  var self = this;
-  self._searchAutocomplete = [];
-  return ServerConnector.getChemicalSuggestedQueryList().then(function (queries) {
-    self._searchAutocomplete = self.computeAutocompleteDictionary(queries);
-    return self._searchAutocomplete;
-  });
-};
-
-ChemicalPanel.prototype.getToolTipForAnnotation = function (annotation) {
-  var self = this;
-  var promise = Promise.resolve('disease');
-  if (annotation !== null && annotation !== undefined) {
-    promise = ServerConnector.getMesh({id: annotation.getResource()}).then(function (mesh) {
-      return mesh.getName() + " (" + self.getGuiUtils().createAnnotationLink(annotation).outerHTML + ")";
-    });
-  }
-  return promise.then(function (diseaseString) {
-    var result = '<p>source: Comparative Toxicogenomics Database <a target="_ctd" href="http://ctdbase.org/">ctdbase.org</a></p>'
-      + '<p>only associations between genes and chemicals with direct evidence to '
-      + diseaseString + ' are displayed</p>'
-      + '<p>use only the full name of chemicals according to <a target="_ctd_chemicals" href="http://ctdbase.org/voc.go?type=chem"> ctdbase/chem</a> for search</p>'
-      + 'if the chemical name includes comma(s), place a semicolon behind the name to avoid a segmentation of the name</p>'
-      + '<p>separate multiple search by semicolon';
-    return Promise.resolve(result);
-  });
-};
-
-module.exports = ChemicalPanel;
+"use strict";
+
+var Promise = require("bluebird");
+
+/* exported logger */
+// noinspection JSUnusedLocalSymbols
+var logger = require('../../logger');
+
+var AbstractDbPanel = require('./AbstractDbPanel');
+var PanelControlElementType = require('../PanelControlElementType');
+
+/**
+ *
+ * @param params
+ * @constructor
+ * @extends AbstractDbPanel
+ */
+function ChemicalPanel(params) {
+  var self = this;
+  params.panelName = "chemical";
+  params.placeholder = "full chemical name (CTD)";
+
+
+  AbstractDbPanel.call(self, params);
+
+  if (self.getMap().getProject().getDisease() === undefined) {
+    self.disablePanel("The Comparative Toxicogenomics Database (CTD) requires a disease context. " +
+      "Choose an appropriate MeSH code and provide it in the via the Admin section of this MINERVA platform. " +
+      "See User Manual for more details ");
+  } else {
+    self.getControlElement(PanelControlElementType.SEARCH_LABEL).innerHTML = "SEARCH FOR TARGETS OF:";
+  }
+}
+
+ChemicalPanel.prototype = Object.create(AbstractDbPanel.prototype);
+ChemicalPanel.prototype.constructor = ChemicalPanel;
+
+ChemicalPanel.prototype.createPreamble = function (chemical) {
+  var self = this;
+  var guiUtils = self.getGuiUtils();
+  var result = document.createElement("div");
+  if (chemical === undefined || chemical.getName() === undefined) {
+    result.appendChild(guiUtils.createLabel("NOT FOUND"));
+  } else {
+    result.appendChild(guiUtils.createParamLine("Chemical: ", chemical.getName()));
+    result.appendChild(guiUtils.createParamLine("Description: ", chemical.getDescription()));
+    result.appendChild(guiUtils.createArrayParamLine("Synonyms: ", chemical.getSynonyms()));
+    result.appendChild(guiUtils.createParamLine("Direct Evidence: ", chemical.getDirectEvidence()));
+    result.appendChild(guiUtils
+      .createAnnotations("Direct Evidence Publications: ", chemical.getDirectEvidenceReferences(), {groupAnnotations: false}));
+    result.appendChild(guiUtils.createAnnotations("Sources: ", chemical.getReferences()));
+    result.appendChild(guiUtils.createNewLine());
+  }
+
+  return result;
+};
+
+ChemicalPanel.prototype.createTableElement = function (target, icon) {
+  return this.createTargetRow(target, icon);
+};
+
+ChemicalPanel.prototype.searchByQuery = function () {
+  var self = this;
+  var query = self.getControlElement(PanelControlElementType.SEARCH_INPUT).value;
+
+  return self.getOverlayDb().searchByQuery(query);
+};
+
+ChemicalPanel.prototype.init = function () {
+  var self = this;
+  return self.getToolTipForAnnotation(self.getProject().getDisease()).then(function (toolTip) {
+    self.setHelpTip(toolTip);
+    var query = ServerConnector.getSessionData().getChemicalQuery();
+    if (query !== undefined) {
+      return self.getOverlayDb().searchByEncodedQuery(query);
+    }
+  });
+};
+
+ChemicalPanel.prototype.destroy = function () {
+  return Promise.resolve();
+};
+
+ChemicalPanel.prototype.getAutocomplete = function (query) {
+  if (this._searchAutocomplete === undefined) {
+    this.refreshSearchAutocomplete();
+    return [];
+  }
+
+  return this._searchAutocomplete[query];
+};
+
+ChemicalPanel.prototype.refreshSearchAutocomplete = function () {
+  var self = this;
+  self._searchAutocomplete = [];
+  return ServerConnector.getChemicalSuggestedQueryList().then(function (queries) {
+    self._searchAutocomplete = self.computeAutocompleteDictionary(queries);
+    return self._searchAutocomplete;
+  });
+};
+
+ChemicalPanel.prototype.getToolTipForAnnotation = function (annotation) {
+  var self = this;
+  var promise = Promise.resolve('disease');
+  if (annotation !== null && annotation !== undefined) {
+    promise = ServerConnector.getMesh({id: annotation.getResource()}).then(function (mesh) {
+      return mesh.getName() + " (" + self.getGuiUtils().createAnnotationLink(annotation).outerHTML + ")";
+    });
+  }
+  return promise.then(function (diseaseString) {
+    var result = '<p>source: Comparative Toxicogenomics Database <a target="_ctd" href="http://ctdbase.org/">ctdbase.org</a></p>'
+      + '<p>only associations between genes and chemicals with direct evidence to '
+      + diseaseString + ' are displayed</p>'
+      + '<p>use only the full name of chemicals according to <a target="_ctd_chemicals" href="http://ctdbase.org/voc.go?type=chem"> ctdbase/chem</a> for search</p>'
+      + 'if the chemical name includes comma(s), place a semicolon behind the name to avoid a segmentation of the name</p>'
+      + '<p>separate multiple search by semicolon';
+    return Promise.resolve(result);
+  });
+};
+
+module.exports = ChemicalPanel;
diff --git a/frontend-js/src/main/js/gui/leftPanel/DrugPanel.js b/frontend-js/src/main/js/gui/leftPanel/DrugPanel.js
index ee96cfe765e6810c7b0c462c661f0e075dcdabf3..d2b5c8447d7b1131e23521adfdf5487530816edc 100644
--- a/frontend-js/src/main/js/gui/leftPanel/DrugPanel.js
+++ b/frontend-js/src/main/js/gui/leftPanel/DrugPanel.js
@@ -1,97 +1,97 @@
-"use strict";
-
-var Promise = require("bluebird");
-
-/* exported logger */
-var logger = require('../../logger');
-
-var AbstractDbPanel = require('./AbstractDbPanel');
-var PanelControlElementType = require('../PanelControlElementType');
-
-/**
- *
- * @param params
- * @constructor
- * @extends AbstractDbPanel
- */
-function DrugPanel(params) {
-  params.panelName = "drug";
-  params.helpTip = '<p>source: <a target="_drugbank" href="http://www.drugbank.ca/">DrugBank</a> and '
-    + '<a target="_drugbank" href="https://www.ebi.ac.uk/chembl/">ChEMBL</a></p>'
-    + "<p>use of drug names, synonyms and brand names is supported<p>separate multiple search by semicolon</p>";
-  params.placeholder = "drug, synonym, brand name";
-
-  AbstractDbPanel.call(this, params);
-  var self = this;
-  self.getControlElement(PanelControlElementType.SEARCH_LABEL).innerHTML = "SEARCH FOR TARGETS OF:";
-}
-
-DrugPanel.prototype = Object.create(AbstractDbPanel.prototype);
-DrugPanel.prototype.constructor = DrugPanel;
-
-/**
- *
- * @param {Drug} drug
- * @returns {HTMLDivElement}
- */
-DrugPanel.prototype.createPreamble = function (drug) {
-  var self = this;
-  var guiUtils = self.getGuiUtils();
-  var result = document.createElement("div");
-  if (drug === undefined || drug.getName() === undefined) {
-    result.appendChild(guiUtils.createLabel("NOT FOUND"));
-  } else {
-    result.appendChild(guiUtils.createParamLine("Drug: ", drug.getName()));
-    result.appendChild(guiUtils.createParamLine("Description: ", drug.getDescription()));
-    result.appendChild(guiUtils.createArrayParamLine("Synonyms: ", drug.getSynonyms()));
-    result.appendChild(guiUtils.createArrayParamLine("Brand names: ", drug.getBrandNames()));
-    result.appendChild(guiUtils.createParamLine("Blood brain barrier: ", drug.getBloodBrainBarrier()));
-    result.appendChild(guiUtils.createAnnotations("Sources: ", drug.getReferences(), {groupAnnotations: false}));
-    result.appendChild(guiUtils.createNewLine());
-  }
-
-  return result;
-};
-
-DrugPanel.prototype.createTableElement = function (target, icon) {
-  return this.createTargetRow(target, icon);
-};
-
-DrugPanel.prototype.searchByQuery = function () {
-  var self = this;
-  var query = self.getControlElement(PanelControlElementType.SEARCH_INPUT).value;
-  return self.getOverlayDb().searchByQuery(query);
-};
-
-DrugPanel.prototype.init = function () {
-  var query = ServerConnector.getSessionData().getDrugQuery();
-  if (query !== undefined) {
-    return this.getOverlayDb().searchByEncodedQuery(query);
-  } else {
-    return Promise.resolve();
-  }
-};
-
-DrugPanel.prototype.destroy = function () {
-  return Promise.resolve();
-};
-
-DrugPanel.prototype.getAutocomplete = function (query) {
-  if (this._searchAutocomplete === undefined) {
-    this.refreshSearchAutocomplete();
-    return [];
-  }
-
-  return this._searchAutocomplete[query];
-};
-
-DrugPanel.prototype.refreshSearchAutocomplete = function () {
-  var self = this;
-  self._searchAutocomplete = [];
-  return ServerConnector.getDrugSuggestedQueryList().then(function (queries) {
-    self._searchAutocomplete = self.computeAutocompleteDictionary(queries);
-    return self._searchAutocomplete;
-  });
-};
-
-module.exports = DrugPanel;
+"use strict";
+
+var Promise = require("bluebird");
+
+/* exported logger */
+var logger = require('../../logger');
+
+var AbstractDbPanel = require('./AbstractDbPanel');
+var PanelControlElementType = require('../PanelControlElementType');
+
+/**
+ *
+ * @param params
+ * @constructor
+ * @extends AbstractDbPanel
+ */
+function DrugPanel(params) {
+  params.panelName = "drug";
+  params.helpTip = '<p>source: <a target="_drugbank" href="http://www.drugbank.ca/">DrugBank</a> and '
+    + '<a target="_drugbank" href="https://www.ebi.ac.uk/chembl/">ChEMBL</a></p>'
+    + "<p>use of drug names, synonyms and brand names is supported<p>separate multiple search by semicolon</p>";
+  params.placeholder = "drug, synonym, brand name";
+
+  AbstractDbPanel.call(this, params);
+  var self = this;
+  self.getControlElement(PanelControlElementType.SEARCH_LABEL).innerHTML = "SEARCH FOR TARGETS OF:";
+}
+
+DrugPanel.prototype = Object.create(AbstractDbPanel.prototype);
+DrugPanel.prototype.constructor = DrugPanel;
+
+/**
+ *
+ * @param {Drug} drug
+ * @returns {HTMLDivElement}
+ */
+DrugPanel.prototype.createPreamble = function (drug) {
+  var self = this;
+  var guiUtils = self.getGuiUtils();
+  var result = document.createElement("div");
+  if (drug === undefined || drug.getName() === undefined) {
+    result.appendChild(guiUtils.createLabel("NOT FOUND"));
+  } else {
+    result.appendChild(guiUtils.createParamLine("Drug: ", drug.getName()));
+    result.appendChild(guiUtils.createParamLine("Description: ", drug.getDescription()));
+    result.appendChild(guiUtils.createArrayParamLine("Synonyms: ", drug.getSynonyms()));
+    result.appendChild(guiUtils.createArrayParamLine("Brand names: ", drug.getBrandNames()));
+    result.appendChild(guiUtils.createParamLine("Blood brain barrier: ", drug.getBloodBrainBarrier()));
+    result.appendChild(guiUtils.createAnnotations("Sources: ", drug.getReferences(), {groupAnnotations: false}));
+    result.appendChild(guiUtils.createNewLine());
+  }
+
+  return result;
+};
+
+DrugPanel.prototype.createTableElement = function (target, icon) {
+  return this.createTargetRow(target, icon);
+};
+
+DrugPanel.prototype.searchByQuery = function () {
+  var self = this;
+  var query = self.getControlElement(PanelControlElementType.SEARCH_INPUT).value;
+  return self.getOverlayDb().searchByQuery(query);
+};
+
+DrugPanel.prototype.init = function () {
+  var query = ServerConnector.getSessionData().getDrugQuery();
+  if (query !== undefined) {
+    return this.getOverlayDb().searchByEncodedQuery(query);
+  } else {
+    return Promise.resolve();
+  }
+};
+
+DrugPanel.prototype.destroy = function () {
+  return Promise.resolve();
+};
+
+DrugPanel.prototype.getAutocomplete = function (query) {
+  if (this._searchAutocomplete === undefined) {
+    this.refreshSearchAutocomplete();
+    return [];
+  }
+
+  return this._searchAutocomplete[query];
+};
+
+DrugPanel.prototype.refreshSearchAutocomplete = function () {
+  var self = this;
+  self._searchAutocomplete = [];
+  return ServerConnector.getDrugSuggestedQueryList().then(function (queries) {
+    self._searchAutocomplete = self.computeAutocompleteDictionary(queries);
+    return self._searchAutocomplete;
+  });
+};
+
+module.exports = DrugPanel;
diff --git a/frontend-js/src/main/js/gui/leftPanel/GenericSearchPanel.js b/frontend-js/src/main/js/gui/leftPanel/GenericSearchPanel.js
index e1b3d6fa419a879bf18c388d3bebeafea431b6ae..cb400d39b6b2e80471713333a89a548c0afb8280 100644
--- a/frontend-js/src/main/js/gui/leftPanel/GenericSearchPanel.js
+++ b/frontend-js/src/main/js/gui/leftPanel/GenericSearchPanel.js
@@ -1,179 +1,179 @@
-"use strict";
-
-var Promise = require("bluebird");
-
-/* exported logger */
-
-var AbstractDbPanel = require('./AbstractDbPanel');
-var Alias = require('../../map/data/Alias');
-var InvalidArgumentError = require('../../InvalidArgumentError');
-var PanelControlElementType = require('../PanelControlElementType');
-var Reaction = require('../../map/data/Reaction');
-var SearchBioEntityGroup = require('../../map/data/SearchBioEntityGroup');
-
-// noinspection JSUnusedLocalSymbols
-var logger = require('../../logger');
-var Functions = require('../../Functions');
-
-function GenericSearchPanel(params) {
-  params.panelName = "search";
-  params.helpTip = "<p>search tab allows to search for particular elements or interactions in the map</p>"
-    + "<p>perfect match tick box active: only terms with an exact match to the query will be returned</p>"
-    + "<p>separate multiple search by semicolon</p>";
-  params.placeholder = "keyword";
-
-  AbstractDbPanel.call(this, params);
-
-  this.createSearchGui();
-}
-
-GenericSearchPanel.prototype = Object.create(AbstractDbPanel.prototype);
-GenericSearchPanel.prototype.constructor = GenericSearchPanel;
-
-GenericSearchPanel.prototype.createSearchGui = function () {
-  var searchDiv = this.getControlElement(PanelControlElementType.SEARCH_DIV);
-
-  var perfectMatchCheckbox = Functions.createElement({
-    type: "input",
-    name: "searchPerfectMatch",
-    inputType: "checkbox"
-  });
-  searchDiv.appendChild(perfectMatchCheckbox);
-  this.setControlElement(PanelControlElementType.SEARCH_PERFECT_MATCH_CHECKBOX, perfectMatchCheckbox);
-
-  var perfectMatchLabel = Functions.createElement({
-    type: "span",
-    content: "PERFECT MATCH"
-  });
-  searchDiv.appendChild(perfectMatchLabel);
-};
-
-/**
- *
- * @param {SearchBioEntityGroup|BioEntity} element
- * @param {string} icon
- * @returns {Promise<HTMLTableRowElement>}
- */
-GenericSearchPanel.prototype.createTableElement = function (element, icon) {
-  if (element instanceof Alias) {
-    return this.createAliasElement(element, icon);
-  } else if (element instanceof Reaction) {
-    return this.createReactionElement(element);
-  } else if (element instanceof SearchBioEntityGroup) {
-    return this.createSearchBioEntityGroupElement(element);
-  } else {
-    throw new Error("Unknown element type: " + element.constructor.name);
-  }
-};
-
-GenericSearchPanel.prototype.createPreamble = function () {
-  return document.createElement("div");
-};
-
-/**
- *
- * @param {Reaction} reaction
- * @returns {Promise<HTMLTableRowElement>}
- */
-GenericSearchPanel.prototype.createReactionElement = function (reaction) {
-  var self = this;
-  var guiUtils = self.getGuiUtils();
-  var result = document.createElement("tr");
-  var td = document.createElement("td");
-  result.appendChild(td);
-
-  return guiUtils.createReactionElement({reaction: reaction}).then((function (div) {
-    div.appendChild(guiUtils.createSeparator());
-    td.appendChild(div);
-    return result;
-  }));
-};
-
-/**
- *
- * @param {Alias} alias
- * @param {string} icon
- * @returns {Promise<HTMLTableRowElement>}
- */
-GenericSearchPanel.prototype.createAliasElement = function (alias, icon) {
-  var self = this;
-  var guiUtils = self.getGuiUtils();
-
-  var result = document.createElement("tr");
-  var td = document.createElement("td");
-  result.appendChild(td);
-  return guiUtils.createAliasElement({
-    alias: alias,
-    icon: icon
-  }).then(function (div) {
-    div.appendChild(guiUtils.createSeparator());
-    td.appendChild(div);
-
-    return result;
-  });
-
-};
-
-/**
- *
- * @param {SearchBioEntityGroup} group
- * @returns {Promise<HTMLTableRowElement>}
- */
-GenericSearchPanel.prototype.createSearchBioEntityGroupElement = function (group) {
-  var self = this;
-  var guiUtils = self.getGuiUtils();
-
-  var result = document.createElement("tr");
-  var td = document.createElement("td");
-  result.appendChild(td);
-  return guiUtils.createSearchBioEntityGroupElement(group).then(function (div) {
-    div.appendChild(guiUtils.createSeparator());
-    td.appendChild(div);
-
-    return result;
-  });
-
-};
-
-GenericSearchPanel.prototype.searchByQuery = function () {
-  var self = this;
-  var query = this.getControlElement(PanelControlElementType.SEARCH_INPUT).value;
-  var perfect = this.getControlElement(PanelControlElementType.SEARCH_PERFECT_MATCH_CHECKBOX).checked;
-  return self.getOverlayDb().searchByQuery(query, perfect, true);
-};
-
-GenericSearchPanel.prototype.getAutocomplete = function (query) {
-  if (this._searchAutocomplete === undefined) {
-    this.refreshSearchAutocomplete();
-    return [];
-  }
-
-  return this._searchAutocomplete[query];
-};
-
-GenericSearchPanel.prototype.refreshSearchAutocomplete = function () {
-  var self = this;
-  self._searchAutocomplete = [];
-  return ServerConnector.getSuggestedQueryList().then(function (queries) {
-    self._searchAutocomplete = self.computeAutocompleteDictionary(queries);
-    return self._searchAutocomplete;
-  });
-};
-
-GenericSearchPanel.prototype.init = function () {
-  var query = ServerConnector.getSessionData().getSearchQuery();
-  if (query !== undefined) {
-    return this.getOverlayDb().searchByEncodedQuery(query, false).catch(function (error) {
-      if (error instanceof InvalidArgumentError) {
-        logger.warn(error.message);
-      } else {
-        throw error;
-      }
-    });
-  } else {
-    return Promise.resolve();
-  }
-};
-
-
-module.exports = GenericSearchPanel;
+"use strict";
+
+var Promise = require("bluebird");
+
+/* exported logger */
+
+var AbstractDbPanel = require('./AbstractDbPanel');
+var Alias = require('../../map/data/Alias');
+var InvalidArgumentError = require('../../InvalidArgumentError');
+var PanelControlElementType = require('../PanelControlElementType');
+var Reaction = require('../../map/data/Reaction');
+var SearchBioEntityGroup = require('../../map/data/SearchBioEntityGroup');
+
+// noinspection JSUnusedLocalSymbols
+var logger = require('../../logger');
+var Functions = require('../../Functions');
+
+function GenericSearchPanel(params) {
+  params.panelName = "search";
+  params.helpTip = "<p>search tab allows to search for particular elements or interactions in the map</p>"
+    + "<p>perfect match tick box active: only terms with an exact match to the query will be returned</p>"
+    + "<p>separate multiple search by semicolon</p>";
+  params.placeholder = "keyword";
+
+  AbstractDbPanel.call(this, params);
+
+  this.createSearchGui();
+}
+
+GenericSearchPanel.prototype = Object.create(AbstractDbPanel.prototype);
+GenericSearchPanel.prototype.constructor = GenericSearchPanel;
+
+GenericSearchPanel.prototype.createSearchGui = function () {
+  var searchDiv = this.getControlElement(PanelControlElementType.SEARCH_DIV);
+
+  var perfectMatchCheckbox = Functions.createElement({
+    type: "input",
+    name: "searchPerfectMatch",
+    inputType: "checkbox"
+  });
+  searchDiv.appendChild(perfectMatchCheckbox);
+  this.setControlElement(PanelControlElementType.SEARCH_PERFECT_MATCH_CHECKBOX, perfectMatchCheckbox);
+
+  var perfectMatchLabel = Functions.createElement({
+    type: "span",
+    content: "PERFECT MATCH"
+  });
+  searchDiv.appendChild(perfectMatchLabel);
+};
+
+/**
+ *
+ * @param {SearchBioEntityGroup|BioEntity} element
+ * @param {string} icon
+ * @returns {Promise<HTMLTableRowElement>}
+ */
+GenericSearchPanel.prototype.createTableElement = function (element, icon) {
+  if (element instanceof Alias) {
+    return this.createAliasElement(element, icon);
+  } else if (element instanceof Reaction) {
+    return this.createReactionElement(element);
+  } else if (element instanceof SearchBioEntityGroup) {
+    return this.createSearchBioEntityGroupElement(element);
+  } else {
+    throw new Error("Unknown element type: " + element.constructor.name);
+  }
+};
+
+GenericSearchPanel.prototype.createPreamble = function () {
+  return document.createElement("div");
+};
+
+/**
+ *
+ * @param {Reaction} reaction
+ * @returns {Promise<HTMLTableRowElement>}
+ */
+GenericSearchPanel.prototype.createReactionElement = function (reaction) {
+  var self = this;
+  var guiUtils = self.getGuiUtils();
+  var result = document.createElement("tr");
+  var td = document.createElement("td");
+  result.appendChild(td);
+
+  return guiUtils.createReactionElement({reaction: reaction}).then((function (div) {
+    div.appendChild(guiUtils.createSeparator());
+    td.appendChild(div);
+    return result;
+  }));
+};
+
+/**
+ *
+ * @param {Alias} alias
+ * @param {string} icon
+ * @returns {Promise<HTMLTableRowElement>}
+ */
+GenericSearchPanel.prototype.createAliasElement = function (alias, icon) {
+  var self = this;
+  var guiUtils = self.getGuiUtils();
+
+  var result = document.createElement("tr");
+  var td = document.createElement("td");
+  result.appendChild(td);
+  return guiUtils.createAliasElement({
+    alias: alias,
+    icon: icon
+  }).then(function (div) {
+    div.appendChild(guiUtils.createSeparator());
+    td.appendChild(div);
+
+    return result;
+  });
+
+};
+
+/**
+ *
+ * @param {SearchBioEntityGroup} group
+ * @returns {Promise<HTMLTableRowElement>}
+ */
+GenericSearchPanel.prototype.createSearchBioEntityGroupElement = function (group) {
+  var self = this;
+  var guiUtils = self.getGuiUtils();
+
+  var result = document.createElement("tr");
+  var td = document.createElement("td");
+  result.appendChild(td);
+  return guiUtils.createSearchBioEntityGroupElement(group).then(function (div) {
+    div.appendChild(guiUtils.createSeparator());
+    td.appendChild(div);
+
+    return result;
+  });
+
+};
+
+GenericSearchPanel.prototype.searchByQuery = function () {
+  var self = this;
+  var query = this.getControlElement(PanelControlElementType.SEARCH_INPUT).value;
+  var perfect = this.getControlElement(PanelControlElementType.SEARCH_PERFECT_MATCH_CHECKBOX).checked;
+  return self.getOverlayDb().searchByQuery(query, perfect, true);
+};
+
+GenericSearchPanel.prototype.getAutocomplete = function (query) {
+  if (this._searchAutocomplete === undefined) {
+    this.refreshSearchAutocomplete();
+    return [];
+  }
+
+  return this._searchAutocomplete[query];
+};
+
+GenericSearchPanel.prototype.refreshSearchAutocomplete = function () {
+  var self = this;
+  self._searchAutocomplete = [];
+  return ServerConnector.getSuggestedQueryList().then(function (queries) {
+    self._searchAutocomplete = self.computeAutocompleteDictionary(queries);
+    return self._searchAutocomplete;
+  });
+};
+
+GenericSearchPanel.prototype.init = function () {
+  var query = ServerConnector.getSessionData().getSearchQuery();
+  if (query !== undefined) {
+    return this.getOverlayDb().searchByEncodedQuery(query, false).catch(function (error) {
+      if (error instanceof InvalidArgumentError) {
+        logger.warn(error.message);
+      } else {
+        throw error;
+      }
+    });
+  } else {
+    return Promise.resolve();
+  }
+};
+
+
+module.exports = GenericSearchPanel;
diff --git a/frontend-js/src/main/js/gui/leftPanel/LeftPanel.js b/frontend-js/src/main/js/gui/leftPanel/LeftPanel.js
index 646c317f8edc13bfb5ec7d0355fa6354ca7a92ef..c9777db198c6ddee2f101290246de87fc4beb139 100644
--- a/frontend-js/src/main/js/gui/leftPanel/LeftPanel.js
+++ b/frontend-js/src/main/js/gui/leftPanel/LeftPanel.js
@@ -1,361 +1,361 @@
-"use strict";
-
-var Promise = require("bluebird");
-
-/* exported logger */
-
-var AbstractGuiElement = require('../AbstractGuiElement');
-var AbstractDbOverlay = require('../../map/overlay/AbstractDbOverlay');
-var Alias = require('../../map/data/Alias');
-var GuiUtils = require('./GuiUtils');
-var Header = require('../Header');
-var LoginDialog = require('../LoginDialog');
-var OverlayPanel = require('./OverlayPanel');
-var PointData = require('../../map/data/PointData');
-var ProjectInfoPanel = require('./ProjectInfoPanel');
-var Reaction = require('../../map/data/Reaction');
-var SearchPanel = require('./SearchPanel');
-var SubmapPanel = require('./SubmapPanel');
-
-var Functions = require('../../Functions');
-var logger = require('../../logger');
-
-/**
- *
- * @param {Object} params
- * @param {HTMLElement} params.element
- * @param {CustomMap} params.customMap
- * @param {Configuration} params.configuration
- * @param {Project} [params.project]
- * @param {ServerConnector} [params.serverConnector]
- *
- * @constructor
- *
- * @extends AbstractGuiElement
- */
-function LeftPanel(params) {
-  AbstractGuiElement.call(this, params);
-  var self = this;
-
-  this._tabIdCount = 0;
-  this._panels = [];
-
-  self._createPanelGui();
-
-}
-
-LeftPanel.prototype = Object.create(AbstractGuiElement.prototype);
-LeftPanel.prototype.constructor = LeftPanel;
-
-LeftPanel.prototype._createPanelGui = function () {
-  var self = this;
-  var panels = self.getPanelsDefinition();
-
-  var headerDiv = Functions.createElement({
-    type: "div",
-    id: "headerPanel"
-  });
-  var header = new Header({
-    element: headerDiv,
-    customMap: self.getMap(),
-    optionsMenu: true
-  });
-  self.getElement().appendChild(headerDiv);
-
-  var loginDialogDiv = Functions.createElement({
-    type: "div",
-    name: "loginDialog",
-    style: "display:none"
-  });
-  self.getElement().appendChild(loginDialogDiv);
-  this.setLoginDialog(new LoginDialog({
-    element: loginDialogDiv,
-    customMap: self.getMap()
-  }));
-
-  var guiUtils = self.getGuiUtils();
-  var tabData = guiUtils.createTabDiv({
-    element: self.getElement(),
-    id: "left_panel"
-  });
-
-  self.setHeader(header);
-
-  self.elementInfoDiv = Functions.createElement({
-    name: "elementInfoDiv",
-    type: "div",
-    style: "background-color:#f3f3f3",
-    className: "minerva-element-info-div"
-  });
-
-  for (var i = 0; i < panels.length; i++) {
-    self.addTab(panels[i], tabData);
-  }
-};
-
-LeftPanel.prototype.getPanelsDefinition = function () {
-  return [{
-    name: "SEARCH",
-    className: "fa-search",
-    panelClass: SearchPanel
-  }, {
-    name: "OVERLAYS",
-    className: "fa-th-list",
-    panelClass: OverlayPanel
-  }, {
-    name: "SUBMAPS",
-    className: "fa-sitemap",
-    panelClass: SubmapPanel
-  }, {
-    name: "INFO",
-    className: "fa-info",
-    panelClass: ProjectInfoPanel
-  }];
-};
-
-LeftPanel.prototype.hideTab = function (panel) {
-  var self = this;
-  var panelDefinitions = self.getPanelsDefinition();
-  for (var i = 0; i < panelDefinitions.length; i++) {
-    if (panel instanceof panelDefinitions[i].panelClass) {
-      var liElement = $("li:has(a[data='left_tab_" + i + "'])", $(self.getElement()))[0];
-      if (liElement !== undefined) {
-        liElement.style.display = "none";
-      } else {
-        logger.warn("Cannot find tab link for panel: " + panel.getPanelName());
-      }
-    }
-  }
-};
-
-LeftPanel.prototype.init = function () {
-  var self = this;
-
-  var promises = [];
-  for (var i = 0; i < self._panels.length; i++) {
-    promises.push(self._panels[i].init());
-  }
-  promises.push(self.getHeader().init());
-
-  var initEvents = new Promise(function (resolve) {
-    self.getMap().addListener("onBioEntityClick", function (e) {
-      return self.showElementDetails(e.arg);
-    });
-    self.getMap().getOverlayByName("search").addListener("onSearch", function (e) {
-      if (e.arg.type === AbstractDbOverlay.QueryType.SEARCH_BY_COORDINATES ||
-        e.arg.type === AbstractDbOverlay.QueryType.SEARCH_BY_TARGET) {
-        return self.showElementDetails(e.arg.identifiedElements[0][0]);
-      } else {
-        return self.showElementDetails(undefined);
-      }
-    });
-    resolve();
-  });
-  promises.push(initEvents);
-  promises.push(self.getLoginDialog().init());
-  return Promise.all(promises);
-};
-
-LeftPanel.prototype.showElementDetails = function (element) {
-  var self = this;
-  var div = self.elementInfoDiv;
-  if (!$(div).hasClass("ui-dialog-content")) {
-    $(div).dialog({
-      resizable: false,
-      width: $(self.getElement()).width(),
-      height: 200,
-      beforeclose: function () {
-        $(this).dialog('option', 'position', [$(this).offset().left, $(this).offset().top]);
-        $(this).dialog('option', 'width', $(this).width());
-        $(this).dialog('option', 'height', $(this).height());
-      },
-      position: {
-        my: "left bottom",
-        at: "left bottom",
-        of: $(self.getElement())
-      }
-    }).siblings('.ui-dialog-titlebar').css("background", "gray");
-  }
-
-  var openedTabs = $("[name='tabView'] > ul > li.active > a");
-  var openTabName = openedTabs[0].innerHTML;
-  var searchTabName = openedTabs[1].innerHTML;
-  var isPanelHidden = (self.getElement().style.display === "none");
-  if (isPanelHidden) {
-    openTabName = undefined;
-  }
-
-  if (element !== undefined && openTabName !== undefined && (openTabName.indexOf("SEARCH") === -1 || searchTabName !== "GENERIC")) {
-    var model = self.getMap().getSubmapById(element.getModelId()).getModel();
-    var bioEntity;
-    return model.getByIdentifiedElement(element, true).then(function (result) {
-      bioEntity=result;
-      return self.prepareElementDetailsContent(bioEntity);
-    }).then(function(elementDetailsDiv){
-      div.innerHTML = "";
-      div.appendChild(elementDetailsDiv);
-      $(div).dialog("open");
-      $(div).dialog("option", "title", self.getElementTitle(bioEntity));
-      $(div).scrollTop(0);
-    });
-  } else {
-    $(div).dialog("close");
-    return Promise.resolve();
-  }
-};
-
-/**
- *
- * @param {BioEntity} bioEntity
- *
- * @returns {Promise<HTMLDivElement>}
- */
-LeftPanel.prototype.prepareElementDetailsContent = function (bioEntity) {
-  var guiUtils = this.getGuiUtils();
-  if (bioEntity instanceof Reaction) {
-    return guiUtils.createReactionElement({
-      reaction: bioEntity,
-      showTitle: false
-    });
-  } else if (bioEntity instanceof Alias) {
-    return guiUtils.createAliasElement({
-      alias: bioEntity,
-      showTitle: false
-    });
-  } else if (bioEntity instanceof PointData) {
-    return Promise.resolve(Functions.createElement({
-      type: "div"
-    }));
-  } else {
-    throw new Error("Unknown element type:" + bioEntity);
-  }
-};
-
-/**
- *
- * @returns {GuiUtils}
- */
-LeftPanel.prototype.getGuiUtils = function () {
-  var self = this;
-  if (self._guiUtils === undefined) {
-    self._guiUtils = new GuiUtils(self.getMap().getConfiguration());
-    self._guiUtils.setMap(self.getMap());
-  }
-  return self._guiUtils;
-};
-
-/**
- *
- * @param {BioEntity} bioEntity
- * @returns {string}
- */
-LeftPanel.prototype.getElementTitle = function (bioEntity) {
-  if (bioEntity instanceof Reaction) {
-    return bioEntity.getType() + ": " + bioEntity.getReactionId();
-  } else if (bioEntity instanceof Alias) {
-    return bioEntity.getType() + ": " + bioEntity.getName();
-  } else if (bioEntity instanceof PointData) {
-    return "POINT: " + bioEntity.getId();
-  } else {
-    throw new Error("Unknown element type:" + bioEntity);
-  }
-};
-
-LeftPanel.prototype.addTab = function (params, tabData) {
-  var self = this;
-
-  var name = params.name;
-  if (name !== undefined) {
-    if (name.length > 12) {
-      name = name.substring(0, 10) + "...";
-    }
-  } else {
-    name = "";
-  }
-
-
-  var guiUtils = self.getGuiUtils();
-  var data = guiUtils.createTab({
-    tabData: tabData,
-    title: '<div class="maintabdiv"><i class="fa ' + params.className + ' maintab"></i><br>' + name
-    + '</div>',
-    content: ""
-  });
-
-  $(data.title).attr("data", "left_tab_" + this._panels.length);
-
-  this._panels.push(new params.panelClass({
-    element: data.content,
-    customMap: self.getMap(),
-    configuration: self.getConfiguration(),
-    parent: self
-  }));
-
-};
-
-LeftPanel.prototype.hide = function () {
-  this.getElement().style.display = "none";
-};
-LeftPanel.prototype.show = function () {
-  this.getElement().style.display = "block";
-};
-
-LeftPanel.prototype.setHeader = function (header) {
-  this._header = header;
-};
-
-LeftPanel.prototype.getHeader = function () {
-  return this._header;
-};
-
-LeftPanel.prototype.setLoginDialog = function (loginDialog) {
-  this._loginDialog = loginDialog;
-};
-
-LeftPanel.prototype.getLoginDialog = function () {
-  return this._loginDialog;
-};
-
-LeftPanel.prototype.setPluginManager = function (pluginManager) {
-  this._pluginManager = pluginManager;
-  this.getHeader().setPluginManager(pluginManager);
-};
-
-LeftPanel.prototype.getPluginManager = function () {
-  return this._pluginManager;
-};
-
-LeftPanel.prototype.destroy = function () {
-  var self = this;
-  var promises = [];
-  promises.push(self.getHeader().destroy());
-  var div = self.elementInfoDiv;
-
-  var destroyPanel = new Promise(function (resolve) {
-    if ($(div).hasClass("ui-dialog-content")) {
-      $(div).dialog("destroy");
-    }
-    resolve();
-  });
-  promises.push(destroyPanel);
-  promises.push(self.getLoginDialog().destroy());
-  for (var i = 0; i < self._panels.length; i++) {
-    promises.push(self._panels[i].destroy());
-  }
-
-  if (self._pluginManager !== undefined) {
-    promises.push(self._pluginManager.destroy());
-  }
-
-  return Promise.all(promises);
-};
-
-LeftPanel.prototype.setGoogleLicenseConsentRequired = function (value) {
-  this._googleLicenseConsentRequired = value;
-};
-
-LeftPanel.prototype.isGoogleLicenseConsentRequired = function () {
-  return this._googleLicenseConsentRequired;
-};
-
-module.exports = LeftPanel;
+"use strict";
+
+var Promise = require("bluebird");
+
+/* exported logger */
+
+var AbstractGuiElement = require('../AbstractGuiElement');
+var AbstractDbOverlay = require('../../map/overlay/AbstractDbOverlay');
+var Alias = require('../../map/data/Alias');
+var GuiUtils = require('./GuiUtils');
+var Header = require('../Header');
+var LoginDialog = require('../LoginDialog');
+var OverlayPanel = require('./OverlayPanel');
+var PointData = require('../../map/data/PointData');
+var ProjectInfoPanel = require('./ProjectInfoPanel');
+var Reaction = require('../../map/data/Reaction');
+var SearchPanel = require('./SearchPanel');
+var SubmapPanel = require('./SubmapPanel');
+
+var Functions = require('../../Functions');
+var logger = require('../../logger');
+
+/**
+ *
+ * @param {Object} params
+ * @param {HTMLElement} params.element
+ * @param {CustomMap} params.customMap
+ * @param {Configuration} params.configuration
+ * @param {Project} [params.project]
+ * @param {ServerConnector} [params.serverConnector]
+ *
+ * @constructor
+ *
+ * @extends AbstractGuiElement
+ */
+function LeftPanel(params) {
+  AbstractGuiElement.call(this, params);
+  var self = this;
+
+  this._tabIdCount = 0;
+  this._panels = [];
+
+  self._createPanelGui();
+
+}
+
+LeftPanel.prototype = Object.create(AbstractGuiElement.prototype);
+LeftPanel.prototype.constructor = LeftPanel;
+
+LeftPanel.prototype._createPanelGui = function () {
+  var self = this;
+  var panels = self.getPanelsDefinition();
+
+  var headerDiv = Functions.createElement({
+    type: "div",
+    id: "headerPanel"
+  });
+  var header = new Header({
+    element: headerDiv,
+    customMap: self.getMap(),
+    optionsMenu: true
+  });
+  self.getElement().appendChild(headerDiv);
+
+  var loginDialogDiv = Functions.createElement({
+    type: "div",
+    name: "loginDialog",
+    style: "display:none"
+  });
+  self.getElement().appendChild(loginDialogDiv);
+  this.setLoginDialog(new LoginDialog({
+    element: loginDialogDiv,
+    customMap: self.getMap()
+  }));
+
+  var guiUtils = self.getGuiUtils();
+  var tabData = guiUtils.createTabDiv({
+    element: self.getElement(),
+    id: "left_panel"
+  });
+
+  self.setHeader(header);
+
+  self.elementInfoDiv = Functions.createElement({
+    name: "elementInfoDiv",
+    type: "div",
+    style: "background-color:#f3f3f3",
+    className: "minerva-element-info-div"
+  });
+
+  for (var i = 0; i < panels.length; i++) {
+    self.addTab(panels[i], tabData);
+  }
+};
+
+LeftPanel.prototype.getPanelsDefinition = function () {
+  return [{
+    name: "SEARCH",
+    className: "fa-search",
+    panelClass: SearchPanel
+  }, {
+    name: "OVERLAYS",
+    className: "fa-th-list",
+    panelClass: OverlayPanel
+  }, {
+    name: "SUBMAPS",
+    className: "fa-sitemap",
+    panelClass: SubmapPanel
+  }, {
+    name: "INFO",
+    className: "fa-info",
+    panelClass: ProjectInfoPanel
+  }];
+};
+
+LeftPanel.prototype.hideTab = function (panel) {
+  var self = this;
+  var panelDefinitions = self.getPanelsDefinition();
+  for (var i = 0; i < panelDefinitions.length; i++) {
+    if (panel instanceof panelDefinitions[i].panelClass) {
+      var liElement = $("li:has(a[data='left_tab_" + i + "'])", $(self.getElement()))[0];
+      if (liElement !== undefined) {
+        liElement.style.display = "none";
+      } else {
+        logger.warn("Cannot find tab link for panel: " + panel.getPanelName());
+      }
+    }
+  }
+};
+
+LeftPanel.prototype.init = function () {
+  var self = this;
+
+  var promises = [];
+  for (var i = 0; i < self._panels.length; i++) {
+    promises.push(self._panels[i].init());
+  }
+  promises.push(self.getHeader().init());
+
+  var initEvents = new Promise(function (resolve) {
+    self.getMap().addListener("onBioEntityClick", function (e) {
+      return self.showElementDetails(e.arg);
+    });
+    self.getMap().getOverlayByName("search").addListener("onSearch", function (e) {
+      if (e.arg.type === AbstractDbOverlay.QueryType.SEARCH_BY_COORDINATES ||
+        e.arg.type === AbstractDbOverlay.QueryType.SEARCH_BY_TARGET) {
+        return self.showElementDetails(e.arg.identifiedElements[0][0]);
+      } else {
+        return self.showElementDetails(undefined);
+      }
+    });
+    resolve();
+  });
+  promises.push(initEvents);
+  promises.push(self.getLoginDialog().init());
+  return Promise.all(promises);
+};
+
+LeftPanel.prototype.showElementDetails = function (element) {
+  var self = this;
+  var div = self.elementInfoDiv;
+  if (!$(div).hasClass("ui-dialog-content")) {
+    $(div).dialog({
+      resizable: false,
+      width: $(self.getElement()).width(),
+      height: 200,
+      beforeclose: function () {
+        $(this).dialog('option', 'position', [$(this).offset().left, $(this).offset().top]);
+        $(this).dialog('option', 'width', $(this).width());
+        $(this).dialog('option', 'height', $(this).height());
+      },
+      position: {
+        my: "left bottom",
+        at: "left bottom",
+        of: $(self.getElement())
+      }
+    }).siblings('.ui-dialog-titlebar').css("background", "gray");
+  }
+
+  var openedTabs = $("[name='tabView'] > ul > li.active > a");
+  var openTabName = openedTabs[0].innerHTML;
+  var searchTabName = openedTabs[1].innerHTML;
+  var isPanelHidden = (self.getElement().style.display === "none");
+  if (isPanelHidden) {
+    openTabName = undefined;
+  }
+
+  if (element !== undefined && openTabName !== undefined && (openTabName.indexOf("SEARCH") === -1 || searchTabName !== "GENERIC")) {
+    var model = self.getMap().getSubmapById(element.getModelId()).getModel();
+    var bioEntity;
+    return model.getByIdentifiedElement(element, true).then(function (result) {
+      bioEntity=result;
+      return self.prepareElementDetailsContent(bioEntity);
+    }).then(function(elementDetailsDiv){
+      div.innerHTML = "";
+      div.appendChild(elementDetailsDiv);
+      $(div).dialog("open");
+      $(div).dialog("option", "title", self.getElementTitle(bioEntity));
+      $(div).scrollTop(0);
+    });
+  } else {
+    $(div).dialog("close");
+    return Promise.resolve();
+  }
+};
+
+/**
+ *
+ * @param {BioEntity} bioEntity
+ *
+ * @returns {Promise<HTMLDivElement>}
+ */
+LeftPanel.prototype.prepareElementDetailsContent = function (bioEntity) {
+  var guiUtils = this.getGuiUtils();
+  if (bioEntity instanceof Reaction) {
+    return guiUtils.createReactionElement({
+      reaction: bioEntity,
+      showTitle: false
+    });
+  } else if (bioEntity instanceof Alias) {
+    return guiUtils.createAliasElement({
+      alias: bioEntity,
+      showTitle: false
+    });
+  } else if (bioEntity instanceof PointData) {
+    return Promise.resolve(Functions.createElement({
+      type: "div"
+    }));
+  } else {
+    throw new Error("Unknown element type:" + bioEntity);
+  }
+};
+
+/**
+ *
+ * @returns {GuiUtils}
+ */
+LeftPanel.prototype.getGuiUtils = function () {
+  var self = this;
+  if (self._guiUtils === undefined) {
+    self._guiUtils = new GuiUtils(self.getMap().getConfiguration());
+    self._guiUtils.setMap(self.getMap());
+  }
+  return self._guiUtils;
+};
+
+/**
+ *
+ * @param {BioEntity} bioEntity
+ * @returns {string}
+ */
+LeftPanel.prototype.getElementTitle = function (bioEntity) {
+  if (bioEntity instanceof Reaction) {
+    return bioEntity.getType() + ": " + bioEntity.getReactionId();
+  } else if (bioEntity instanceof Alias) {
+    return bioEntity.getType() + ": " + bioEntity.getName();
+  } else if (bioEntity instanceof PointData) {
+    return "POINT: " + bioEntity.getId();
+  } else {
+    throw new Error("Unknown element type:" + bioEntity);
+  }
+};
+
+LeftPanel.prototype.addTab = function (params, tabData) {
+  var self = this;
+
+  var name = params.name;
+  if (name !== undefined) {
+    if (name.length > 12) {
+      name = name.substring(0, 10) + "...";
+    }
+  } else {
+    name = "";
+  }
+
+
+  var guiUtils = self.getGuiUtils();
+  var data = guiUtils.createTab({
+    tabData: tabData,
+    title: '<div class="maintabdiv"><i class="fa ' + params.className + ' maintab"></i><br>' + name
+    + '</div>',
+    content: ""
+  });
+
+  $(data.title).attr("data", "left_tab_" + this._panels.length);
+
+  this._panels.push(new params.panelClass({
+    element: data.content,
+    customMap: self.getMap(),
+    configuration: self.getConfiguration(),
+    parent: self
+  }));
+
+};
+
+LeftPanel.prototype.hide = function () {
+  this.getElement().style.display = "none";
+};
+LeftPanel.prototype.show = function () {
+  this.getElement().style.display = "block";
+};
+
+LeftPanel.prototype.setHeader = function (header) {
+  this._header = header;
+};
+
+LeftPanel.prototype.getHeader = function () {
+  return this._header;
+};
+
+LeftPanel.prototype.setLoginDialog = function (loginDialog) {
+  this._loginDialog = loginDialog;
+};
+
+LeftPanel.prototype.getLoginDialog = function () {
+  return this._loginDialog;
+};
+
+LeftPanel.prototype.setPluginManager = function (pluginManager) {
+  this._pluginManager = pluginManager;
+  this.getHeader().setPluginManager(pluginManager);
+};
+
+LeftPanel.prototype.getPluginManager = function () {
+  return this._pluginManager;
+};
+
+LeftPanel.prototype.destroy = function () {
+  var self = this;
+  var promises = [];
+  promises.push(self.getHeader().destroy());
+  var div = self.elementInfoDiv;
+
+  var destroyPanel = new Promise(function (resolve) {
+    if ($(div).hasClass("ui-dialog-content")) {
+      $(div).dialog("destroy");
+    }
+    resolve();
+  });
+  promises.push(destroyPanel);
+  promises.push(self.getLoginDialog().destroy());
+  for (var i = 0; i < self._panels.length; i++) {
+    promises.push(self._panels[i].destroy());
+  }
+
+  if (self._pluginManager !== undefined) {
+    promises.push(self._pluginManager.destroy());
+  }
+
+  return Promise.all(promises);
+};
+
+LeftPanel.prototype.setGoogleLicenseConsentRequired = function (value) {
+  this._googleLicenseConsentRequired = value;
+};
+
+LeftPanel.prototype.isGoogleLicenseConsentRequired = function () {
+  return this._googleLicenseConsentRequired;
+};
+
+module.exports = LeftPanel;
diff --git a/frontend-js/src/main/js/gui/leftPanel/MiRnaPanel.js b/frontend-js/src/main/js/gui/leftPanel/MiRnaPanel.js
index db300dedd1e78d52a89be252499282ae54cc8351..eb678ae5a4daa80374ae7b8e8cbd1d04cc5f5e86 100644
--- a/frontend-js/src/main/js/gui/leftPanel/MiRnaPanel.js
+++ b/frontend-js/src/main/js/gui/leftPanel/MiRnaPanel.js
@@ -1,84 +1,84 @@
-"use strict";
-
-var Promise = require("bluebird");
-
-/* exported logger */
-var logger = require('../../logger');
-
-var AbstractDbPanel = require('./AbstractDbPanel');
-var PanelControlElementType = require('../PanelControlElementType');
-
-function MiRnaPanel(params) {
-  params.panelName = "mirna";
-  params.helpTip = '<p>source: <a target="_mirtarbase" href="http://mirtarbase.mbc.nctu.edu.tw/">miRTarBase</a></p>'
-      + '<p>use only mature sequence IDs according to <a target="_mirbase" href="http://www.mirbase.org">www.mirbase.org</a> (e.g., hsa-miR-125a-3p)</p>'
-      + '<p>only targets with strong evidence as defined by miRTarBase are displayed<p>separate multiple search by semicolon</p>';
-  params.placeholder = "mature seq. ID (miRTarBase)";
-  AbstractDbPanel.call(this, params);
-  this.getControlElement(PanelControlElementType.SEARCH_LABEL).innerHTML = "SEARCH FOR TARGETS OF:";
-}
-MiRnaPanel.prototype = Object.create(AbstractDbPanel.prototype);
-MiRnaPanel.prototype.constructor = MiRnaPanel;
-
-MiRnaPanel.prototype.createPreamble = function(miRna) {
-  var self = this;
-  var guiUtils = self.getGuiUtils();
-  var result = document.createElement("div");
-  if (miRna === undefined || miRna.getName() === undefined) {
-    result.appendChild(guiUtils.createLabel("NOT FOUND"));
-  } else {
-    var line = document.createElement("div");
-    line.appendChild(guiUtils.createLabel("MiRNA: "));
-    line.appendChild(guiUtils.createLink("http://www.mirbase.org/cgi-bin/mirna_entry.pl?acc=" + miRna.getName(), miRna
-        .getName()));
-    line.appendChild(guiUtils.createNewLine());
-
-    result.appendChild(line);
-    result.appendChild(guiUtils.createNewLine());
-  }
-
-  return result;
-};
-
-MiRnaPanel.prototype.createTableElement = function(target, icon) {
-  return this.createTargetRow(target, icon);
-};
-
-MiRnaPanel.prototype.searchByQuery = function() {
-  var self = this;
-  var query = self.getControlElement(PanelControlElementType.SEARCH_INPUT).value;
-  return self.getOverlayDb().searchByQuery(query);
-};
-
-MiRnaPanel.prototype.init = function() {
-  var query = ServerConnector.getSessionData().getMiRnaQuery();
-  if (query !== undefined) {
-    return this.getOverlayDb().searchByEncodedQuery(query);
-  } else {
-    return Promise.resolve();
-  }
-};
-
-MiRnaPanel.prototype.destroy = function () {
-    return Promise.resolve();
-};
-
-MiRnaPanel.prototype.getAutocomplete = function (query) {
-  if (this._searchAutocomplete === undefined) {
-    this.refreshSearchAutocomplete();
-    return [];
-  }
-
-  return this._searchAutocomplete[query];
-};
-
-MiRnaPanel.prototype.refreshSearchAutocomplete = function () {
-  var self = this;
-  self._searchAutocomplete = [];
-  return ServerConnector.getMiRnaSuggestedQueryList().then(function (queries) {
-    self._searchAutocomplete = self.computeAutocompleteDictionary(queries);
-    return self._searchAutocomplete;
-  });
-};
-
-module.exports = MiRnaPanel;
+"use strict";
+
+var Promise = require("bluebird");
+
+/* exported logger */
+var logger = require('../../logger');
+
+var AbstractDbPanel = require('./AbstractDbPanel');
+var PanelControlElementType = require('../PanelControlElementType');
+
+function MiRnaPanel(params) {
+  params.panelName = "mirna";
+  params.helpTip = '<p>source: <a target="_mirtarbase" href="http://mirtarbase.mbc.nctu.edu.tw/">miRTarBase</a></p>'
+      + '<p>use only mature sequence IDs according to <a target="_mirbase" href="http://www.mirbase.org">www.mirbase.org</a> (e.g., hsa-miR-125a-3p)</p>'
+      + '<p>only targets with strong evidence as defined by miRTarBase are displayed<p>separate multiple search by semicolon</p>';
+  params.placeholder = "mature seq. ID (miRTarBase)";
+  AbstractDbPanel.call(this, params);
+  this.getControlElement(PanelControlElementType.SEARCH_LABEL).innerHTML = "SEARCH FOR TARGETS OF:";
+}
+MiRnaPanel.prototype = Object.create(AbstractDbPanel.prototype);
+MiRnaPanel.prototype.constructor = MiRnaPanel;
+
+MiRnaPanel.prototype.createPreamble = function(miRna) {
+  var self = this;
+  var guiUtils = self.getGuiUtils();
+  var result = document.createElement("div");
+  if (miRna === undefined || miRna.getName() === undefined) {
+    result.appendChild(guiUtils.createLabel("NOT FOUND"));
+  } else {
+    var line = document.createElement("div");
+    line.appendChild(guiUtils.createLabel("MiRNA: "));
+    line.appendChild(guiUtils.createLink("http://www.mirbase.org/cgi-bin/mirna_entry.pl?acc=" + miRna.getName(), miRna
+        .getName()));
+    line.appendChild(guiUtils.createNewLine());
+
+    result.appendChild(line);
+    result.appendChild(guiUtils.createNewLine());
+  }
+
+  return result;
+};
+
+MiRnaPanel.prototype.createTableElement = function(target, icon) {
+  return this.createTargetRow(target, icon);
+};
+
+MiRnaPanel.prototype.searchByQuery = function() {
+  var self = this;
+  var query = self.getControlElement(PanelControlElementType.SEARCH_INPUT).value;
+  return self.getOverlayDb().searchByQuery(query);
+};
+
+MiRnaPanel.prototype.init = function() {
+  var query = ServerConnector.getSessionData().getMiRnaQuery();
+  if (query !== undefined) {
+    return this.getOverlayDb().searchByEncodedQuery(query);
+  } else {
+    return Promise.resolve();
+  }
+};
+
+MiRnaPanel.prototype.destroy = function () {
+    return Promise.resolve();
+};
+
+MiRnaPanel.prototype.getAutocomplete = function (query) {
+  if (this._searchAutocomplete === undefined) {
+    this.refreshSearchAutocomplete();
+    return [];
+  }
+
+  return this._searchAutocomplete[query];
+};
+
+MiRnaPanel.prototype.refreshSearchAutocomplete = function () {
+  var self = this;
+  self._searchAutocomplete = [];
+  return ServerConnector.getMiRnaSuggestedQueryList().then(function (queries) {
+    self._searchAutocomplete = self.computeAutocompleteDictionary(queries);
+    return self._searchAutocomplete;
+  });
+};
+
+module.exports = MiRnaPanel;
diff --git a/frontend-js/src/main/js/gui/leftPanel/OverlayPanel.js b/frontend-js/src/main/js/gui/leftPanel/OverlayPanel.js
index 862b8f9f46349a84796d866ffea8f3016e8cca71..0a178c5e3008042600a77549ff2ab443b0a34706 100644
--- a/frontend-js/src/main/js/gui/leftPanel/OverlayPanel.js
+++ b/frontend-js/src/main/js/gui/leftPanel/OverlayPanel.js
@@ -1,668 +1,668 @@
-"use strict";
-
-/* exported logger */
-
-var AddOverlayDialog = require('../AddOverlayDialog');
-var Panel = require('../Panel');
-var PanelControlElementType = require('../PanelControlElementType');
-
-var GuiConnector = require('../../GuiConnector');
-// noinspection JSUnusedLocalSymbols
-var logger = require('../../logger');
-var Functions = require('../../Functions');
-
-var Promise = require('bluebird');
-
-/**
- *
- * @param {Object} params
- * @param {HTMLElement} params.element
- * @param {CustomMap} params.customMap
- * @param {Configuration} [params.configuration]
- * @param {Project} [params.project]
- * @param params.parent
- *
- * @constructor
- * @extends Panel
- */
-function OverlayPanel(params) {
-  params["panelName"] = "overlays";
-  params["scrollable"] = true;
-  params["helpTip"] = "<p>Overlays tab allows to display or generate custom coloring of elements and interactions in the map.</p>"
-    + "<p>General overlays are overlays accessible for every user viewing the content.</p>"
-    + "<p>Custom overlays are user-provided overlays, this menu becomes available upon login (see below).</p>";
-  if (params.project === undefined) {
-    params.project = params.customMap.getProject();
-  }
-  Panel.call(this, params);
-
-  //overflow is defined in minerva-overlay-panel, so remove the one that is already there
-  $(params.element).css("overflow", "");
-  $(params.element).addClass("minerva-overlay-panel");
-
-  var self = this;
-
-  self._createOverlayPanelGui();
-
-  var addButton = this.getControlElement(PanelControlElementType.OVERLAY_ADD_OVERLAY_BUTTON);
-
-  addButton.onclick = function () {
-    return self.openAddOverlayDialog();
-  };
-
-  var titleElement = this.getControlElement(PanelControlElementType.OVERLAY_CUSTOM_OVERLAY_TITLE);
-  self.setCustomOverlaysMessage(titleElement.innerHTML);
-
-  $(self.getElement()).on("click", "[name='overlayToggle']", function () {
-    var thisCheckbox = this;
-    var overlayId = $(thisCheckbox).attr("data");
-    var toggleOverlayPromise;
-    if (thisCheckbox.checked) {
-      toggleOverlayPromise = self.getMap().openDataOverlay(overlayId);
-    } else {
-      toggleOverlayPromise = self.getMap().hideDataOverlay(overlayId);
-    }
-    $(thisCheckbox).prop("disabled", true);
-    return toggleOverlayPromise.catch(GuiConnector.alert).finally(function () {
-      $(thisCheckbox).prop("disabled", false);
-    });
-  });
-  $(self.getElement()).on("click", "[name='overlayLink']", function () {
-    var overlayId = $(this).attr("data");
-    return self.getMap().openDataOverlay(overlayId);
-  });
-  self.getMap().addListener("onBackgroundOverlayChange", function (e) {
-    var overlayId = e.arg.toString();
-    var buttons = $("[name='overlayLink']", self.getElement());
-    for (var i = 0; i < buttons.length; i++) {
-      var button = buttons[i];
-      if ($(button).attr("data").toString() === overlayId) {
-        $(button.parentNode.parentNode).addClass('active').siblings().removeClass('active');
-      }
-    }
-  });
-  $(self.getElement()).on("click", "[name='download-overlay']", function () {
-    var overlayId = $(this).attr("data");
-    return self.getServerConnector().getOverlaySourceDownloadUrl({
-      overlayId: overlayId
-    }).then(function (url) {
-      return self.downloadFile(url);
-    }).then(null, GuiConnector.alert);
-  });
-  $(self.getElement()).on("click", "[name='editButton']", function () {
-    var overlayId = $(this).attr("data");
-    return self.getProject().getDataOverlayById(overlayId).then(function (overlay) {
-      return self.openEditOverlayDialog(overlay);
-    });
-  });
-}
-
-OverlayPanel.prototype = Object.create(Panel.prototype);
-OverlayPanel.prototype.constructor = OverlayPanel;
-
-/**
- *
- * @private
- */
-OverlayPanel.prototype._createOverlayPanelGui = function () {
-  var generalOverlaysDiv = Functions.createElement({
-    type: "div",
-    name: "generalOverlays",
-    className: "searchPanel"
-  });
-  this.getElement().appendChild(generalOverlaysDiv);
-  this.setControlElement(PanelControlElementType.OVERLAY_GENERAL_OVERLAY_DIV, generalOverlaysDiv);
-
-  var generalOverlaysTitle = Functions.createElement({
-    type: "h5",
-    content: "GENERAL OVERLAYS:"
-  });
-  generalOverlaysDiv.appendChild(generalOverlaysTitle);
-
-  var generalOverlaysTableDiv = Functions.createElement({
-    type: "table",
-    name: "generalOverlaysTab",
-    className: "table table-bordered",
-    style: "width:100%"
-  });
-  generalOverlaysDiv.appendChild(generalOverlaysTableDiv);
-  this.setControlElement(PanelControlElementType.OVERLAY_GENERAL_OVERLAY_TABLE, generalOverlaysTableDiv);
-
-  var customOverlaysDiv = Functions.createElement({
-    type: "div",
-    name: "customOverlays",
-    className: "searchPanel"
-  });
-  this.getElement().appendChild(customOverlaysDiv);
-  this.setControlElement(PanelControlElementType.OVERLAY_CUSTOM_OVERLAY_DIV, customOverlaysDiv);
-
-  var customOverlaysTitle = Functions.createElement({
-    type: "h5",
-    name: "customOverlaysTitle",
-    content: "USER-PROVIDED OVERLAYS:"
-  });
-  customOverlaysDiv.appendChild(customOverlaysTitle);
-  this.setControlElement(PanelControlElementType.OVERLAY_CUSTOM_OVERLAY_TITLE, customOverlaysTitle);
-
-  var customOverlaysTableDiv = Functions.createElement({
-    type: "table",
-    name: "customOverlaysTab",
-    className: "table table-bordered",
-    style: "width:100%"
-  });
-  customOverlaysDiv.appendChild(customOverlaysTableDiv);
-  this.setControlElement(PanelControlElementType.OVERLAY_CUSTOM_OVERLAY_TABLE, customOverlaysTableDiv);
-
-  var centerTag = Functions.createElement({
-    type: "center"
-  });
-  customOverlaysDiv.appendChild(centerTag);
-
-  var addOverlayButton = Functions.createElement({
-    type: "button",
-    name: "addOverlay",
-    content: "Add overlay"
-  });
-  centerTag.appendChild(addOverlayButton);
-  this.setControlElement(PanelControlElementType.OVERLAY_ADD_OVERLAY_BUTTON, addOverlayButton);
-};
-
-OverlayPanel.prototype.clear = function () {
-  var table = this.getControlElement(PanelControlElementType.OVERLAY_GENERAL_OVERLAY_TABLE);
-  while (table.firstChild) {
-    table.removeChild(table.firstChild);
-  }
-
-  table = $(this.getControlElement(PanelControlElementType.OVERLAY_CUSTOM_OVERLAY_TABLE)).DataTable();
-  table.clear().draw();
-};
-
-/**
- *
- * @param {boolean} [edit=false]
- * @returns {HTMLElement}
- */
-OverlayPanel.prototype.createTableHeader = function (edit) {
-  if (edit === undefined) {
-    edit = false;
-  }
-  var result = document.createElement("thead");
-
-  var row = document.createElement("tr");
-
-  var nameTd = document.createElement("th");
-  nameTd.innerHTML = "Name";
-  row.appendChild(nameTd);
-
-  var viewTd = document.createElement("th");
-  viewTd.innerHTML = "View";
-  row.appendChild(viewTd);
-
-  var dataTd = document.createElement("th");
-  dataTd.innerHTML = "Data";
-  row.appendChild(dataTd);
-
-  if (edit) {
-    var editTd = document.createElement("th");
-    editTd.innerHTML = "Edit";
-    row.appendChild(editTd);
-  }
-
-  result.appendChild(row);
-  return result;
-};
-
-/**
- *
- * @param {DataOverlay} overlay
- * @param {boolean} [checked=false]
- * @param {boolean} [disabled=false]
- * @returns {HTMLElement}
- */
-OverlayPanel.prototype.createOverlayRow = function (overlay, checked, disabled) {
-  var self = this;
-  var guiUtils = self.getGuiUtils();
-  var result = document.createElement("tr");
-
-  if (checked && !overlay.getInputDataAvailable()) {
-    result.className = "active";
-  }
-
-  var nameTd = Functions.createElement({type: "td", content: overlay.getName(), xss: true});
-  result.appendChild(nameTd);
-
-  var viewTd = document.createElement("td");
-  if (overlay.getInputDataAvailable()) {
-    var checkbox = Functions.createElement({
-      type: "input",
-      inputType: "checkbox",
-      name: "overlayToggle",
-      data: overlay.getId()
-    });
-    checkbox.checked = checked;
-    $(checkbox).prop("disabled", disabled);
-    if (disabled) {
-      var warningDiv = Functions.createElement({
-        type: "div",
-        content: "<i class='fa fa-exclamation-triangle' style='font-size:18px; font-weight:400; padding-right:10px;color:orange'></i>",
-        xss: false
-      });
-      warningDiv.title = "You did not consent to terms of the license of Google Maps Platform. Click the \"Edit\" button to do so.";
-      viewTd.appendChild(warningDiv)
-    } else {
-      viewTd.appendChild(checkbox);
-    }
-  } else {
-    var img = guiUtils.createIcon("icons/search.png");
-    var link = Functions.createElement({type: "a", href: "#", name: "overlayLink", data: overlay.getId()});
-    link.appendChild(img);
-    viewTd.appendChild(link);
-  }
-  result.appendChild(viewTd);
-
-  var dataTd = document.createElement("td");
-  if (overlay.getInputDataAvailable()) {
-    var button = Functions.createElement({
-      type: "button",
-      name: "download-overlay",
-      data: overlay.getId(),
-      content: "<span class='ui-icon ui-icon-arrowthickstop-1-s'></span>",
-      xss: false
-    });
-    dataTd.appendChild(button);
-  }
-
-  result.appendChild(dataTd);
-
-  if (overlay.getCreator() !== "" && overlay.getCreator() !== undefined) {
-    var editTd = document.createElement("td");
-    button = Functions.createElement({
-      type: "button",
-      name: "editButton",
-      data: overlay.getId(),
-      content: "<span class='ui-icon ui-icon-document'></span>",
-      xss: false
-    });
-    editTd.appendChild(button);
-    result.appendChild(editTd);
-  }
-  result.title = overlay.getDescription();
-  return result;
-};
-
-/**
- *
- * @param {DataOverlay} overlay
- * @param {boolean} checked
- * @param {boolean} disabled
- * @returns {Array}
- */
-OverlayPanel.prototype.overlayToDataRow = function (overlay, checked, disabled) {
-  var result = [];
-  result[0] = overlay.getOrder();
-  result[1] = overlay.getName();
-
-  if (overlay.getInputDataAvailable()) {
-    if (disabled) {
-      result[2] = "<div title='You did not consent to terms of the license of Google Maps Platform. Click the \"Edit\" button to do so.'>" +
-        "<i class='fa fa-exclamation-triangle' style='font-size:18px; font-weight:400; padding-right:10px;color:orange'></i></div>";
-    } else {
-      var checkedString = "";
-      if (checked) {
-        checkedString = " checked ";
-      }
-      result[2] = "<input type='checkbox' " + checkedString + " data='" + overlay.getId() + "' name='overlayToggle'/>";
-    }
-
-    result[3] = "<button data='" + overlay.getId() + "' name='download-overlay'><span class='ui-icon ui-icon-arrowthickstop-1-s'></span></button>";
-  } else {
-    result[2] = "<a href='#' data='" + overlay.getId() + "' name='overlayLink'><img src='" + GuiConnector.getImgPrefix() + "icons/search.png' style='float: left' hspace='5'/></a>";
-    result[3] = "";
-  }
-
-  if (overlay.getCreator() !== "" && overlay.getCreator() !== undefined) {
-    result[4] = "<button data='" + overlay.getId() + "' name='editButton'><span class='ui-icon ui-icon-document'></span></button>";
-  } else {
-    result[4] = "";
-  }
-  if (overlay.getDescription() !== "") {
-    for (var i = 0; i < result.length; i++) {
-
-      result[i] = "<div class=\"minerva-tooltip\">" + result[i] +
-        "<span class=\"minerva-tooltip-text\">" + overlay.getDescription() + "</span>" +
-        "</div>";
-    }
-  }
-  return result;
-};
-
-/**
- *
- * @param {DataOverlay} overlay
- */
-OverlayPanel.prototype.openEditOverlayDialog = function (overlay) {
-  var self = this;
-  var guiUtils = self.getGuiUtils();
-  var content = document.createElement("fieldset");
-  var nameInput = guiUtils.createInputText(overlay.getName());
-  var row = guiUtils.createTableRow([guiUtils.createLabel("Name: "), nameInput]);
-  content.appendChild(row);
-
-  var descriptionInput = guiUtils.createTextArea(overlay.getDescription());
-  row = guiUtils.createTableRow([guiUtils.createLabel("Description: "), descriptionInput]);
-  content.appendChild(row);
-
-  var consentCheckbox = document.createElement("input");
-  consentCheckbox.type = "checkbox";
-  consentCheckbox.checked = overlay.isGoogleLicenseConsent();
-
-  row = guiUtils.createTableRow([guiUtils.createLabel("I am aware that if this map is displayed using Google Maps API, " +
-    "it falls under their license <a href='https://cloud.google.com/maps-platform/terms/' target='_blank'>" +
-    "https://cloud.google.com/maps-platform/terms/</a>, to which I agree. I warrant that this dataset contains no " +
-    "Protected Health Information (as defined in and subject to HIPAA)."), consentCheckbox]);
-  content.appendChild(row);
-
-  var buttons = [{
-    text: "SAVE",
-    click: function () {
-      var windowSelf = this;
-      overlay.setName(nameInput.value);
-      overlay.setDescription(descriptionInput.value);
-      overlay.setGoogleLicenseConsent(consentCheckbox.checked);
-
-      return self.getServerConnector().updateOverlay(overlay).then(function () {
-        return self.refresh();
-      }).then(function () {
-        $(windowSelf).dialog("close");
-      }).then(null, GuiConnector.alert);
-    }
-  }, {
-    text: "REMOVE",
-    click: function () {
-      var windowSelf = this;
-      return GuiConnector.showConfirmationDialog({
-        message: "Do you want to delete overlay: " + overlay.getName() + "?"
-      }).then(function (confirmation) {
-        if (confirmation) {
-          return self.removeOverlay(overlay).then(function () {
-            $(windowSelf).dialog("close");
-          }).then(null, GuiConnector.alert);
-        }
-      });
-    }
-  }, {
-    text: "CANCEL",
-    click: function () {
-      $(this).dialog("close");
-    }
-  }];
-  self.openDialog(content, {
-    width: "600px",
-    id: overlay.getId(),
-    buttons: buttons,
-    title: "Data overlay: " + overlay.getName(),
-    className: "minerva-overlay-dialog"
-  });
-};
-
-/**
- *
- * @param {boolean} [showDefault=false]
- * @returns {PromiseLike}
- */
-OverlayPanel.prototype.refresh = function (showDefault) {
-  if (showDefault === undefined) {
-    showDefault = false;
-  }
-  var self = this;
-  var user = null;
-
-  var overlayTypes = [];
-  var selectedOverlay = [];
-
-  return self.getServerConnector().getOverlayTypes().then(function (types) {
-    overlayTypes = types;
-    return self.getServerConnector().getLoggedUser();
-  }).then(function (loggedUser) {
-    user = loggedUser;
-    return self.getMap().getVisibleDataOverlays();
-  }).then(function (visibleDataOverlays) {
-    for (var j = 0; j < visibleDataOverlays.length; j++) {
-      selectedOverlay[visibleDataOverlays[j].getId()] = true;
-    }
-
-    return self.getServerConnector().getOverlays({
-      publicOverlay: false,
-      creator: user.getLogin()
-    });
-  }).then(function (customOverlays) {
-
-    if (!showDefault) {
-      var id = self.getMap().getBackgroundDataOverlay().getId();
-      selectedOverlay[id] = true;
-    }
-
-    self.clear();
-
-    var generalOverlays = [];
-    var overlay;
-
-    var overlays = self.getProject().getDataOverlays();
-    for (var i = 0; i < overlays.length; i++) {
-      overlay = overlays[i];
-      if (overlay.getCreator() === undefined || overlay.getCreator() === "") {
-        generalOverlays.push(overlay);
-        if (showDefault && overlay.isDefaultOverlay()) {
-          selectedOverlay[overlay.getId()] = true;
-        }
-      }
-    }
-
-    var table = self.getControlElement(PanelControlElementType.OVERLAY_GENERAL_OVERLAY_TABLE);
-    table.appendChild(self.createTableHeader());
-
-    var body = document.createElement("tbody");
-    table.appendChild(body);
-    for (i = 0; i < generalOverlays.length; i++) {
-      overlay = generalOverlays[i];
-      body.appendChild(self.createOverlayRow(overlay, selectedOverlay[overlay.getId()], false));
-    }
-
-    var title = self.getControlElement(PanelControlElementType.OVERLAY_CUSTOM_OVERLAY_TITLE);
-    var addButton = self.getControlElement(PanelControlElementType.OVERLAY_ADD_OVERLAY_BUTTON);
-    var tableElement = self.getControlElement(PanelControlElementType.OVERLAY_CUSTOM_OVERLAY_TABLE);
-    if (user.getLogin() === "anonymous") {
-      title.innerHTML = 'YOU ARE NOT LOGGED IN. PLEASE, <a href="#">LOG IN</a> '
-        + 'TO UPLOAD AND VIEW CUSTOM OVERLAYS<br/><center><button>LOGIN</button></center>';
-      var openLoginDialog = function () {
-        return self.getParent().getLoginDialog().open();
-      };
-      $(title).find("a")[0].onclick = openLoginDialog;
-      $(title).find("button")[0].onclick = openLoginDialog;
-      addButton.style.display = "none";
-      $(tableElement).hide();
-    } else {
-      $(tableElement).show();
-      title.innerHTML = self.getCustomOverlaysMessage();
-      addButton.style.display = "block";
-
-      table = $(tableElement).on('order.dt', function () {
-        if ($(tableElement).dataTable().fnSettings().aaSorting[0][0] === 0) {
-          table.rowReorder.enable();
-        } else {
-          table.rowReorder.disable();
-        }
-      }).DataTable();
-      var data = [];
-      self.setGoogleLicenseConsentRequired(false);
-      for (i = 0; i < customOverlays.length; i++) {
-        overlay = customOverlays[i];
-        if (showDefault && overlay.isDefaultOverlay()) {
-          selectedOverlay[overlay.getId()] = true;
-        }
-        var disabled = !overlay.isGoogleLicenseConsent() && self.getMap().getProject().getMapCanvasType() === "GOOGLE_MAPS_API";
-        data.push(self.overlayToDataRow(overlay, selectedOverlay[overlay.getId()], disabled));
-        if (disabled) {
-          self.setGoogleLicenseConsentRequired(true);
-        }
-      }
-      table.clear().rows.add(data).draw();
-
-    }
-
-    self.onresize();
-
-    var promises = [];
-    if (showDefault) {
-      for (var key in selectedOverlay) {
-        if (selectedOverlay.hasOwnProperty(key) && selectedOverlay[key]) {
-          promises.push(self.getMap().openDataOverlay(key));
-        }
-      }
-    }
-    return Promise.all(promises);
-  });
-};
-
-/**
- *
- * @param {string} customOverlaysMessage
- */
-OverlayPanel.prototype.setCustomOverlaysMessage = function (customOverlaysMessage) {
-  this._customOverlaysMessage = customOverlaysMessage;
-};
-
-/**
- *
- * @returns {string}
- */
-OverlayPanel.prototype.getCustomOverlaysMessage = function () {
-  return this._customOverlaysMessage;
-};
-
-
-/**
- *
- * @returns {PromiseLike}
- */
-OverlayPanel.prototype.openAddOverlayDialog = function () {
-  var self = this;
-  if (self._addOverlayDialog !== undefined) {
-    self._addOverlayDialog.destroy();
-  }
-  self._addOverlayDialog = new AddOverlayDialog({
-    project: self.getProject(),
-    customMap: self.getMap(),
-    element: document.createElement("div"),
-    configuration: self.getConfiguration()
-  });
-  self._addOverlayDialog.addListener("onAddOverlay", function (e) {
-    self.getProject().addDataOverlay(e.arg);
-    return self.refresh();
-  });
-  return self._addOverlayDialog.init().then(function () {
-    return self._addOverlayDialog.open();
-  });
-};
-
-/**
- *
- * @returns {PromiseLike}
- */
-OverlayPanel.prototype.init = function () {
-  var self = this;
-  var backgroundOverlay = self.getServerConnector().getSessionData().getSelectedBackgroundOverlay();
-  var showDefault = (backgroundOverlay === undefined || backgroundOverlay === "undefined");
-  var table = $(this.getControlElement(PanelControlElementType.OVERLAY_CUSTOM_OVERLAY_TABLE)).DataTable({
-    columns: [{
-      title: 'No',
-      className: "no_padding"
-    }, {
-      title: 'Name'
-    }, {
-      title: 'View',
-      orderable: false,
-      className: "no_padding"
-    }, {
-      title: 'Data',
-      orderable: false,
-      className: "no_padding"
-    }, {
-      title: 'Edit',
-      orderable: false,
-      className: "no_padding"
-    }],
-    paging: false,
-    searching: false,
-    info: false,
-    rowReorder: true
-  });
-  table.on('row-reorder', function (e, diff) {
-    var promises = [];
-
-    for (var i = 0, ien = diff.length; i < ien; i++) {
-      var rowData = table.row(diff[i].node).data();
-      var overlayId = $(rowData[2]).attr("data");
-      promises.push(self.updateOverlayOrder(overlayId, diff[i].newData));
-    }
-    promises.push(self.getMap().redrawSelectedDataOverlays());
-    return Promise.all(promises);
-  });
-
-  return this.refresh(showDefault);
-};
-
-/**
- *
- * @param {number} overlayId
- * @param {number} order
- * @returns {PromiseLike}
- */
-OverlayPanel.prototype.updateOverlayOrder = function (overlayId, order) {
-  var self = this;
-  return self.getProject().getDataOverlayById(overlayId).then(function (overlay) {
-    overlay.setOrder(order);
-    return self.getServerConnector().updateOverlay(overlay);
-  });
-};
-
-/**
- *
- * @param {DataOverlay} overlay
- * @returns {PromiseLike<any>}
- */
-OverlayPanel.prototype.removeOverlay = function (overlay) {
-  var self = this;
-  return self.getMap().hideDataOverlay(overlay.getId()).then(function () {
-    return self.getServerConnector().removeOverlay({overlayId: overlay.getId()});
-  }).then(function () {
-    return self.refresh();
-  })
-};
-
-/**
- *
- * @returns {PromiseLike}
- */
-OverlayPanel.prototype.destroy = function () {
-  var self = this;
-  Panel.prototype.destroy.call(this);
-  var customOverlayDataTable = self.getControlElement(PanelControlElementType.OVERLAY_CUSTOM_OVERLAY_TABLE);
-  if ($.fn.DataTable.isDataTable(customOverlayDataTable)) {
-    $(customOverlayDataTable).DataTable().destroy();
-  }
-
-  if (self._addOverlayDialog !== undefined) {
-    return self._addOverlayDialog.destroy();
-  } else {
-    return Promise.resolve();
-  }
-};
-
-OverlayPanel.prototype.setGoogleLicenseConsentRequired = function (value) {
-  var leftPanel = this.getParent();
-  if (leftPanel !== undefined) {
-    leftPanel.setGoogleLicenseConsentRequired(value);
-  }
-};
-module.exports = OverlayPanel;
+"use strict";
+
+/* exported logger */
+
+var AddOverlayDialog = require('../AddOverlayDialog');
+var Panel = require('../Panel');
+var PanelControlElementType = require('../PanelControlElementType');
+
+var GuiConnector = require('../../GuiConnector');
+// noinspection JSUnusedLocalSymbols
+var logger = require('../../logger');
+var Functions = require('../../Functions');
+
+var Promise = require('bluebird');
+
+/**
+ *
+ * @param {Object} params
+ * @param {HTMLElement} params.element
+ * @param {CustomMap} params.customMap
+ * @param {Configuration} [params.configuration]
+ * @param {Project} [params.project]
+ * @param params.parent
+ *
+ * @constructor
+ * @extends Panel
+ */
+function OverlayPanel(params) {
+  params["panelName"] = "overlays";
+  params["scrollable"] = true;
+  params["helpTip"] = "<p>Overlays tab allows to display or generate custom coloring of elements and interactions in the map.</p>"
+    + "<p>General overlays are overlays accessible for every user viewing the content.</p>"
+    + "<p>Custom overlays are user-provided overlays, this menu becomes available upon login (see below).</p>";
+  if (params.project === undefined) {
+    params.project = params.customMap.getProject();
+  }
+  Panel.call(this, params);
+
+  //overflow is defined in minerva-overlay-panel, so remove the one that is already there
+  $(params.element).css("overflow", "");
+  $(params.element).addClass("minerva-overlay-panel");
+
+  var self = this;
+
+  self._createOverlayPanelGui();
+
+  var addButton = this.getControlElement(PanelControlElementType.OVERLAY_ADD_OVERLAY_BUTTON);
+
+  addButton.onclick = function () {
+    return self.openAddOverlayDialog();
+  };
+
+  var titleElement = this.getControlElement(PanelControlElementType.OVERLAY_CUSTOM_OVERLAY_TITLE);
+  self.setCustomOverlaysMessage(titleElement.innerHTML);
+
+  $(self.getElement()).on("click", "[name='overlayToggle']", function () {
+    var thisCheckbox = this;
+    var overlayId = $(thisCheckbox).attr("data");
+    var toggleOverlayPromise;
+    if (thisCheckbox.checked) {
+      toggleOverlayPromise = self.getMap().openDataOverlay(overlayId);
+    } else {
+      toggleOverlayPromise = self.getMap().hideDataOverlay(overlayId);
+    }
+    $(thisCheckbox).prop("disabled", true);
+    return toggleOverlayPromise.catch(GuiConnector.alert).finally(function () {
+      $(thisCheckbox).prop("disabled", false);
+    });
+  });
+  $(self.getElement()).on("click", "[name='overlayLink']", function () {
+    var overlayId = $(this).attr("data");
+    return self.getMap().openDataOverlay(overlayId);
+  });
+  self.getMap().addListener("onBackgroundOverlayChange", function (e) {
+    var overlayId = e.arg.toString();
+    var buttons = $("[name='overlayLink']", self.getElement());
+    for (var i = 0; i < buttons.length; i++) {
+      var button = buttons[i];
+      if ($(button).attr("data").toString() === overlayId) {
+        $(button.parentNode.parentNode).addClass('active').siblings().removeClass('active');
+      }
+    }
+  });
+  $(self.getElement()).on("click", "[name='download-overlay']", function () {
+    var overlayId = $(this).attr("data");
+    return self.getServerConnector().getOverlaySourceDownloadUrl({
+      overlayId: overlayId
+    }).then(function (url) {
+      return self.downloadFile(url);
+    }).then(null, GuiConnector.alert);
+  });
+  $(self.getElement()).on("click", "[name='editButton']", function () {
+    var overlayId = $(this).attr("data");
+    return self.getProject().getDataOverlayById(overlayId).then(function (overlay) {
+      return self.openEditOverlayDialog(overlay);
+    });
+  });
+}
+
+OverlayPanel.prototype = Object.create(Panel.prototype);
+OverlayPanel.prototype.constructor = OverlayPanel;
+
+/**
+ *
+ * @private
+ */
+OverlayPanel.prototype._createOverlayPanelGui = function () {
+  var generalOverlaysDiv = Functions.createElement({
+    type: "div",
+    name: "generalOverlays",
+    className: "searchPanel"
+  });
+  this.getElement().appendChild(generalOverlaysDiv);
+  this.setControlElement(PanelControlElementType.OVERLAY_GENERAL_OVERLAY_DIV, generalOverlaysDiv);
+
+  var generalOverlaysTitle = Functions.createElement({
+    type: "h5",
+    content: "GENERAL OVERLAYS:"
+  });
+  generalOverlaysDiv.appendChild(generalOverlaysTitle);
+
+  var generalOverlaysTableDiv = Functions.createElement({
+    type: "table",
+    name: "generalOverlaysTab",
+    className: "table table-bordered",
+    style: "width:100%"
+  });
+  generalOverlaysDiv.appendChild(generalOverlaysTableDiv);
+  this.setControlElement(PanelControlElementType.OVERLAY_GENERAL_OVERLAY_TABLE, generalOverlaysTableDiv);
+
+  var customOverlaysDiv = Functions.createElement({
+    type: "div",
+    name: "customOverlays",
+    className: "searchPanel"
+  });
+  this.getElement().appendChild(customOverlaysDiv);
+  this.setControlElement(PanelControlElementType.OVERLAY_CUSTOM_OVERLAY_DIV, customOverlaysDiv);
+
+  var customOverlaysTitle = Functions.createElement({
+    type: "h5",
+    name: "customOverlaysTitle",
+    content: "USER-PROVIDED OVERLAYS:"
+  });
+  customOverlaysDiv.appendChild(customOverlaysTitle);
+  this.setControlElement(PanelControlElementType.OVERLAY_CUSTOM_OVERLAY_TITLE, customOverlaysTitle);
+
+  var customOverlaysTableDiv = Functions.createElement({
+    type: "table",
+    name: "customOverlaysTab",
+    className: "table table-bordered",
+    style: "width:100%"
+  });
+  customOverlaysDiv.appendChild(customOverlaysTableDiv);
+  this.setControlElement(PanelControlElementType.OVERLAY_CUSTOM_OVERLAY_TABLE, customOverlaysTableDiv);
+
+  var centerTag = Functions.createElement({
+    type: "center"
+  });
+  customOverlaysDiv.appendChild(centerTag);
+
+  var addOverlayButton = Functions.createElement({
+    type: "button",
+    name: "addOverlay",
+    content: "Add overlay"
+  });
+  centerTag.appendChild(addOverlayButton);
+  this.setControlElement(PanelControlElementType.OVERLAY_ADD_OVERLAY_BUTTON, addOverlayButton);
+};
+
+OverlayPanel.prototype.clear = function () {
+  var table = this.getControlElement(PanelControlElementType.OVERLAY_GENERAL_OVERLAY_TABLE);
+  while (table.firstChild) {
+    table.removeChild(table.firstChild);
+  }
+
+  table = $(this.getControlElement(PanelControlElementType.OVERLAY_CUSTOM_OVERLAY_TABLE)).DataTable();
+  table.clear().draw();
+};
+
+/**
+ *
+ * @param {boolean} [edit=false]
+ * @returns {HTMLElement}
+ */
+OverlayPanel.prototype.createTableHeader = function (edit) {
+  if (edit === undefined) {
+    edit = false;
+  }
+  var result = document.createElement("thead");
+
+  var row = document.createElement("tr");
+
+  var nameTd = document.createElement("th");
+  nameTd.innerHTML = "Name";
+  row.appendChild(nameTd);
+
+  var viewTd = document.createElement("th");
+  viewTd.innerHTML = "View";
+  row.appendChild(viewTd);
+
+  var dataTd = document.createElement("th");
+  dataTd.innerHTML = "Data";
+  row.appendChild(dataTd);
+
+  if (edit) {
+    var editTd = document.createElement("th");
+    editTd.innerHTML = "Edit";
+    row.appendChild(editTd);
+  }
+
+  result.appendChild(row);
+  return result;
+};
+
+/**
+ *
+ * @param {DataOverlay} overlay
+ * @param {boolean} [checked=false]
+ * @param {boolean} [disabled=false]
+ * @returns {HTMLElement}
+ */
+OverlayPanel.prototype.createOverlayRow = function (overlay, checked, disabled) {
+  var self = this;
+  var guiUtils = self.getGuiUtils();
+  var result = document.createElement("tr");
+
+  if (checked && !overlay.getInputDataAvailable()) {
+    result.className = "active";
+  }
+
+  var nameTd = Functions.createElement({type: "td", content: overlay.getName(), xss: true});
+  result.appendChild(nameTd);
+
+  var viewTd = document.createElement("td");
+  if (overlay.getInputDataAvailable()) {
+    var checkbox = Functions.createElement({
+      type: "input",
+      inputType: "checkbox",
+      name: "overlayToggle",
+      data: overlay.getId()
+    });
+    checkbox.checked = checked;
+    $(checkbox).prop("disabled", disabled);
+    if (disabled) {
+      var warningDiv = Functions.createElement({
+        type: "div",
+        content: "<i class='fa fa-exclamation-triangle' style='font-size:18px; font-weight:400; padding-right:10px;color:orange'></i>",
+        xss: false
+      });
+      warningDiv.title = "You did not consent to terms of the license of Google Maps Platform. Click the \"Edit\" button to do so.";
+      viewTd.appendChild(warningDiv)
+    } else {
+      viewTd.appendChild(checkbox);
+    }
+  } else {
+    var img = guiUtils.createIcon("icons/search.png");
+    var link = Functions.createElement({type: "a", href: "#", name: "overlayLink", data: overlay.getId()});
+    link.appendChild(img);
+    viewTd.appendChild(link);
+  }
+  result.appendChild(viewTd);
+
+  var dataTd = document.createElement("td");
+  if (overlay.getInputDataAvailable()) {
+    var button = Functions.createElement({
+      type: "button",
+      name: "download-overlay",
+      data: overlay.getId(),
+      content: "<span class='ui-icon ui-icon-arrowthickstop-1-s'></span>",
+      xss: false
+    });
+    dataTd.appendChild(button);
+  }
+
+  result.appendChild(dataTd);
+
+  if (overlay.getCreator() !== "" && overlay.getCreator() !== undefined) {
+    var editTd = document.createElement("td");
+    button = Functions.createElement({
+      type: "button",
+      name: "editButton",
+      data: overlay.getId(),
+      content: "<span class='ui-icon ui-icon-document'></span>",
+      xss: false
+    });
+    editTd.appendChild(button);
+    result.appendChild(editTd);
+  }
+  result.title = overlay.getDescription();
+  return result;
+};
+
+/**
+ *
+ * @param {DataOverlay} overlay
+ * @param {boolean} checked
+ * @param {boolean} disabled
+ * @returns {Array}
+ */
+OverlayPanel.prototype.overlayToDataRow = function (overlay, checked, disabled) {
+  var result = [];
+  result[0] = overlay.getOrder();
+  result[1] = overlay.getName();
+
+  if (overlay.getInputDataAvailable()) {
+    if (disabled) {
+      result[2] = "<div title='You did not consent to terms of the license of Google Maps Platform. Click the \"Edit\" button to do so.'>" +
+        "<i class='fa fa-exclamation-triangle' style='font-size:18px; font-weight:400; padding-right:10px;color:orange'></i></div>";
+    } else {
+      var checkedString = "";
+      if (checked) {
+        checkedString = " checked ";
+      }
+      result[2] = "<input type='checkbox' " + checkedString + " data='" + overlay.getId() + "' name='overlayToggle'/>";
+    }
+
+    result[3] = "<button data='" + overlay.getId() + "' name='download-overlay'><span class='ui-icon ui-icon-arrowthickstop-1-s'></span></button>";
+  } else {
+    result[2] = "<a href='#' data='" + overlay.getId() + "' name='overlayLink'><img src='" + GuiConnector.getImgPrefix() + "icons/search.png' style='float: left' hspace='5'/></a>";
+    result[3] = "";
+  }
+
+  if (overlay.getCreator() !== "" && overlay.getCreator() !== undefined) {
+    result[4] = "<button data='" + overlay.getId() + "' name='editButton'><span class='ui-icon ui-icon-document'></span></button>";
+  } else {
+    result[4] = "";
+  }
+  if (overlay.getDescription() !== "") {
+    for (var i = 0; i < result.length; i++) {
+
+      result[i] = "<div class=\"minerva-tooltip\">" + result[i] +
+        "<span class=\"minerva-tooltip-text\">" + overlay.getDescription() + "</span>" +
+        "</div>";
+    }
+  }
+  return result;
+};
+
+/**
+ *
+ * @param {DataOverlay} overlay
+ */
+OverlayPanel.prototype.openEditOverlayDialog = function (overlay) {
+  var self = this;
+  var guiUtils = self.getGuiUtils();
+  var content = document.createElement("fieldset");
+  var nameInput = guiUtils.createInputText(overlay.getName());
+  var row = guiUtils.createTableRow([guiUtils.createLabel("Name: "), nameInput]);
+  content.appendChild(row);
+
+  var descriptionInput = guiUtils.createTextArea(overlay.getDescription());
+  row = guiUtils.createTableRow([guiUtils.createLabel("Description: "), descriptionInput]);
+  content.appendChild(row);
+
+  var consentCheckbox = document.createElement("input");
+  consentCheckbox.type = "checkbox";
+  consentCheckbox.checked = overlay.isGoogleLicenseConsent();
+
+  row = guiUtils.createTableRow([guiUtils.createLabel("I am aware that if this map is displayed using Google Maps API, " +
+    "it falls under their license <a href='https://cloud.google.com/maps-platform/terms/' target='_blank'>" +
+    "https://cloud.google.com/maps-platform/terms/</a>, to which I agree. I warrant that this dataset contains no " +
+    "Protected Health Information (as defined in and subject to HIPAA)."), consentCheckbox]);
+  content.appendChild(row);
+
+  var buttons = [{
+    text: "SAVE",
+    click: function () {
+      var windowSelf = this;
+      overlay.setName(nameInput.value);
+      overlay.setDescription(descriptionInput.value);
+      overlay.setGoogleLicenseConsent(consentCheckbox.checked);
+
+      return self.getServerConnector().updateOverlay(overlay).then(function () {
+        return self.refresh();
+      }).then(function () {
+        $(windowSelf).dialog("close");
+      }).then(null, GuiConnector.alert);
+    }
+  }, {
+    text: "REMOVE",
+    click: function () {
+      var windowSelf = this;
+      return GuiConnector.showConfirmationDialog({
+        message: "Do you want to delete overlay: " + overlay.getName() + "?"
+      }).then(function (confirmation) {
+        if (confirmation) {
+          return self.removeOverlay(overlay).then(function () {
+            $(windowSelf).dialog("close");
+          }).then(null, GuiConnector.alert);
+        }
+      });
+    }
+  }, {
+    text: "CANCEL",
+    click: function () {
+      $(this).dialog("close");
+    }
+  }];
+  self.openDialog(content, {
+    width: "600px",
+    id: overlay.getId(),
+    buttons: buttons,
+    title: "Data overlay: " + overlay.getName(),
+    className: "minerva-overlay-dialog"
+  });
+};
+
+/**
+ *
+ * @param {boolean} [showDefault=false]
+ * @returns {PromiseLike}
+ */
+OverlayPanel.prototype.refresh = function (showDefault) {
+  if (showDefault === undefined) {
+    showDefault = false;
+  }
+  var self = this;
+  var user = null;
+
+  var overlayTypes = [];
+  var selectedOverlay = [];
+
+  return self.getServerConnector().getOverlayTypes().then(function (types) {
+    overlayTypes = types;
+    return self.getServerConnector().getLoggedUser();
+  }).then(function (loggedUser) {
+    user = loggedUser;
+    return self.getMap().getVisibleDataOverlays();
+  }).then(function (visibleDataOverlays) {
+    for (var j = 0; j < visibleDataOverlays.length; j++) {
+      selectedOverlay[visibleDataOverlays[j].getId()] = true;
+    }
+
+    return self.getServerConnector().getOverlays({
+      publicOverlay: false,
+      creator: user.getLogin()
+    });
+  }).then(function (customOverlays) {
+
+    if (!showDefault) {
+      var id = self.getMap().getBackgroundDataOverlay().getId();
+      selectedOverlay[id] = true;
+    }
+
+    self.clear();
+
+    var generalOverlays = [];
+    var overlay;
+
+    var overlays = self.getProject().getDataOverlays();
+    for (var i = 0; i < overlays.length; i++) {
+      overlay = overlays[i];
+      if (overlay.getCreator() === undefined || overlay.getCreator() === "") {
+        generalOverlays.push(overlay);
+        if (showDefault && overlay.isDefaultOverlay()) {
+          selectedOverlay[overlay.getId()] = true;
+        }
+      }
+    }
+
+    var table = self.getControlElement(PanelControlElementType.OVERLAY_GENERAL_OVERLAY_TABLE);
+    table.appendChild(self.createTableHeader());
+
+    var body = document.createElement("tbody");
+    table.appendChild(body);
+    for (i = 0; i < generalOverlays.length; i++) {
+      overlay = generalOverlays[i];
+      body.appendChild(self.createOverlayRow(overlay, selectedOverlay[overlay.getId()], false));
+    }
+
+    var title = self.getControlElement(PanelControlElementType.OVERLAY_CUSTOM_OVERLAY_TITLE);
+    var addButton = self.getControlElement(PanelControlElementType.OVERLAY_ADD_OVERLAY_BUTTON);
+    var tableElement = self.getControlElement(PanelControlElementType.OVERLAY_CUSTOM_OVERLAY_TABLE);
+    if (user.getLogin() === "anonymous") {
+      title.innerHTML = 'YOU ARE NOT LOGGED IN. PLEASE, <a href="#">LOG IN</a> '
+        + 'TO UPLOAD AND VIEW CUSTOM OVERLAYS<br/><center><button>LOGIN</button></center>';
+      var openLoginDialog = function () {
+        return self.getParent().getLoginDialog().open();
+      };
+      $(title).find("a")[0].onclick = openLoginDialog;
+      $(title).find("button")[0].onclick = openLoginDialog;
+      addButton.style.display = "none";
+      $(tableElement).hide();
+    } else {
+      $(tableElement).show();
+      title.innerHTML = self.getCustomOverlaysMessage();
+      addButton.style.display = "block";
+
+      table = $(tableElement).on('order.dt', function () {
+        if ($(tableElement).dataTable().fnSettings().aaSorting[0][0] === 0) {
+          table.rowReorder.enable();
+        } else {
+          table.rowReorder.disable();
+        }
+      }).DataTable();
+      var data = [];
+      self.setGoogleLicenseConsentRequired(false);
+      for (i = 0; i < customOverlays.length; i++) {
+        overlay = customOverlays[i];
+        if (showDefault && overlay.isDefaultOverlay()) {
+          selectedOverlay[overlay.getId()] = true;
+        }
+        var disabled = !overlay.isGoogleLicenseConsent() && self.getMap().getProject().getMapCanvasType() === "GOOGLE_MAPS_API";
+        data.push(self.overlayToDataRow(overlay, selectedOverlay[overlay.getId()], disabled));
+        if (disabled) {
+          self.setGoogleLicenseConsentRequired(true);
+        }
+      }
+      table.clear().rows.add(data).draw();
+
+    }
+
+    self.onresize();
+
+    var promises = [];
+    if (showDefault) {
+      for (var key in selectedOverlay) {
+        if (selectedOverlay.hasOwnProperty(key) && selectedOverlay[key]) {
+          promises.push(self.getMap().openDataOverlay(key));
+        }
+      }
+    }
+    return Promise.all(promises);
+  });
+};
+
+/**
+ *
+ * @param {string} customOverlaysMessage
+ */
+OverlayPanel.prototype.setCustomOverlaysMessage = function (customOverlaysMessage) {
+  this._customOverlaysMessage = customOverlaysMessage;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+OverlayPanel.prototype.getCustomOverlaysMessage = function () {
+  return this._customOverlaysMessage;
+};
+
+
+/**
+ *
+ * @returns {PromiseLike}
+ */
+OverlayPanel.prototype.openAddOverlayDialog = function () {
+  var self = this;
+  if (self._addOverlayDialog !== undefined) {
+    self._addOverlayDialog.destroy();
+  }
+  self._addOverlayDialog = new AddOverlayDialog({
+    project: self.getProject(),
+    customMap: self.getMap(),
+    element: document.createElement("div"),
+    configuration: self.getConfiguration()
+  });
+  self._addOverlayDialog.addListener("onAddOverlay", function (e) {
+    self.getProject().addDataOverlay(e.arg);
+    return self.refresh();
+  });
+  return self._addOverlayDialog.init().then(function () {
+    return self._addOverlayDialog.open();
+  });
+};
+
+/**
+ *
+ * @returns {PromiseLike}
+ */
+OverlayPanel.prototype.init = function () {
+  var self = this;
+  var backgroundOverlay = self.getServerConnector().getSessionData().getSelectedBackgroundOverlay();
+  var showDefault = (backgroundOverlay === undefined || backgroundOverlay === "undefined");
+  var table = $(this.getControlElement(PanelControlElementType.OVERLAY_CUSTOM_OVERLAY_TABLE)).DataTable({
+    columns: [{
+      title: 'No',
+      className: "no_padding"
+    }, {
+      title: 'Name'
+    }, {
+      title: 'View',
+      orderable: false,
+      className: "no_padding"
+    }, {
+      title: 'Data',
+      orderable: false,
+      className: "no_padding"
+    }, {
+      title: 'Edit',
+      orderable: false,
+      className: "no_padding"
+    }],
+    paging: false,
+    searching: false,
+    info: false,
+    rowReorder: true
+  });
+  table.on('row-reorder', function (e, diff) {
+    var promises = [];
+
+    for (var i = 0, ien = diff.length; i < ien; i++) {
+      var rowData = table.row(diff[i].node).data();
+      var overlayId = $(rowData[2]).attr("data");
+      promises.push(self.updateOverlayOrder(overlayId, diff[i].newData));
+    }
+    promises.push(self.getMap().redrawSelectedDataOverlays());
+    return Promise.all(promises);
+  });
+
+  return this.refresh(showDefault);
+};
+
+/**
+ *
+ * @param {number} overlayId
+ * @param {number} order
+ * @returns {PromiseLike}
+ */
+OverlayPanel.prototype.updateOverlayOrder = function (overlayId, order) {
+  var self = this;
+  return self.getProject().getDataOverlayById(overlayId).then(function (overlay) {
+    overlay.setOrder(order);
+    return self.getServerConnector().updateOverlay(overlay);
+  });
+};
+
+/**
+ *
+ * @param {DataOverlay} overlay
+ * @returns {PromiseLike<any>}
+ */
+OverlayPanel.prototype.removeOverlay = function (overlay) {
+  var self = this;
+  return self.getMap().hideDataOverlay(overlay.getId()).then(function () {
+    return self.getServerConnector().removeOverlay({overlayId: overlay.getId()});
+  }).then(function () {
+    return self.refresh();
+  })
+};
+
+/**
+ *
+ * @returns {PromiseLike}
+ */
+OverlayPanel.prototype.destroy = function () {
+  var self = this;
+  Panel.prototype.destroy.call(this);
+  var customOverlayDataTable = self.getControlElement(PanelControlElementType.OVERLAY_CUSTOM_OVERLAY_TABLE);
+  if ($.fn.DataTable.isDataTable(customOverlayDataTable)) {
+    $(customOverlayDataTable).DataTable().destroy();
+  }
+
+  if (self._addOverlayDialog !== undefined) {
+    return self._addOverlayDialog.destroy();
+  } else {
+    return Promise.resolve();
+  }
+};
+
+OverlayPanel.prototype.setGoogleLicenseConsentRequired = function (value) {
+  var leftPanel = this.getParent();
+  if (leftPanel !== undefined) {
+    leftPanel.setGoogleLicenseConsentRequired(value);
+  }
+};
+module.exports = OverlayPanel;
diff --git a/frontend-js/src/main/js/gui/leftPanel/ProjectInfoPanel.js b/frontend-js/src/main/js/gui/leftPanel/ProjectInfoPanel.js
index c981bc420c36799ea77e938bce6b771e01d811ee..004f351df91b8e5d6027366eeff0c325b25bd428 100644
--- a/frontend-js/src/main/js/gui/leftPanel/ProjectInfoPanel.js
+++ b/frontend-js/src/main/js/gui/leftPanel/ProjectInfoPanel.js
@@ -1,382 +1,382 @@
-"use strict";
-
-/* exported logger */
-
-var ConfigurationType = require('../../ConfigurationType');
-var GuiConnector = require('../../GuiConnector');
-var Panel = require('../Panel');
-var PanelControlElementType = require('../PanelControlElementType');
-var PublicationListDialog = require('./PublicationListDialog');
-
-var logger = require('../../logger');
-var Functions = require('../../Functions');
-
-function ProjectInfoPanel(params) {
-  params.panelName = "info";
-  params.scrollable = true;
-  Panel.call(this, params);
-  var self = this;
-  self._createInfoPanelGui();
-  self._createInfoPanelLogic();
-
-  self._createUserDataTab();
-  var logoutButton = self.getControlElement(PanelControlElementType.USER_TAB_LOGOUT_BUTTON);
-
-  logoutButton.onclick = function () {
-    return ServerConnector.logout().then(function () {
-      window.location.reload(false);
-    }).then(null, GuiConnector.alert);
-  };
-
-}
-
-ProjectInfoPanel.prototype = Object.create(Panel.prototype);
-ProjectInfoPanel.prototype.constructor = ProjectInfoPanel;
-
-ProjectInfoPanel.prototype._createInfoPanelGui = function () {
-  var self = this;
-  var guiUtils = self.getGuiUtils();
-  var projectId = self.getMap().getProject().getProjectId();
-
-  var infoDiv = Functions.createElement({
-    type: "div",
-    name: "infoDiv",
-    className: "searchPanel"
-  });
-  this.getElement().appendChild(infoDiv);
-  this.setControlElement(PanelControlElementType.INFO_DIV, infoDiv);
-
-  var infoTitle = Functions.createElement({
-    type: "h4",
-    content: "PROJECT INFO:"
-  });
-  infoDiv.appendChild(infoTitle);
-
-  var dataTab = Functions.createElement({
-    type: "div",
-    style: "width:100%;display: table;border-spacing: 10px;"
-  });
-  infoDiv.appendChild(dataTab);
-
-  var projectNameLabel = Functions.createElement({
-    type: "div",
-    content: "Name:"
-  });
-  var projectNameText = Functions.createElement({
-    type: "div",
-    style: "width:100%",
-    name: "projectNameText"
-  });
-  this.setControlElement(PanelControlElementType.INFO_PROJECT_NAME_TEXT, projectNameText);
-  dataTab.appendChild(guiUtils.createTableRow([projectNameLabel, projectNameText]));
-
-  var projectVersionLabel = Functions.createElement({
-    type: "div",
-    content: "Version:"
-  });
-  var projectVersionText = Functions.createElement({
-    type: "div",
-    style: "width:100%",
-    name: "projectVersionText"
-  });
-  this.setControlElement(PanelControlElementType.INFO_PROJECT_VERSION_TEXT, projectVersionText);
-  dataTab.appendChild(guiUtils.createTableRow([projectVersionLabel, projectVersionText]));
-
-  infoTitle = Functions.createElement({
-    type: "h4",
-    content: "Data:"
-  });
-  infoDiv.appendChild(infoTitle);
-
-  var dialogDiv = Functions.createElement({
-    type: "div"
-  });
-
-  this.publicationListDialog = new PublicationListDialog({
-    customMap: self.getMap(),
-    element: dialogDiv
-  });
-
-  dataTab = Functions.createElement({
-    type: "ul"
-  });
-  infoDiv.appendChild(dataTab);
-
-  var projectPublicationsText = Functions.createElement({
-    type: "span",
-    name: "projectPublicationsText",
-    style: "font-family:FontAwesome; font-weight: normal;font-style: normal;cursor: pointer"
-  });
-  this.setControlElement(PanelControlElementType.INFO_PROJECT_PUBLICATIONS_TEXT, projectPublicationsText);
-
-  var projectPublicationsButton = Functions.createElement({
-    type: "a",
-    name: "projectPublicationsButton"
-  });
-  projectPublicationsButton.appendChild(Functions.createElement({
-    type: "span",
-    content: "<i class='fa fa-list'>&nbsp;",
-    xss: false
-  }));
-
-  projectPublicationsButton.appendChild(projectPublicationsText);
-  projectPublicationsButton.appendChild(Functions.createElement({
-    type: "span",
-    style: "font-family:FontAwesome; font-weight: normal;font-style: normal;cursor: pointer",
-    content: "&nbsp;publication(s)"
-  }));
-  this.setControlElement(PanelControlElementType.INFO_PROJECT_SHOW_PUBLICATIONS_BUTTON, projectPublicationsButton);
-
-  var liElement = Functions.createElement({
-    type: "li",
-    style: "line-height: 30px;"
-  });
-  liElement.appendChild(projectPublicationsButton);
-  dataTab.appendChild(liElement);
-
-  var projectOriginalFileButton = Functions.createElement({
-    type: "a",
-    name: "projectOriginalFileButton",
-    href: "#",
-    content: "<i class='fa fa-files-o'>&nbsp;source file",
-    xss: false
-  });
-  this.setControlElement(PanelControlElementType.INFO_PROJECT_GET_ORIGINAL_FILE_BUTTON, projectOriginalFileButton);
-  liElement = Functions.createElement({
-    type: "li",
-    style: "line-height: 30px"
-  });
-  liElement.appendChild(projectOriginalFileButton);
-  dataTab.appendChild(liElement);
-
-  var exportButton = Functions.createElement({
-    type: "a",
-    href: ServerConnector.getServerBaseUrl() + "/export.xhtml?id=" + projectId,
-    content: '<i class="fa fa-mail-forward">&nbsp;EXPORT',
-    xss: false
-  });
-  liElement = Functions.createElement({
-    type: "li",
-    style: "line-height: 30px"
-  });
-  liElement.appendChild(exportButton);
-  dataTab.appendChild(liElement);
-
-  var manualButton = Functions.createElement({
-    type: "a",
-    name: "manualLink",
-    content: '<i class="fa fa-file">&nbsp;MANUAL',
-    xss: false
-  });
-  manualButton.href = "#";
-  manualButton.onclick = function () {
-    return ServerConnector.getConfigurationParam(ConfigurationType.USER_MANUAL_FILE).then(function (manualFileUrl) {
-      var win = window.open(manualFileUrl, '_user_manual_');
-      win.focus();
-    });
-  };
-  liElement = Functions.createElement({
-    type: "li",
-    style: "line-height: 30px"
-  });
-  liElement.appendChild(manualButton);
-  dataTab.appendChild(liElement);
-
-};
-
-ProjectInfoPanel.prototype._createInfoPanelLogic = function () {
-  var self = this;
-
-  var downloadSourceButton = self.getControlElement(PanelControlElementType.INFO_PROJECT_GET_ORIGINAL_FILE_BUTTON);
-  var showPublicationsButton = self.getControlElement(PanelControlElementType.INFO_PROJECT_SHOW_PUBLICATIONS_BUTTON);
-
-  downloadSourceButton.onclick = function () {
-    return self.downloadSourceFile();
-  };
-  showPublicationsButton.onclick = function () {
-    return self.showPublicationListDialog();
-  };
-};
-
-ProjectInfoPanel.prototype.downloadSourceFile = function () {
-  var self = this;
-  return ServerConnector.getProjectSourceDownloadUrl().then(function (url) {
-    return self.downloadFile(url);
-  }).then(null, GuiConnector.alert);
-};
-
-ProjectInfoPanel.prototype.showPublicationListDialog = function () {
-  return this.publicationListDialog.show();
-};
-
-ProjectInfoPanel.prototype.refresh = function () {
-  var self = this;
-
-  var projectNameText = self.getControlElement(PanelControlElementType.INFO_PROJECT_NAME_TEXT);
-  var projectVersionText = self.getControlElement(PanelControlElementType.INFO_PROJECT_VERSION_TEXT);
-  var projectPublicationsText = self.getControlElement(PanelControlElementType.INFO_PROJECT_PUBLICATIONS_TEXT);
-
-  var project = self.getProject();
-  projectNameText.innerHTML = project.getName();
-  projectVersionText.innerHTML = project.getVersion();
-
-  return ServerConnector.getProjectStatistics().then(function (statistics) {
-    projectPublicationsText.innerHTML = statistics.getPublicationCount();
-    return ServerConnector.getLoggedUser();
-  }).then(function (user) {
-    self.showUserProfilePage(user);
-  });
-};
-
-ProjectInfoPanel.prototype._createUserDataTab = function () {
-  var self = this;
-  var guiUtils = self.getGuiUtils();
-  var userDataDiv = Functions.createElement({
-    type: "div",
-    name: "userDataTab",
-    className: "searchPanel",
-    style: "display:none"
-  });
-  this.getElement().appendChild(userDataDiv);
-  this.setControlElement(PanelControlElementType.USER_TAB_USER_DIV, userDataDiv);
-
-  var userDataTitle = Functions.createElement({
-    type: "h3",
-    content: '<img src="./resources/images/profile.png" border="0" align="left"/><br/>User data<br/>',
-    xss: false
-  });
-  userDataDiv.appendChild(userDataTitle);
-
-  var userDataFormTab = Functions.createElement({
-    type: "div",
-    style: "width:100%;display: table;border-spacing: 10px;"
-  });
-  userDataDiv.appendChild(userDataFormTab);
-
-  var loginLabel = Functions.createElement({
-    type: "span",
-    content: "LOGIN:",
-    style: "color:#999999"
-  });
-  var loginText = Functions.createElement({
-    type: "span",
-    name: "loginValue"
-  });
-  this.setControlElement(PanelControlElementType.USER_TAB_LOGIN_TEXT, loginText);
-  userDataDiv.appendChild(guiUtils.createTableRow([loginLabel, loginText]));
-
-  var nameLabel = Functions.createElement({
-    type: "span",
-    content: "NAME:",
-    style: "color:#999999"
-  });
-  var nameText = Functions.createElement({
-    type: "span",
-    name: "nameValue"
-  });
-  this.setControlElement(PanelControlElementType.USER_TAB_NAME_TEXT, nameText);
-  userDataDiv.appendChild(guiUtils.createTableRow([nameLabel, nameText]));
-
-  var surnameLabel = Functions.createElement({
-    type: "span",
-    content: "SURNAME:",
-    style: "color:#999999"
-  });
-  var surnameText = Functions.createElement({
-    type: "span",
-    name: "surnameValue"
-  });
-  this.setControlElement(PanelControlElementType.USER_TAB_SURNAME_TEXT, surnameText);
-  userDataDiv.appendChild(guiUtils.createTableRow([surnameLabel, surnameText]));
-
-  var emailLabel = Functions.createElement({
-    type: "span",
-    content: "EMAIL:",
-    style: "color:#999999"
-  });
-  var emailText = Functions.createElement({
-    type: "span",
-    name: "emailValue"
-  });
-  self.setControlElement(PanelControlElementType.USER_TAB_EMAIL_TEXT, emailText);
-  userDataDiv.appendChild(guiUtils.createTableRow([emailLabel, emailText]));
-
-  var centerTag = Functions.createElement({
-    type: "center"
-  });
-  userDataDiv.appendChild(centerTag);
-
-  var logoutButton = Functions.createElement({
-    type: "button",
-    name: "logoutButton",
-    content: "LOGOUT"
-  });
-  centerTag.appendChild(logoutButton);
-  self.setControlElement(PanelControlElementType.USER_TAB_LOGOUT_BUTTON, logoutButton);
-  self.setControlElement(PanelControlElementType.USER_TAB_USER_DIV, userDataDiv);
-
-  var loginTabDiv = Functions.createElement({
-    type: "div",
-    name: "userLoginTab",
-    className: "searchPanel",
-    style: "display:none",
-    content: '<h3><img src="./resources/images/profile.png" border="0" align="left"/>'
-    + '<br/>User data</h3><br/>YOU ARE NOT LOGGED IN.<br/>' + '<center><button>LOGIN</button></center>' +
-    '<br/><a href="#" name="requestAccount">Request an account</a>',
-    xss: false
-
-  });
-  $(loginTabDiv).find("button")[0].onclick = function () {
-    return self.getParent().getLoginDialog().open();
-  };
-
-  self.getElement().appendChild(loginTabDiv);
-  self.setControlElement(PanelControlElementType.USER_TAB_LOGIN_DIV, loginTabDiv);
-
-};
-
-
-ProjectInfoPanel.prototype.showUserProfilePage = function (user) {
-
-  var self = this;
-  var userDataTabDiv = self.getControlElement(PanelControlElementType.USER_TAB_USER_DIV);
-  var userLoginTabDiv = self.getControlElement(PanelControlElementType.USER_TAB_LOGIN_DIV);
-  if (user.getLogin() !== "anonymous") {
-    var loginText = self.getControlElement(PanelControlElementType.USER_TAB_LOGIN_TEXT);
-    var nameText = self.getControlElement(PanelControlElementType.USER_TAB_NAME_TEXT);
-    var surnameText = self.getControlElement(PanelControlElementType.USER_TAB_SURNAME_TEXT);
-    var emailText = self.getControlElement(PanelControlElementType.USER_TAB_EMAIL_TEXT);
-
-    userLoginTabDiv.style.display = "none";
-    userDataTabDiv.style.display = "block";
-
-    loginText.innerHTML = user.getLogin();
-    nameText.innerHTML = user.getName();
-    surnameText.innerHTML = user.getSurname();
-    emailText.innerHTML = user.getEmail();
-  } else {
-
-    userLoginTabDiv.style.display = "block";
-    userDataTabDiv.style.display = "none";
-  }
-};
-
-ProjectInfoPanel.prototype.init = function () {
-  var self = this;
-  var email, content;
-  return ServerConnector.getConfigurationParam(ConfigurationType.REQUEST_ACCOUNT_EMAIL).then(function (result) {
-    email = result;
-    return ServerConnector.getConfigurationParam(ConfigurationType.REQUEST_ACCOUNT_DEFAULT_CONTENT);
-  }).then(function (result) {
-    content = encodeURIComponent(result);
-    var url = 'mailto:' + email + '?subject=MINERVA account request&body=' + content;
-    var link = $("[name=requestAccount]", self.getElement());
-    link.attr("href", url);
-    return self.refresh();
-  });
-};
-
-ProjectInfoPanel.prototype.destroy = function () {
-  return this.publicationListDialog.destroy();
-};
-module.exports = ProjectInfoPanel;
+"use strict";
+
+/* exported logger */
+
+var ConfigurationType = require('../../ConfigurationType');
+var GuiConnector = require('../../GuiConnector');
+var Panel = require('../Panel');
+var PanelControlElementType = require('../PanelControlElementType');
+var PublicationListDialog = require('./PublicationListDialog');
+
+var logger = require('../../logger');
+var Functions = require('../../Functions');
+
+function ProjectInfoPanel(params) {
+  params.panelName = "info";
+  params.scrollable = true;
+  Panel.call(this, params);
+  var self = this;
+  self._createInfoPanelGui();
+  self._createInfoPanelLogic();
+
+  self._createUserDataTab();
+  var logoutButton = self.getControlElement(PanelControlElementType.USER_TAB_LOGOUT_BUTTON);
+
+  logoutButton.onclick = function () {
+    return ServerConnector.logout().then(function () {
+      window.location.reload(false);
+    }).then(null, GuiConnector.alert);
+  };
+
+}
+
+ProjectInfoPanel.prototype = Object.create(Panel.prototype);
+ProjectInfoPanel.prototype.constructor = ProjectInfoPanel;
+
+ProjectInfoPanel.prototype._createInfoPanelGui = function () {
+  var self = this;
+  var guiUtils = self.getGuiUtils();
+  var projectId = self.getMap().getProject().getProjectId();
+
+  var infoDiv = Functions.createElement({
+    type: "div",
+    name: "infoDiv",
+    className: "searchPanel"
+  });
+  this.getElement().appendChild(infoDiv);
+  this.setControlElement(PanelControlElementType.INFO_DIV, infoDiv);
+
+  var infoTitle = Functions.createElement({
+    type: "h4",
+    content: "PROJECT INFO:"
+  });
+  infoDiv.appendChild(infoTitle);
+
+  var dataTab = Functions.createElement({
+    type: "div",
+    style: "width:100%;display: table;border-spacing: 10px;"
+  });
+  infoDiv.appendChild(dataTab);
+
+  var projectNameLabel = Functions.createElement({
+    type: "div",
+    content: "Name:"
+  });
+  var projectNameText = Functions.createElement({
+    type: "div",
+    style: "width:100%",
+    name: "projectNameText"
+  });
+  this.setControlElement(PanelControlElementType.INFO_PROJECT_NAME_TEXT, projectNameText);
+  dataTab.appendChild(guiUtils.createTableRow([projectNameLabel, projectNameText]));
+
+  var projectVersionLabel = Functions.createElement({
+    type: "div",
+    content: "Version:"
+  });
+  var projectVersionText = Functions.createElement({
+    type: "div",
+    style: "width:100%",
+    name: "projectVersionText"
+  });
+  this.setControlElement(PanelControlElementType.INFO_PROJECT_VERSION_TEXT, projectVersionText);
+  dataTab.appendChild(guiUtils.createTableRow([projectVersionLabel, projectVersionText]));
+
+  infoTitle = Functions.createElement({
+    type: "h4",
+    content: "Data:"
+  });
+  infoDiv.appendChild(infoTitle);
+
+  var dialogDiv = Functions.createElement({
+    type: "div"
+  });
+
+  this.publicationListDialog = new PublicationListDialog({
+    customMap: self.getMap(),
+    element: dialogDiv
+  });
+
+  dataTab = Functions.createElement({
+    type: "ul"
+  });
+  infoDiv.appendChild(dataTab);
+
+  var projectPublicationsText = Functions.createElement({
+    type: "span",
+    name: "projectPublicationsText",
+    style: "font-family:FontAwesome; font-weight: normal;font-style: normal;cursor: pointer"
+  });
+  this.setControlElement(PanelControlElementType.INFO_PROJECT_PUBLICATIONS_TEXT, projectPublicationsText);
+
+  var projectPublicationsButton = Functions.createElement({
+    type: "a",
+    name: "projectPublicationsButton"
+  });
+  projectPublicationsButton.appendChild(Functions.createElement({
+    type: "span",
+    content: "<i class='fa fa-list'>&nbsp;",
+    xss: false
+  }));
+
+  projectPublicationsButton.appendChild(projectPublicationsText);
+  projectPublicationsButton.appendChild(Functions.createElement({
+    type: "span",
+    style: "font-family:FontAwesome; font-weight: normal;font-style: normal;cursor: pointer",
+    content: "&nbsp;publication(s)"
+  }));
+  this.setControlElement(PanelControlElementType.INFO_PROJECT_SHOW_PUBLICATIONS_BUTTON, projectPublicationsButton);
+
+  var liElement = Functions.createElement({
+    type: "li",
+    style: "line-height: 30px;"
+  });
+  liElement.appendChild(projectPublicationsButton);
+  dataTab.appendChild(liElement);
+
+  var projectOriginalFileButton = Functions.createElement({
+    type: "a",
+    name: "projectOriginalFileButton",
+    href: "#",
+    content: "<i class='fa fa-files-o'>&nbsp;source file",
+    xss: false
+  });
+  this.setControlElement(PanelControlElementType.INFO_PROJECT_GET_ORIGINAL_FILE_BUTTON, projectOriginalFileButton);
+  liElement = Functions.createElement({
+    type: "li",
+    style: "line-height: 30px"
+  });
+  liElement.appendChild(projectOriginalFileButton);
+  dataTab.appendChild(liElement);
+
+  var exportButton = Functions.createElement({
+    type: "a",
+    href: ServerConnector.getServerBaseUrl() + "/export.xhtml?id=" + projectId,
+    content: '<i class="fa fa-mail-forward">&nbsp;EXPORT',
+    xss: false
+  });
+  liElement = Functions.createElement({
+    type: "li",
+    style: "line-height: 30px"
+  });
+  liElement.appendChild(exportButton);
+  dataTab.appendChild(liElement);
+
+  var manualButton = Functions.createElement({
+    type: "a",
+    name: "manualLink",
+    content: '<i class="fa fa-file">&nbsp;MANUAL',
+    xss: false
+  });
+  manualButton.href = "#";
+  manualButton.onclick = function () {
+    return ServerConnector.getConfigurationParam(ConfigurationType.USER_MANUAL_FILE).then(function (manualFileUrl) {
+      var win = window.open(manualFileUrl, '_user_manual_');
+      win.focus();
+    });
+  };
+  liElement = Functions.createElement({
+    type: "li",
+    style: "line-height: 30px"
+  });
+  liElement.appendChild(manualButton);
+  dataTab.appendChild(liElement);
+
+};
+
+ProjectInfoPanel.prototype._createInfoPanelLogic = function () {
+  var self = this;
+
+  var downloadSourceButton = self.getControlElement(PanelControlElementType.INFO_PROJECT_GET_ORIGINAL_FILE_BUTTON);
+  var showPublicationsButton = self.getControlElement(PanelControlElementType.INFO_PROJECT_SHOW_PUBLICATIONS_BUTTON);
+
+  downloadSourceButton.onclick = function () {
+    return self.downloadSourceFile();
+  };
+  showPublicationsButton.onclick = function () {
+    return self.showPublicationListDialog();
+  };
+};
+
+ProjectInfoPanel.prototype.downloadSourceFile = function () {
+  var self = this;
+  return ServerConnector.getProjectSourceDownloadUrl().then(function (url) {
+    return self.downloadFile(url);
+  }).then(null, GuiConnector.alert);
+};
+
+ProjectInfoPanel.prototype.showPublicationListDialog = function () {
+  return this.publicationListDialog.show();
+};
+
+ProjectInfoPanel.prototype.refresh = function () {
+  var self = this;
+
+  var projectNameText = self.getControlElement(PanelControlElementType.INFO_PROJECT_NAME_TEXT);
+  var projectVersionText = self.getControlElement(PanelControlElementType.INFO_PROJECT_VERSION_TEXT);
+  var projectPublicationsText = self.getControlElement(PanelControlElementType.INFO_PROJECT_PUBLICATIONS_TEXT);
+
+  var project = self.getProject();
+  projectNameText.innerHTML = project.getName();
+  projectVersionText.innerHTML = project.getVersion();
+
+  return ServerConnector.getProjectStatistics().then(function (statistics) {
+    projectPublicationsText.innerHTML = statistics.getPublicationCount();
+    return ServerConnector.getLoggedUser();
+  }).then(function (user) {
+    self.showUserProfilePage(user);
+  });
+};
+
+ProjectInfoPanel.prototype._createUserDataTab = function () {
+  var self = this;
+  var guiUtils = self.getGuiUtils();
+  var userDataDiv = Functions.createElement({
+    type: "div",
+    name: "userDataTab",
+    className: "searchPanel",
+    style: "display:none"
+  });
+  this.getElement().appendChild(userDataDiv);
+  this.setControlElement(PanelControlElementType.USER_TAB_USER_DIV, userDataDiv);
+
+  var userDataTitle = Functions.createElement({
+    type: "h3",
+    content: '<img src="./resources/images/profile.png" border="0" align="left"/><br/>User data<br/>',
+    xss: false
+  });
+  userDataDiv.appendChild(userDataTitle);
+
+  var userDataFormTab = Functions.createElement({
+    type: "div",
+    style: "width:100%;display: table;border-spacing: 10px;"
+  });
+  userDataDiv.appendChild(userDataFormTab);
+
+  var loginLabel = Functions.createElement({
+    type: "span",
+    content: "LOGIN:",
+    style: "color:#999999"
+  });
+  var loginText = Functions.createElement({
+    type: "span",
+    name: "loginValue"
+  });
+  this.setControlElement(PanelControlElementType.USER_TAB_LOGIN_TEXT, loginText);
+  userDataDiv.appendChild(guiUtils.createTableRow([loginLabel, loginText]));
+
+  var nameLabel = Functions.createElement({
+    type: "span",
+    content: "NAME:",
+    style: "color:#999999"
+  });
+  var nameText = Functions.createElement({
+    type: "span",
+    name: "nameValue"
+  });
+  this.setControlElement(PanelControlElementType.USER_TAB_NAME_TEXT, nameText);
+  userDataDiv.appendChild(guiUtils.createTableRow([nameLabel, nameText]));
+
+  var surnameLabel = Functions.createElement({
+    type: "span",
+    content: "SURNAME:",
+    style: "color:#999999"
+  });
+  var surnameText = Functions.createElement({
+    type: "span",
+    name: "surnameValue"
+  });
+  this.setControlElement(PanelControlElementType.USER_TAB_SURNAME_TEXT, surnameText);
+  userDataDiv.appendChild(guiUtils.createTableRow([surnameLabel, surnameText]));
+
+  var emailLabel = Functions.createElement({
+    type: "span",
+    content: "EMAIL:",
+    style: "color:#999999"
+  });
+  var emailText = Functions.createElement({
+    type: "span",
+    name: "emailValue"
+  });
+  self.setControlElement(PanelControlElementType.USER_TAB_EMAIL_TEXT, emailText);
+  userDataDiv.appendChild(guiUtils.createTableRow([emailLabel, emailText]));
+
+  var centerTag = Functions.createElement({
+    type: "center"
+  });
+  userDataDiv.appendChild(centerTag);
+
+  var logoutButton = Functions.createElement({
+    type: "button",
+    name: "logoutButton",
+    content: "LOGOUT"
+  });
+  centerTag.appendChild(logoutButton);
+  self.setControlElement(PanelControlElementType.USER_TAB_LOGOUT_BUTTON, logoutButton);
+  self.setControlElement(PanelControlElementType.USER_TAB_USER_DIV, userDataDiv);
+
+  var loginTabDiv = Functions.createElement({
+    type: "div",
+    name: "userLoginTab",
+    className: "searchPanel",
+    style: "display:none",
+    content: '<h3><img src="./resources/images/profile.png" border="0" align="left"/>'
+    + '<br/>User data</h3><br/>YOU ARE NOT LOGGED IN.<br/>' + '<center><button>LOGIN</button></center>' +
+    '<br/><a href="#" name="requestAccount">Request an account</a>',
+    xss: false
+
+  });
+  $(loginTabDiv).find("button")[0].onclick = function () {
+    return self.getParent().getLoginDialog().open();
+  };
+
+  self.getElement().appendChild(loginTabDiv);
+  self.setControlElement(PanelControlElementType.USER_TAB_LOGIN_DIV, loginTabDiv);
+
+};
+
+
+ProjectInfoPanel.prototype.showUserProfilePage = function (user) {
+
+  var self = this;
+  var userDataTabDiv = self.getControlElement(PanelControlElementType.USER_TAB_USER_DIV);
+  var userLoginTabDiv = self.getControlElement(PanelControlElementType.USER_TAB_LOGIN_DIV);
+  if (user.getLogin() !== "anonymous") {
+    var loginText = self.getControlElement(PanelControlElementType.USER_TAB_LOGIN_TEXT);
+    var nameText = self.getControlElement(PanelControlElementType.USER_TAB_NAME_TEXT);
+    var surnameText = self.getControlElement(PanelControlElementType.USER_TAB_SURNAME_TEXT);
+    var emailText = self.getControlElement(PanelControlElementType.USER_TAB_EMAIL_TEXT);
+
+    userLoginTabDiv.style.display = "none";
+    userDataTabDiv.style.display = "block";
+
+    loginText.innerHTML = user.getLogin();
+    nameText.innerHTML = user.getName();
+    surnameText.innerHTML = user.getSurname();
+    emailText.innerHTML = user.getEmail();
+  } else {
+
+    userLoginTabDiv.style.display = "block";
+    userDataTabDiv.style.display = "none";
+  }
+};
+
+ProjectInfoPanel.prototype.init = function () {
+  var self = this;
+  var email, content;
+  return ServerConnector.getConfigurationParam(ConfigurationType.REQUEST_ACCOUNT_EMAIL).then(function (result) {
+    email = result;
+    return ServerConnector.getConfigurationParam(ConfigurationType.REQUEST_ACCOUNT_DEFAULT_CONTENT);
+  }).then(function (result) {
+    content = encodeURIComponent(result);
+    var url = 'mailto:' + email + '?subject=MINERVA account request&body=' + content;
+    var link = $("[name=requestAccount]", self.getElement());
+    link.attr("href", url);
+    return self.refresh();
+  });
+};
+
+ProjectInfoPanel.prototype.destroy = function () {
+  return this.publicationListDialog.destroy();
+};
+module.exports = ProjectInfoPanel;
diff --git a/frontend-js/src/main/js/gui/leftPanel/SearchPanel.js b/frontend-js/src/main/js/gui/leftPanel/SearchPanel.js
index 22a3c038d76cc1f72e85f01abded2e059b04be99..17b93ec24a5c7b8cb40fb307c2843f41a3324ad5 100644
--- a/frontend-js/src/main/js/gui/leftPanel/SearchPanel.js
+++ b/frontend-js/src/main/js/gui/leftPanel/SearchPanel.js
@@ -1,118 +1,118 @@
-"use strict";
-
-var Promise = require("bluebird");
-
-/* exported logger */
-
-var Panel = require('../Panel');
-var ChemicalPanel = require('./ChemicalPanel');
-var DrugPanel = require('./DrugPanel');
-var MiRnaPanel = require('./MiRnaPanel');
-var GenericSearchPanel = require('./GenericSearchPanel');
-
-var logger = require('../../logger');
-
-/**
- *
- * @param {Configuration} params.configuration
- * @param {HTMLElement} params.element
- * @param {Project} params.project
- * @param {CustomMap} params.customMap
- * @param params.parent
- *
- * @constructor
- * @extends AbstractGuiElement
- */
-function SearchPanel(params) {
-  params["panelName"] = "global-search";
-  Panel.call(this, params);
-  var self = this;
-
-  self._createPanelGui();
-}
-
-SearchPanel.prototype = Object.create(Panel.prototype);
-SearchPanel.prototype.constructor = SearchPanel;
-
-/**
- *
- * @private
- */
-SearchPanel.prototype._createPanelGui = function () {
-  var self = this;
-
-  self.getGuiUtils().initTabContent(self);
-
-  var panels = self.getPanelsDefinition();
-  for (var i = 0; i < panels.length; i++) {
-    self.getGuiUtils().addTab(self, panels[i]);
-  }
-};
-
-/**
- *
- * @returns {*[]}
- */
-SearchPanel.prototype.getPanelsDefinition = function () {
-  return [{
-    name: "GENERIC",
-    panelClass: GenericSearchPanel,
-    options: {parent: this}
-  }, {
-    name: "DRUG",
-    panelClass: DrugPanel,
-    options: {parent: this}
-  }, {
-    name: "CHEMICAL",
-    panelClass: ChemicalPanel,
-    options: {parent: this}
-  }, {
-    name: "MiRNA",
-    panelClass: MiRnaPanel,
-    options: {parent: this}
-  }];
-};
-
-/**
- *
- * @param {AbstractDbPanel} panel
- */
-SearchPanel.prototype.hideTab = function (panel) {
-  var self = this;
-  var panelDefinitions = self.getPanelsDefinition();
-  for (var i = 0; i < panelDefinitions.length; i++) {
-    if (panel instanceof panelDefinitions[i].panelClass) {
-      var liElement = $("li:has(a[href='#search_panel_tab_" + i + "'])", $(self.getElement()))[0];
-      if (liElement !== undefined) {
-        liElement.style.display = "none";
-      } else {
-        logger.warn("Cannot find tab link for panel: " + panel.getPanelName());
-      }
-    }
-  }
-};
-
-/**
- *
- * @returns {Promise}
- */
-SearchPanel.prototype.init = function () {
-  var self = this;
-
-  var promises = [];
-  for (var i = 0; i < self._panels.length; i++) {
-    promises.push(self._panels[i].init());
-  }
-  return Promise.all(promises);
-};
-
-/**
- *
- * @returns {Promise}
- */
-SearchPanel.prototype.destroy = function () {
-  return Promise.resolve();
-};
-
-
-module.exports = SearchPanel;
+"use strict";
+
+var Promise = require("bluebird");
+
+/* exported logger */
+
+var Panel = require('../Panel');
+var ChemicalPanel = require('./ChemicalPanel');
+var DrugPanel = require('./DrugPanel');
+var MiRnaPanel = require('./MiRnaPanel');
+var GenericSearchPanel = require('./GenericSearchPanel');
+
+var logger = require('../../logger');
+
+/**
+ *
+ * @param {Configuration} params.configuration
+ * @param {HTMLElement} params.element
+ * @param {Project} params.project
+ * @param {CustomMap} params.customMap
+ * @param params.parent
+ *
+ * @constructor
+ * @extends AbstractGuiElement
+ */
+function SearchPanel(params) {
+  params["panelName"] = "global-search";
+  Panel.call(this, params);
+  var self = this;
+
+  self._createPanelGui();
+}
+
+SearchPanel.prototype = Object.create(Panel.prototype);
+SearchPanel.prototype.constructor = SearchPanel;
+
+/**
+ *
+ * @private
+ */
+SearchPanel.prototype._createPanelGui = function () {
+  var self = this;
+
+  self.getGuiUtils().initTabContent(self);
+
+  var panels = self.getPanelsDefinition();
+  for (var i = 0; i < panels.length; i++) {
+    self.getGuiUtils().addTab(self, panels[i]);
+  }
+};
+
+/**
+ *
+ * @returns {*[]}
+ */
+SearchPanel.prototype.getPanelsDefinition = function () {
+  return [{
+    name: "GENERIC",
+    panelClass: GenericSearchPanel,
+    options: {parent: this}
+  }, {
+    name: "DRUG",
+    panelClass: DrugPanel,
+    options: {parent: this}
+  }, {
+    name: "CHEMICAL",
+    panelClass: ChemicalPanel,
+    options: {parent: this}
+  }, {
+    name: "MiRNA",
+    panelClass: MiRnaPanel,
+    options: {parent: this}
+  }];
+};
+
+/**
+ *
+ * @param {AbstractDbPanel} panel
+ */
+SearchPanel.prototype.hideTab = function (panel) {
+  var self = this;
+  var panelDefinitions = self.getPanelsDefinition();
+  for (var i = 0; i < panelDefinitions.length; i++) {
+    if (panel instanceof panelDefinitions[i].panelClass) {
+      var liElement = $("li:has(a[href='#search_panel_tab_" + i + "'])", $(self.getElement()))[0];
+      if (liElement !== undefined) {
+        liElement.style.display = "none";
+      } else {
+        logger.warn("Cannot find tab link for panel: " + panel.getPanelName());
+      }
+    }
+  }
+};
+
+/**
+ *
+ * @returns {Promise}
+ */
+SearchPanel.prototype.init = function () {
+  var self = this;
+
+  var promises = [];
+  for (var i = 0; i < self._panels.length; i++) {
+    promises.push(self._panels[i].init());
+  }
+  return Promise.all(promises);
+};
+
+/**
+ *
+ * @returns {Promise}
+ */
+SearchPanel.prototype.destroy = function () {
+  return Promise.resolve();
+};
+
+
+module.exports = SearchPanel;
diff --git a/frontend-js/src/main/js/gui/leftPanel/SubmapPanel.js b/frontend-js/src/main/js/gui/leftPanel/SubmapPanel.js
index a2ac63594384c18c00f103efda155667740b21e8..908a50916ea52da4c562df1cc322772ba1162acc 100644
--- a/frontend-js/src/main/js/gui/leftPanel/SubmapPanel.js
+++ b/frontend-js/src/main/js/gui/leftPanel/SubmapPanel.js
@@ -1,151 +1,151 @@
-"use strict";
-
-var Promise = require("bluebird");
-
-var GuiConnector= require('../../GuiConnector');
-var Panel = require('../Panel');
-var PanelControlElementType = require('../PanelControlElementType');
-
-// noinspection JSUnusedLocalSymbols
-var logger = require('../../logger');
-var Functions = require('../../Functions');
-
-function SubmapPanel(params) {
-  params.panelName = "submap";
-  params.scrollable = true;
-  params.helpTip = "The Submaps tab summarizes all the submap networks uploaded together and linked to the main network of <b>'"
-    + params.parent.getMap().getProject().getName() + "'</b> project.";
-  Panel.call(this, params);
-
-  var self = this;
-  self._createSubmapGui();
-}
-
-SubmapPanel.prototype = Object.create(Panel.prototype);
-SubmapPanel.prototype.constructor = SubmapPanel;
-
-SubmapPanel.prototype._createSubmapGui = function () {
-  var submapDiv = Functions.createElement({
-    type: "div",
-    name: "submapDiv",
-    className: "searchPanel"
-  });
-  this.getElement().appendChild(submapDiv);
-  this.setControlElement(PanelControlElementType.SUBMAP_DIV, submapDiv);
-
-};
-
-SubmapPanel.prototype.createRow = function (model) {
-  var self = this;
-  var guiUtils = self.getGuiUtils();
-  var result = document.createElement("tr");
-
-  var nameTd = document.createElement("td");
-  nameTd.innerHTML = model.getName();
-  result.appendChild(nameTd);
-
-  var openTd = document.createElement("td");
-
-  if (model.getId() !== self.getMap().getId()) {
-    var img = guiUtils.createIcon("icons/search.png");
-    var link = document.createElement("a");
-    link.href = "#";
-    link.onclick = function () {
-      return self.getMap().openSubmap(model.getId()).catch(GuiConnector.alert);
-    };
-    link.appendChild(img);
-    openTd.appendChild(link);
-  }
-
-  result.appendChild(openTd);
-
-  return result;
-};
-
-SubmapPanel.prototype.createTableHeader = function () {
-  var result = document.createElement("thead");
-
-  var row = document.createElement("tr");
-
-  var nameTd = document.createElement("th");
-  nameTd.innerHTML = "Name";
-  row.appendChild(nameTd);
-
-  row.appendChild(Functions.createElement({
-    type: "th",
-    style: "width: 60px;",
-    content: "View"
-  }));
-
-  result.appendChild(row);
-  return result;
-};
-
-SubmapPanel.prototype.init = function () {
-  var self = this;
-  return new Promise(function (resolve) {
-    var div = self.getControlElement(PanelControlElementType.SUBMAP_DIV);
-    div.innerHTML = "";
-    var models = self.getMap().getProject().getModels();
-    var modelsByType = [];
-    var types = [];
-    var i;
-    for (i = 1; i < models.length; i++) {
-      var model = models[i];
-      if (modelsByType[model.getSubmodelType()] === undefined) {
-        modelsByType[model.getSubmodelType()] = [];
-        types.push(model.getSubmodelType());
-      }
-      modelsByType[model.getSubmodelType()].push(model);
-    }
-    for (i = 0; i < types.length; i++) {
-      var type = types[i];
-      var tableName = type + " submaps";
-      if (type === "UNKNOWN") {
-        tableName = ""
-      }
-      div.appendChild(self.createTable(modelsByType[type], tableName));
-    }
-    if (models.length <= 1) {
-      self.getParent().hideTab(self);
-    }
-    return resolve();
-  });
-};
-
-SubmapPanel.prototype.createTable = function (models, type) {
-  var self = this;
-  var result = Functions.createElement({
-    type: "div"
-  });
-
-  var title = Functions.createElement({
-    type: "h5",
-    content: type
-  });
-  result.appendChild(title);
-
-  var table = Functions.createElement({
-    type: "table",
-    className: "table table-bordered",
-    style: "width:100%"
-  });
-  result.appendChild(table);
-
-  table.appendChild(self.createTableHeader());
-  var tableBody = Functions.createElement({
-    type: "tbody"
-  });
-  table.appendChild(tableBody);
-
-  for (var i = 0; i < models.length; i++) {
-    tableBody.appendChild(self.createRow(models[i]));
-  }
-  return result;
-};
-
-SubmapPanel.prototype.destroy = function () {
-  return Promise.resolve();
-};
-
-module.exports = SubmapPanel;
+"use strict";
+
+var Promise = require("bluebird");
+
+var GuiConnector= require('../../GuiConnector');
+var Panel = require('../Panel');
+var PanelControlElementType = require('../PanelControlElementType');
+
+// noinspection JSUnusedLocalSymbols
+var logger = require('../../logger');
+var Functions = require('../../Functions');
+
+function SubmapPanel(params) {
+  params.panelName = "submap";
+  params.scrollable = true;
+  params.helpTip = "The Submaps tab summarizes all the submap networks uploaded together and linked to the main network of <b>'"
+    + params.parent.getMap().getProject().getName() + "'</b> project.";
+  Panel.call(this, params);
+
+  var self = this;
+  self._createSubmapGui();
+}
+
+SubmapPanel.prototype = Object.create(Panel.prototype);
+SubmapPanel.prototype.constructor = SubmapPanel;
+
+SubmapPanel.prototype._createSubmapGui = function () {
+  var submapDiv = Functions.createElement({
+    type: "div",
+    name: "submapDiv",
+    className: "searchPanel"
+  });
+  this.getElement().appendChild(submapDiv);
+  this.setControlElement(PanelControlElementType.SUBMAP_DIV, submapDiv);
+
+};
+
+SubmapPanel.prototype.createRow = function (model) {
+  var self = this;
+  var guiUtils = self.getGuiUtils();
+  var result = document.createElement("tr");
+
+  var nameTd = document.createElement("td");
+  nameTd.innerHTML = model.getName();
+  result.appendChild(nameTd);
+
+  var openTd = document.createElement("td");
+
+  if (model.getId() !== self.getMap().getId()) {
+    var img = guiUtils.createIcon("icons/search.png");
+    var link = document.createElement("a");
+    link.href = "#";
+    link.onclick = function () {
+      return self.getMap().openSubmap(model.getId()).catch(GuiConnector.alert);
+    };
+    link.appendChild(img);
+    openTd.appendChild(link);
+  }
+
+  result.appendChild(openTd);
+
+  return result;
+};
+
+SubmapPanel.prototype.createTableHeader = function () {
+  var result = document.createElement("thead");
+
+  var row = document.createElement("tr");
+
+  var nameTd = document.createElement("th");
+  nameTd.innerHTML = "Name";
+  row.appendChild(nameTd);
+
+  row.appendChild(Functions.createElement({
+    type: "th",
+    style: "width: 60px;",
+    content: "View"
+  }));
+
+  result.appendChild(row);
+  return result;
+};
+
+SubmapPanel.prototype.init = function () {
+  var self = this;
+  return new Promise(function (resolve) {
+    var div = self.getControlElement(PanelControlElementType.SUBMAP_DIV);
+    div.innerHTML = "";
+    var models = self.getMap().getProject().getModels();
+    var modelsByType = [];
+    var types = [];
+    var i;
+    for (i = 1; i < models.length; i++) {
+      var model = models[i];
+      if (modelsByType[model.getSubmodelType()] === undefined) {
+        modelsByType[model.getSubmodelType()] = [];
+        types.push(model.getSubmodelType());
+      }
+      modelsByType[model.getSubmodelType()].push(model);
+    }
+    for (i = 0; i < types.length; i++) {
+      var type = types[i];
+      var tableName = type + " submaps";
+      if (type === "UNKNOWN") {
+        tableName = ""
+      }
+      div.appendChild(self.createTable(modelsByType[type], tableName));
+    }
+    if (models.length <= 1) {
+      self.getParent().hideTab(self);
+    }
+    return resolve();
+  });
+};
+
+SubmapPanel.prototype.createTable = function (models, type) {
+  var self = this;
+  var result = Functions.createElement({
+    type: "div"
+  });
+
+  var title = Functions.createElement({
+    type: "h5",
+    content: type
+  });
+  result.appendChild(title);
+
+  var table = Functions.createElement({
+    type: "table",
+    className: "table table-bordered",
+    style: "width:100%"
+  });
+  result.appendChild(table);
+
+  table.appendChild(self.createTableHeader());
+  var tableBody = Functions.createElement({
+    type: "tbody"
+  });
+  table.appendChild(tableBody);
+
+  for (var i = 0; i < models.length; i++) {
+    tableBody.appendChild(self.createRow(models[i]));
+  }
+  return result;
+};
+
+SubmapPanel.prototype.destroy = function () {
+  return Promise.resolve();
+};
+
+module.exports = SubmapPanel;
diff --git a/frontend-js/src/main/js/gui/topMenu/TopMenu.js b/frontend-js/src/main/js/gui/topMenu/TopMenu.js
index a38f9a6abf86b758a1f81c8581839dc2c677310c..44016f2259496c840427ef62e1edf8e05e9a575d 100644
--- a/frontend-js/src/main/js/gui/topMenu/TopMenu.js
+++ b/frontend-js/src/main/js/gui/topMenu/TopMenu.js
@@ -1,243 +1,243 @@
-"use strict";
-
-var Promise = require("bluebird");
-
-/* exported logger */
-
-var AbstractGuiElement = require('../AbstractGuiElement');
-var GuiConnector = require('../../GuiConnector');
-var OverviewDialog = require('../OverviewDialog');
-var PanelControlElementType = require('../PanelControlElementType');
-
-var Functions = require('../../Functions');
-var logger = require('../../logger');
-
-function TopMenu(params) {
-  AbstractGuiElement.call(this, params);
-  var self = this;
-
-  self._createGui();
-}
-
-TopMenu.prototype = Object.create(AbstractGuiElement.prototype);
-TopMenu.prototype.constructor = TopMenu;
-
-TopMenu.prototype._createGui = function () {
-  var self = this;
-
-  var overviewDialogDiv = Functions.createElement({
-    type: "div",
-    name: "overviewDialog"
-  });
-  self.getElement().appendChild(overviewDialogDiv);
-  self.setControlElement(PanelControlElementType.OVERVIEW_DIALOG_DIV, overviewDialogDiv);
-
-  var hideButtonDiv = Functions.createElement({
-    type: "div",
-    className: "headerHideDivButton"
-  });
-  self.getElement().appendChild(hideButtonDiv);
-
-  var hideButton = Functions.createElement({
-    type: "button",
-    className: "headerHideButton",
-    name: "hideButton"
-  });
-  hideButtonDiv.appendChild(hideButton);
-  self.setControlElement(PanelControlElementType.MENU_HIDE_LEFT_PANEL_BUTTON, hideButton);
-
-  var hideButtonIcon = Functions.createElement({
-    type: "i",
-    className: "fa fa-chevron-left",
-    name: "hideButtonIcon"
-  });
-  hideButton.appendChild(hideButtonIcon);
-  self.setControlElement(PanelControlElementType.MENU_HIDE_LEFT_PANEL_BUTTON_ICON, hideButtonIcon);
-
-  var versionDiv = Functions.createElement({
-    type: "div",
-    className: "headerTextBold",
-    name: "versionDiv"
-  });
-  self.getElement().appendChild(versionDiv);
-  self.setControlElement(PanelControlElementType.MENU_VERSION_DIV, versionDiv);
-
-  var showOverviewDiv = Functions.createElement({
-    type: "div",
-    style: "float: left;"
-  });
-  self.getElement().appendChild(showOverviewDiv);
-
-  var showOverviewButton = Functions.createElement({
-    type: "button",
-    className: "minerva-overview-button",
-    name: "showOverviewButton",
-    content: "<i class='fa fa-sitemap' style='font-size:18px; font-weight:400; padding-right:10px;'></i><span >SHOW OVERVIEW</span>",
-    style: "display:none",
-    xss: false
-  });
-  showOverviewDiv.appendChild(showOverviewButton);
-  self.setControlElement(PanelControlElementType.MENU_SHOW_OVERVIEW_BUTTON, showOverviewButton);
-
-  var rightHeaderMenuDiv = Functions.createElement({
-    type: "div",
-    className: "rightHeaderMenu"
-  });
-  self.getElement().appendChild(rightHeaderMenuDiv);
-
-  var div4checkboxes = Functions.createElement({
-    type: "div",
-    className: "minerva-top-checkbox-div"
-  });
-  rightHeaderMenuDiv.appendChild(div4checkboxes);
-
-  var legendCheckbox = Functions.createElement({
-    type: "input",
-    inputType: "checkbox",
-    name: "legendCheckbox"
-  });
-  div4checkboxes.appendChild(legendCheckbox);
-  self.setControlElement(PanelControlElementType.MENU_LEGEND_CHECKBOX, legendCheckbox);
-
-  div4checkboxes.appendChild(Functions.createElement({
-    type: "label",
-    content: "LEGEND"
-  }));
-
-  var commentCheckbox = Functions.createElement({
-    type: "input",
-    inputType: "checkbox",
-    name: "commentCheckbox"
-  });
-  div4checkboxes.appendChild(commentCheckbox);
-  self.setControlElement(PanelControlElementType.MENU_COMMENTS_CHECKBOX, commentCheckbox);
-
-  div4checkboxes.appendChild(Functions.createElement({
-    type: "label",
-    content: "COMMENTS"
-  }));
-
-  var refreshCommentButton = Functions.createElement({
-    type: "button",
-    className: "minerva-overview-button",
-    name: "refreshCommentButton",
-    content: "<i class='fa fa-refresh' style='font-size:21px; font-weight:400;'></i>",
-    style: "display:none",
-    xss: false
-  });
-  div4checkboxes.appendChild(refreshCommentButton);
-  self.setControlElement(PanelControlElementType.MENU_REFRESH_COMMENTS_BUTTON, refreshCommentButton);
-
-  var clearButton = Functions.createElement({
-    type: "button",
-    className: "minerva-overview-button",
-    name: "clearButton",
-    content: "<i class='fa fa-times' style='font-size:18px; font-weight:300; padding-right:10px;'></i>CLEAR",
-    xss: false
-  });
-  rightHeaderMenuDiv.appendChild(clearButton);
-  self.setControlElement(PanelControlElementType.MENU_CLEAR_BUTTON, clearButton);
-
-};
-
-TopMenu.prototype.init = function () {
-  var self = this;
-  self.getControlElement(PanelControlElementType.MENU_LEGEND_CHECKBOX).onclick = function () {
-    return self.toggleLegend();
-  };
-  var hideButton = self.getControlElement(PanelControlElementType.MENU_HIDE_LEFT_PANEL_BUTTON);
-  var icon = self.getControlElement(PanelControlElementType.MENU_HIDE_LEFT_PANEL_BUTTON_ICON);
-  hideButton.onclick = function () {
-    if (icon.className.indexOf("fa-chevron-left") >= 0) {
-      icon.className = "fa fa-chevron-right";
-      self.getLeftPanel().hide();
-    } else {
-      icon.className = "fa fa-chevron-left";
-      self.getLeftPanel().show();
-    }
-    self.getMap().getMapCanvas().triggerListeners('resize');
-  };
-
-  var project = self.getMap().getProject();
-  self.getControlElement(PanelControlElementType.MENU_VERSION_DIV).innerHTML = project.getVersion();
-
-  var commentCheckbox = self.getControlElement(PanelControlElementType.MENU_COMMENTS_CHECKBOX);
-  var refreshCommentButton = self.getControlElement(PanelControlElementType.MENU_REFRESH_COMMENTS_BUTTON);
-  commentCheckbox.onclick = function () {
-    ServerConnector.getSessionData(project).setShowComments(commentCheckbox.checked);
-    if (commentCheckbox.checked) {
-      $(refreshCommentButton).css("display","inline");
-    } else {
-      $(refreshCommentButton).css("display","none");
-    }
-    return self.getMap().refreshComments().then(null, GuiConnector.alert);
-  };
-  refreshCommentButton.onclick = (function () {
-    return function () {
-      self.getMap().refreshComments();
-      return false;
-    };
-  })();
-
-  var clearButton = self.getControlElement(PanelControlElementType.MENU_CLEAR_BUTTON);
-  clearButton.onclick = (function () {
-    return function () {
-      return self.getMap().clearDbOverlays();
-    };
-  })();
-
-  if (project.getTopOverviewImage() !== undefined && project.getTopOverviewImage() !== null) {
-    self._overviewDialog = new OverviewDialog({
-      customMap: self.getMap(),
-      element: self.getControlElement(PanelControlElementType.OVERVIEW_DIALOG_DIV)
-    });
-    var showOverviewButton = self.getControlElement(PanelControlElementType.MENU_SHOW_OVERVIEW_BUTTON);
-    showOverviewButton.onclick = function () {
-      return self._overviewDialog.showOverview();
-    };
-    $(showOverviewButton).css("display","inline-block");
-  }
-
-  if (ServerConnector.getSessionData().getShowComments()) {
-    self.getControlElement(PanelControlElementType.MENU_COMMENTS_CHECKBOX).checked = true;
-    return self.getMap().refreshComments();
-  } else {
-    return Promise.resolve();
-  }
-};
-
-TopMenu.prototype.setLegend = function (legend) {
-  this._legend = legend;
-};
-
-TopMenu.prototype.getLegend = function () {
-  return this._legend;
-};
-
-TopMenu.prototype.setLeftPanel = function (leftPanel) {
-  this._leftPanel = leftPanel;
-};
-
-TopMenu.prototype.getLeftPanel = function () {
-  return this._leftPanel;
-};
-
-TopMenu.prototype.destroy = function () {
-  var self = this;
-  if (self._overviewDialog !== undefined) {
-    self._overviewDialog.destroy();
-  }
-  return Promise.resolve();
-};
-
-TopMenu.prototype.toggleLegend = function () {
-  var self = this;
-  var legend = self.getLegend();
-  if (self.getControlElement(PanelControlElementType.MENU_LEGEND_CHECKBOX).checked) {
-    legend.show();
-  } else {
-    legend.hide();
-  }
-};
-
+"use strict";
+
+var Promise = require("bluebird");
+
+/* exported logger */
+
+var AbstractGuiElement = require('../AbstractGuiElement');
+var GuiConnector = require('../../GuiConnector');
+var OverviewDialog = require('../OverviewDialog');
+var PanelControlElementType = require('../PanelControlElementType');
+
+var Functions = require('../../Functions');
+var logger = require('../../logger');
+
+function TopMenu(params) {
+  AbstractGuiElement.call(this, params);
+  var self = this;
+
+  self._createGui();
+}
+
+TopMenu.prototype = Object.create(AbstractGuiElement.prototype);
+TopMenu.prototype.constructor = TopMenu;
+
+TopMenu.prototype._createGui = function () {
+  var self = this;
+
+  var overviewDialogDiv = Functions.createElement({
+    type: "div",
+    name: "overviewDialog"
+  });
+  self.getElement().appendChild(overviewDialogDiv);
+  self.setControlElement(PanelControlElementType.OVERVIEW_DIALOG_DIV, overviewDialogDiv);
+
+  var hideButtonDiv = Functions.createElement({
+    type: "div",
+    className: "headerHideDivButton"
+  });
+  self.getElement().appendChild(hideButtonDiv);
+
+  var hideButton = Functions.createElement({
+    type: "button",
+    className: "headerHideButton",
+    name: "hideButton"
+  });
+  hideButtonDiv.appendChild(hideButton);
+  self.setControlElement(PanelControlElementType.MENU_HIDE_LEFT_PANEL_BUTTON, hideButton);
+
+  var hideButtonIcon = Functions.createElement({
+    type: "i",
+    className: "fa fa-chevron-left",
+    name: "hideButtonIcon"
+  });
+  hideButton.appendChild(hideButtonIcon);
+  self.setControlElement(PanelControlElementType.MENU_HIDE_LEFT_PANEL_BUTTON_ICON, hideButtonIcon);
+
+  var versionDiv = Functions.createElement({
+    type: "div",
+    className: "headerTextBold",
+    name: "versionDiv"
+  });
+  self.getElement().appendChild(versionDiv);
+  self.setControlElement(PanelControlElementType.MENU_VERSION_DIV, versionDiv);
+
+  var showOverviewDiv = Functions.createElement({
+    type: "div",
+    style: "float: left;"
+  });
+  self.getElement().appendChild(showOverviewDiv);
+
+  var showOverviewButton = Functions.createElement({
+    type: "button",
+    className: "minerva-overview-button",
+    name: "showOverviewButton",
+    content: "<i class='fa fa-sitemap' style='font-size:18px; font-weight:400; padding-right:10px;'></i><span >SHOW OVERVIEW</span>",
+    style: "display:none",
+    xss: false
+  });
+  showOverviewDiv.appendChild(showOverviewButton);
+  self.setControlElement(PanelControlElementType.MENU_SHOW_OVERVIEW_BUTTON, showOverviewButton);
+
+  var rightHeaderMenuDiv = Functions.createElement({
+    type: "div",
+    className: "rightHeaderMenu"
+  });
+  self.getElement().appendChild(rightHeaderMenuDiv);
+
+  var div4checkboxes = Functions.createElement({
+    type: "div",
+    className: "minerva-top-checkbox-div"
+  });
+  rightHeaderMenuDiv.appendChild(div4checkboxes);
+
+  var legendCheckbox = Functions.createElement({
+    type: "input",
+    inputType: "checkbox",
+    name: "legendCheckbox"
+  });
+  div4checkboxes.appendChild(legendCheckbox);
+  self.setControlElement(PanelControlElementType.MENU_LEGEND_CHECKBOX, legendCheckbox);
+
+  div4checkboxes.appendChild(Functions.createElement({
+    type: "label",
+    content: "LEGEND"
+  }));
+
+  var commentCheckbox = Functions.createElement({
+    type: "input",
+    inputType: "checkbox",
+    name: "commentCheckbox"
+  });
+  div4checkboxes.appendChild(commentCheckbox);
+  self.setControlElement(PanelControlElementType.MENU_COMMENTS_CHECKBOX, commentCheckbox);
+
+  div4checkboxes.appendChild(Functions.createElement({
+    type: "label",
+    content: "COMMENTS"
+  }));
+
+  var refreshCommentButton = Functions.createElement({
+    type: "button",
+    className: "minerva-overview-button",
+    name: "refreshCommentButton",
+    content: "<i class='fa fa-refresh' style='font-size:21px; font-weight:400;'></i>",
+    style: "display:none",
+    xss: false
+  });
+  div4checkboxes.appendChild(refreshCommentButton);
+  self.setControlElement(PanelControlElementType.MENU_REFRESH_COMMENTS_BUTTON, refreshCommentButton);
+
+  var clearButton = Functions.createElement({
+    type: "button",
+    className: "minerva-overview-button",
+    name: "clearButton",
+    content: "<i class='fa fa-times' style='font-size:18px; font-weight:300; padding-right:10px;'></i>CLEAR",
+    xss: false
+  });
+  rightHeaderMenuDiv.appendChild(clearButton);
+  self.setControlElement(PanelControlElementType.MENU_CLEAR_BUTTON, clearButton);
+
+};
+
+TopMenu.prototype.init = function () {
+  var self = this;
+  self.getControlElement(PanelControlElementType.MENU_LEGEND_CHECKBOX).onclick = function () {
+    return self.toggleLegend();
+  };
+  var hideButton = self.getControlElement(PanelControlElementType.MENU_HIDE_LEFT_PANEL_BUTTON);
+  var icon = self.getControlElement(PanelControlElementType.MENU_HIDE_LEFT_PANEL_BUTTON_ICON);
+  hideButton.onclick = function () {
+    if (icon.className.indexOf("fa-chevron-left") >= 0) {
+      icon.className = "fa fa-chevron-right";
+      self.getLeftPanel().hide();
+    } else {
+      icon.className = "fa fa-chevron-left";
+      self.getLeftPanel().show();
+    }
+    self.getMap().getMapCanvas().triggerListeners('resize');
+  };
+
+  var project = self.getMap().getProject();
+  self.getControlElement(PanelControlElementType.MENU_VERSION_DIV).innerHTML = project.getVersion();
+
+  var commentCheckbox = self.getControlElement(PanelControlElementType.MENU_COMMENTS_CHECKBOX);
+  var refreshCommentButton = self.getControlElement(PanelControlElementType.MENU_REFRESH_COMMENTS_BUTTON);
+  commentCheckbox.onclick = function () {
+    ServerConnector.getSessionData(project).setShowComments(commentCheckbox.checked);
+    if (commentCheckbox.checked) {
+      $(refreshCommentButton).css("display","inline");
+    } else {
+      $(refreshCommentButton).css("display","none");
+    }
+    return self.getMap().refreshComments().then(null, GuiConnector.alert);
+  };
+  refreshCommentButton.onclick = (function () {
+    return function () {
+      self.getMap().refreshComments();
+      return false;
+    };
+  })();
+
+  var clearButton = self.getControlElement(PanelControlElementType.MENU_CLEAR_BUTTON);
+  clearButton.onclick = (function () {
+    return function () {
+      return self.getMap().clearDbOverlays();
+    };
+  })();
+
+  if (project.getTopOverviewImage() !== undefined && project.getTopOverviewImage() !== null) {
+    self._overviewDialog = new OverviewDialog({
+      customMap: self.getMap(),
+      element: self.getControlElement(PanelControlElementType.OVERVIEW_DIALOG_DIV)
+    });
+    var showOverviewButton = self.getControlElement(PanelControlElementType.MENU_SHOW_OVERVIEW_BUTTON);
+    showOverviewButton.onclick = function () {
+      return self._overviewDialog.showOverview();
+    };
+    $(showOverviewButton).css("display","inline-block");
+  }
+
+  if (ServerConnector.getSessionData().getShowComments()) {
+    self.getControlElement(PanelControlElementType.MENU_COMMENTS_CHECKBOX).checked = true;
+    return self.getMap().refreshComments();
+  } else {
+    return Promise.resolve();
+  }
+};
+
+TopMenu.prototype.setLegend = function (legend) {
+  this._legend = legend;
+};
+
+TopMenu.prototype.getLegend = function () {
+  return this._legend;
+};
+
+TopMenu.prototype.setLeftPanel = function (leftPanel) {
+  this._leftPanel = leftPanel;
+};
+
+TopMenu.prototype.getLeftPanel = function () {
+  return this._leftPanel;
+};
+
+TopMenu.prototype.destroy = function () {
+  var self = this;
+  if (self._overviewDialog !== undefined) {
+    self._overviewDialog.destroy();
+  }
+  return Promise.resolve();
+};
+
+TopMenu.prototype.toggleLegend = function () {
+  var self = this;
+  var legend = self.getLegend();
+  if (self.getControlElement(PanelControlElementType.MENU_LEGEND_CHECKBOX).checked) {
+    legend.show();
+  } else {
+    legend.hide();
+  }
+};
+
 module.exports = TopMenu;
\ No newline at end of file
diff --git a/frontend-js/src/main/js/logger.js b/frontend-js/src/main/js/logger.js
index f60d8a4c25c3355a468a715ea767ab7827f45adb..f6cd2db0f6f6a30af3f69278b41e67b3522844db 100644
--- a/frontend-js/src/main/js/logger.js
+++ b/frontend-js/src/main/js/logger.js
@@ -1,20 +1,20 @@
-"use strict";
-
-var log4js = require('log4js');
-
-/**
- * @typedef {Object} Logger
- * @property {function(string):void} setLevel
- * @property {function(Object):void} warn
- * @property {function(Object):void} info
- * @property {function(Object):void} debug
- * @property {function(Object):void} error
- * @property {function(Object):void} fatal
- */
-
-/**
- * @type Logger
- */
-var logger = log4js.getLogger();
-
-module.exports = logger;
+"use strict";
+
+var log4js = require('log4js');
+
+/**
+ * @typedef {Object} Logger
+ * @property {function(string):void} setLevel
+ * @property {function(Object):void} warn
+ * @property {function(Object):void} info
+ * @property {function(Object):void} debug
+ * @property {function(Object):void} error
+ * @property {function(Object):void} fatal
+ */
+
+/**
+ * @type Logger
+ */
+var logger = log4js.getLogger();
+
+module.exports = logger;
diff --git a/frontend-js/src/main/js/map/ControlType.js b/frontend-js/src/main/js/map/ControlType.js
index 9aba0868fe933641990fb124933d97722c444e36..09d41558c3b7c99219f50dd0d899e1998c7364b9 100644
--- a/frontend-js/src/main/js/map/ControlType.js
+++ b/frontend-js/src/main/js/map/ControlType.js
@@ -1,9 +1,9 @@
-"use strict";
-
-var ControlType = {
-  SUBMAP_DIALOGS : "SUBMAP_DIALOGS",
-  LOGO_IMG : "LOGO_IMG",
-  LOGO_2_IMG : "LOGO_2_IMG"
-};
-
-module.exports = ControlType;
+"use strict";
+
+var ControlType = {
+  SUBMAP_DIALOGS : "SUBMAP_DIALOGS",
+  LOGO_IMG : "LOGO_IMG",
+  LOGO_2_IMG : "LOGO_2_IMG"
+};
+
+module.exports = ControlType;
diff --git a/frontend-js/src/main/js/map/CustomMap.js b/frontend-js/src/main/js/map/CustomMap.js
index 949488ace5075ce9bf517502ee6214bda41a3629..e68a051ec5687ef7982a540db7d4d524c7357c3d 100644
--- a/frontend-js/src/main/js/map/CustomMap.js
+++ b/frontend-js/src/main/js/map/CustomMap.js
@@ -1,1319 +1,1319 @@
-"use strict";
-
-var Promise = require("bluebird");
-
-var logger = require('../logger');
-var Functions = require('../Functions');
-
-var AbstractCustomMap = require('./AbstractCustomMap');
-var Alias = require('./data/Alias');
-var CommentDialog = require('../gui/CommentDialog');
-var ConfigurationType = require('../ConfigurationType');
-var ControlType = require('./ControlType');
-var CustomMapOptions = require('./CustomMapOptions');
-var GuiConnector = require('../GuiConnector');
-var IdentifiedElement = require('./data/IdentifiedElement');
-var DataOverlay = require('./data/DataOverlay');
-var Reaction = require('./data/Reaction');
-var ReferenceGenome = require('./data/ReferenceGenome');
-var SecurityError = require('../SecurityError');
-var Submap = require('./Submap');
-
-var Bounds = require('./canvas/Bounds');
-var Point = require('./canvas/Point');
-
-/**
- * Default constructor.
- *
- * @param {CustomMapOptions} options
- *          CustomMapOptions object representing all parameters needed for map
- *          creation
- *
- * @constructor
- * @extends AbstractCustomMap
- */
-function CustomMap(options) {
-  //@type {HTMLElement[]}
-  this._controls = [];
-
-  if (!(options instanceof CustomMapOptions)) {
-    options = new CustomMapOptions(options);
-  }
-  AbstractCustomMap.call(this, options.getProject().getModels()[0], options);
-
-  this.registerListenerType("onBioEntityClick");
-  this.registerListenerType("onShowOverlay");
-  this.registerListenerType("onHideOverlay");
-  this.registerListenerType("onBackgroundOverlayChange");
-
-  // @type {boolean[]}
-  this._selectedOverlays = [];
-
-  this.customizeGoogleMapView(options.getElement());
-
-  this.createMapChangedCallbacks();
-
-  /**
-   *
-   * @type {Object.<string, AbstractDbOverlay>}
-   */
-  this.overlayCollections = {};
-
-  // which submap is active (where user made interaction for the last time)
-  // @type {number}
-  this._activeSubmapId = null;
-
-  // @type {boolean}
-  this.initialized = true;
-
-  // list of reference genomes
-  this._referenceGenome = [];
-
-  this.createSubmaps();
-
-  //@type {HTMLElement[]}
-  this._dialogs = [];
-}
-
-CustomMap.prototype = Object.create(AbstractCustomMap.prototype);
-CustomMap.prototype.constructor = CustomMap;
-
-/**
- * This code must be run after the object is created. It requires to download
- * some data via promises.
- *
- * @return {PromiseLike} with empty result
- */
-CustomMap.prototype.init = function () {
-  var self = this;
-  var sessionData = self.getServerConnector().getSessionData(self.getProject());
-
-  // if we have background overlay stored in the session then restore it
-  var mapType = sessionData.getSelectedBackgroundOverlay();
-  // if we have user data overlays stored in the session then restore it
-  var ids = sessionData.getVisibleOverlays();
-  if (mapType !== undefined) {
-    ids.push(mapType);
-  }
-
-  return Promise.all([self.getMapCanvas().triggerListeners('resize'),
-    // noinspection SpellCheckingInspection
-    self.getMapCanvas().triggerListeners('maptypeid_changed'),
-    self.getMapCanvas().triggerListeners('projection_changed')
-  ]).then(function () {
-
-    // center map and zoom in to fit into browser window if there is no
-    // information about coordinates in the session
-
-    var x = self.getModel().getDefaultCenterX();
-    var y = self.getModel().getDefaultCenterY();
-    var zoom = self.getModel().getDefaultZoomLevel();
-    if (self.getServerConnector().getSessionData(self.getProject()).getCenter(self.getModel()) === undefined &&
-      (x === undefined || y === undefined || zoom === undefined ||
-        x === null || y === null || zoom === null
-      )) {
-      var bounds = new Bounds();
-      bounds.extend(self.getTopLeft());
-      bounds.extend(self.getBottomRight());
-
-      self.getMapCanvas().fitBounds(bounds);
-    }
-
-
-    return Promise.each(ids, function (overlayId) {
-      try {
-        return self.openDataOverlay(overlayId);
-      } catch (e) {
-        if (e instanceof SecurityError) {
-          logger.debug(e.message);
-          sessionData.setSelectedBackgroundOverlay(self.getProject().getDataOverlays()[0].getId());
-        } else {
-          return Promise.reject(e);
-        }
-      }
-    });
-  }).then(function () {
-    return self.getServerConnector().getLogoImg();
-  }).then(function (url) {
-    var logo2 = self.getControl(ControlType.LOGO_2_IMG);
-    if (!/^(f|ht)tps?:\/\//i.test(url)) {
-      url = GuiConnector.getImgPrefix() + url;
-    }
-    logo2.src = url;
-    logo2.setAttribute('title', self.getConfiguration().getOption(ConfigurationType.LOGO_TEXT).getValue());
-    logo2.setAttribute('alt', self.getConfiguration().getOption(ConfigurationType.LOGO_TEXT).getValue());
-  });
-};
-
-/**
- * Create submaps.
- */
-CustomMap.prototype.createSubmaps = function () {
-  this.submaps = [];
-  for (var i = 1; i < this.getProject().getModels().length; i++) {
-    this.submaps.push(new Submap(this, this.getProject().getModels()[i]));
-  }
-};
-
-/**
- * Creates logo and put it on the google map.
- */
-CustomMap.prototype.createLogo = function () {
-  var self = this;
-  var logoControlDiv2 = Functions.createElement({type: "div", index: 0});
-  var logo2 = Functions.createElement({
-    type: 'IMG',
-    style: "cursor: pointer; width: 80px",
-    id: ControlType.LOGO_2_IMG,
-    onclick: function () {
-      return self.getServerConnector().getLogoLink().then(function (url) {
-        var win = window.open(url, '_blank');
-        win.focus();
-      }).catch(GuiConnector.alert);
-    }
-  });
-  this.addControl(logo2);
-
-  logoControlDiv2.appendChild(logo2);
-
-  this.getMapCanvas().addLeftBottomControl(logoControlDiv2);
-
-  var logoControlDiv = Functions.createElement({type: "div", style: "padding: 5px", index: 1});
-  var logo = Functions.createElement({
-    type: "IMG",
-    src: GuiConnector.getImgPrefix() + GuiConnector.getLcsbLogoImg(this.bigButtons),
-    style: "cursor: pointer",
-    id: ControlType.LOGO_IMG,
-    onclick: function () {
-      var win = window.open('http://wwwen.uni.lu/lcsb/', '_blank');
-      win.focus();
-    }
-  });
-  this.addControl(logo);
-  logoControlDiv.appendChild(logo);
-
-  this.getMapCanvas().addRightBottomControl(logoControlDiv);
-};
-
-/**
- * Clear all AbstractDbOverlay.
- *
- * @returns {PromiseLike}
- */
-CustomMap.prototype.clearDbOverlays = function () {
-  var promises = [];
-  var overlays = this.getDbOverlays();
-  for (var i = 0; i < overlays.length; i++) {
-    promises.push(overlays[i].clear());
-  }
-  return Promise.all(promises);
-};
-
-/**
- * Open data overlay given in the parameter.
- *
- * @param {DataOverlay|number|string} param
- *          identifier or DataOverlay identifying data overlay to open
- *
- * @returns {PromiseLike|Promise}
- */
-CustomMap.prototype.openDataOverlay = function (param) {
-  logger.debug("Opening data overlay: " + param);
-
-  var self = this;
-  var identifier = param;
-  if (param instanceof DataOverlay) {
-    identifier = param.getId();
-  }
-  identifier = parseInt(identifier);
-
-  if (isNaN(identifier)) {
-    throw new Error("invalid id: " + param);
-  }
-
-  var overlayToOpen = null;
-  var overlays = self.getProject().getDataOverlays();
-  for (var j = 0; j < overlays.length; j++) {
-    var overlay = overlays[j];
-    if (overlay.getId() === identifier) {
-      overlayToOpen = overlay;
-    }
-  }
-
-  if (overlayToOpen === null) {
-    throw new SecurityError("You have no privileges for selected overlay");
-  } else {
-    return overlayToOpen.init().then(function () {
-      if (overlayToOpen.getInputDataAvailable()) {
-        if (self._selectedOverlays[identifier] === true) {
-          logger.warn("Overlay " + identifier + " already selected");
-          return Promise.resolve();
-        } else {
-          self._selectedOverlays[identifier] = true;
-          return self.getVisibleDataOverlays().then(function (visibleDataOverlays) {
-            var ids = [];
-            for (var i = 0; i < visibleDataOverlays.length; i++) {
-              ids.push(visibleDataOverlays[i].getId());
-            }
-            self.getServerConnector().getSessionData(self.getProject()).setVisibleOverlays(ids);
-            return self.redrawSelectedDataOverlays();
-          }).then(function () {
-            var backgroundToOpen;
-            var overlays = self.getProject().getDataOverlays();
-            for (var i = 0; i < overlays.length; i++) {
-              var overlay = overlays[i];
-              if (overlay.getName().toLowerCase() === "empty") {
-                backgroundToOpen = overlay;
-              }
-            }
-            if (backgroundToOpen === undefined) {
-              logger.warn("Cannot find empty background overlay");
-            } else {
-              return self.openDataOverlay(backgroundToOpen.getId());
-            }
-          });
-        }
-      } else {
-        if (identifier.toString() === self.getMapCanvas().getBackgroundId()) {
-          return Promise.resolve();
-        } else {
-          self.getMapCanvas().setBackgroundId(identifier.toString());
-
-          var submaps = self.getSubmaps();
-          for (var i = 0; i < submaps.length; i++) {
-            var submap = submaps[i];
-            submap.openDataOverlay(identifier);
-          }
-          return self.callListeners("onBackgroundOverlayChange", identifier);
-        }
-      }
-    }).then(function () {
-      return self.callListeners("onShowOverlay", overlayToOpen);
-    });
-  }
-};
-
-/**
- * Returns {DataOverlay} that is used as a background.
- *
- * @returns {DataOverlay}
- */
-CustomMap.prototype.getBackgroundDataOverlay = function () {
-  var identifier = parseInt(this.getMapCanvas().getBackgroundId());
-  var overlays = this.getProject().getDataOverlays();
-  for (var i = 0; i < overlays.length; i++) {
-    var overlay = overlays[i];
-    if (overlay.getId() === identifier) {
-      return overlay;
-    }
-  }
-  return null;
-};
-
-/**
- * Register AbstractDbOverlay in the map.
- *
- * @param {AbstractDbOverlay} dbOverlay
- *          database overlay to be connected to the map
- */
-CustomMap.prototype.registerDbOverlay = function (dbOverlay) {
-  var self = this;
-
-  this.overlayCollections[dbOverlay.getName()] = dbOverlay;
-
-
-  if (dbOverlay.getName() !== undefined) {
-    if (dbOverlay.getName() === "search" || dbOverlay.getName().indexOf("plugin") === 0) {
-      dbOverlay.addListener("onSearch", function (e) {
-        return self.renderOverlayCollection({
-          overlayCollection: dbOverlay,
-          fitBounds: e.arg.fitBounds
-        });
-      });
-    }
-    if (dbOverlay.getName() === "drug" || dbOverlay.getName() === "chemical" || dbOverlay.getName() === "mirna") {
-      dbOverlay.addListener("onSearch", function (e) {
-        return self.renderOverlayCollection({
-          overlayCollection: dbOverlay,
-          fitBounds: e.arg.fitBounds
-        });
-      });
-
-      dbOverlay.addListener("onTargetVisibilityChange", function () {
-        return self.renderOverlayCollection({
-          overlayCollection: dbOverlay,
-          fitBounds: false
-        });
-      });
-    }
-    if (dbOverlay.getName() === "comment") {
-      var listener = function () {
-        return self.renderOverlayCollection({
-          overlayCollection: dbOverlay,
-          fitBounds: false
-        });
-      };
-      dbOverlay.addListener("onRefresh", listener);
-      dbOverlay.addListener("onClear", listener);
-    }
-  }
-
-};
-
-/**
- * Refresh comment list.
- *
- * @return {PromiseLike} promise that is resolved when comment list is refreshed
- */
-CustomMap.prototype.refreshComments = function () {
-  var self = this;
-
-  var commentDbOverlay = self.getOverlayByName("comment");
-  if (commentDbOverlay !== undefined) {
-    if (self.getServerConnector().getSessionData(self.getProject()).getShowComments()) {
-      return commentDbOverlay.refresh();
-    } else {
-      return commentDbOverlay.clear();
-    }
-  }
-  throw new Error("comment DbOverlay not found");
-};
-
-/**
- * Turns on/off drawing module on google maps.
- */
-CustomMap.prototype.toggleDrawing = function () {
-  var submap = this.getSubmapById(this.getActiveSubmapId());
-  if (submap !== undefined) {
-    submap.getMapCanvas().toggleDrawing();
-  } else {
-    throw new Error("Cannot find submodel with id: " + this.getActiveSubmapId());
-  }
-};
-
-/**
- *
- * @returns {PromiseLike}
- */
-CustomMap.prototype.refreshMarkers = function () {
-  var promises = [];
-  logger.debug("Refresh Markers: ");
-
-  var overlays = this.getDbOverlays();
-  for (var i = 0; i < overlays.length; i++) {
-    promises.push(this.refreshOverlayMarkers(overlays[i]));
-  }
-
-  return Promise.all(promises);
-};
-
-/**
- *
- * @param {AbstractDbOverlay} overlay
- * @returns {PromiseLike}
- */
-CustomMap.prototype.refreshOverlayMarkers = function (overlay) {
-  var promises = [];
-  var self = this;
-  logger.debug("Refresh overlay: " + overlay.getName());
-
-  promises.push(self.getMarkerSurfaceCollection().refreshOverlayMarkers(overlay));
-  var submaps = self.getSubmaps();
-  for (var i = 0; i < submaps.length; i++) {
-    if (submaps[i].isInitialized()) {
-      promises.push(submaps[i].getMarkerSurfaceCollection().refreshOverlayMarkers(overlay));
-    }
-  }
-  return Promise.all(promises);
-};
-
-/**
- * Returns HTML div that is attached to jQuery dialog that should be used for
- * opening submap.
- *
- * @param {number} id
- *          identifier of the submap
- *
- * @returns {HTMLElement}
- */
-CustomMap.prototype.getSubmapDialogDiv = function (id) {
-  var dialogDiv = this._dialogs[id];
-
-  if (dialogDiv === undefined) {
-    dialogDiv = document.createElement("div");
-    dialogDiv.setAttribute("name", "dialog-" + id);
-
-    this._dialogs[id] = dialogDiv;
-
-    $(dialogDiv).dialog({
-      autoOpen: false
-    });
-  }
-  return dialogDiv;
-};
-
-/**
- * Opens a dialog with a submodel.
- *
- * @param {number} id
- * @returns {PromiseLike}
- */
-CustomMap.prototype.openSubmap = function (id) {
-  var self = this;
-  var submap = self.getSubmapById(id);
-  if (submap === null) {
-    throw new Error("Unknown submap for id: " + id);
-  } else if (submap !== this) {
-    var wasInitialized = submap.isInitialized();
-
-    var dialogDiv = self.getSubmapDialogDiv(id);
-
-    submap.open(dialogDiv);
-
-    return this.openDataOverlay(self.getMapCanvas().getBackgroundId()).then(function () {
-      if (!wasInitialized) {
-        // now we have to visualize overlays
-        return self.getVisibleDataOverlays().then(function (overlays) {
-          var promises = [];
-          // show overlays that should be visualized (resize or show them)
-          for (var i = 0; i < overlays.length; i++) {
-            promises.push(submap._showSelectedDataOverlay(overlays[i].getId(), i, overlays.length));
-          }
-          return Promise.all(promises);
-        }).then(function () {
-          return self.refreshMarkers();
-        });
-      }
-    });
-  } else {
-    return Promise.resolve();
-  }
-
-};
-
-/**
- *
- * @param {HTMLElement} div
- */
-CustomMap.prototype.customizeGoogleMapView = function (div) {
-  var self = this;
-
-  self.createMapCanvas(div);
-
-  self.createLogo();
-};
-
-/**
- * Creates listeners for google.maps.Map object that will actualize the data in
- * user session.
- */
-CustomMap.prototype.createMapChangedCallbacks = function () {
-  this._createMapChangedCallbacks();
-  var self = this;
-  var sessionData = self.getServerConnector().getSessionData(self.getProject());
-
-  // listener for changing type of background overlay
-  // noinspection SpellCheckingInspection
-  this.getMapCanvas().addListener('maptypeid_changed', function () {
-    sessionData.setSelectedBackgroundOverlay(self.getMapCanvas().getBackgroundId());
-  });
-
-};
-
-/**
- * Returns submap (or this map) by id.
- *
- * @param {number|string} identifier
- *          identifier of the submap
- * @returns {AbstractCustomMap} (submap or this map) with given identifier of the model
- */
-CustomMap.prototype.getSubmapById = function (identifier) {
-  identifier = parseInt(identifier);
-  if (this.getId() === identifier) {
-    return this;
-  }
-  for (var i = 0; i < this.submaps.length; i++) {
-    if (this.submaps[i].getId() === identifier) {
-      return this.submaps[i];
-    }
-  }
-  logger.warn("Cannot find submodel with id: " + identifier);
-  return null;
-};
-
-/**
- *
- */
-CustomMap.prototype.removeSelection = function () {
-  var model = this.getSubmapById(this.getActiveSubmapId());
-  if (model !== null) {
-    model.getMapCanvas().removeSelection();
-  } else {
-    throw new Error("Cannot find submap with id: " + this.getActiveSubmapId());
-  }
-};
-
-/**
- * Removes overlay from visualization.
- *
- * @param {number} identifier
- *          identifier of overlay to remove
- *
- * @returns {PromiseLike}
- */
-CustomMap.prototype.hideDataOverlay = function (identifier) {
-  var self = this;
-  logger.debug("Hiding overlay: " + identifier);
-
-  if (this._selectedOverlays[identifier] !== true) {
-    logger.warn("Overlay " + identifier + " is not selected");
-    return Promise.resolve();
-  } else {
-    self._selectedOverlays[identifier] = false;
-    return self.redrawSelectedDataOverlays().then(function () {
-      return self.getVisibleDataOverlays();
-    }).then(function (visibleDataOverlays) {
-      var ids = [];
-      for (var i = 0; i < visibleDataOverlays.length; i++) {
-        ids.push(visibleDataOverlays[i].getId());
-      }
-      self.getServerConnector().getSessionData(self.getProject()).setVisibleOverlays(ids);
-      return self.redrawSelectedDataOverlays();
-    }).then(function () {
-      return self.getProject().getDataOverlayById(identifier);
-    }).then(function (overlay) {
-      return self.callListeners("onHideOverlay", overlay);
-    });
-  }
-};
-
-/**
- * Redrawing selected overlays.
- *
- * @returns {PromiseLike|Promise}
- */
-CustomMap.prototype.redrawSelectedDataOverlays = function () {
-  logger.debug("Redrawing overlays");
-  var self = this;
-  return self.getVisibleDataOverlays().then(function (visibleDataOverlays) {
-    // show overlays that should be visualized (resize or show them)
-    var promises = [];
-    for (var i = 0; i < visibleDataOverlays.length; i++) {
-      var overlayId = visibleDataOverlays[i].getId();
-      if (self.layoutContainsOverlays(overlayId)) {
-        // resize element on the map
-        promises.push(self.resizeSelectedDataOverlay(overlayId, i, visibleDataOverlays.length));
-      } else {
-        promises.push(self.showSelectedDataOverlay(overlayId, i, visibleDataOverlays.length));
-      }
-    }
-    return Promise.all(promises);
-  }).then(function () {
-    var promises = [];
-    // hide overlays that were visible
-    var overlays = self.getProject().getDataOverlays();
-    for (var i = 0; i < overlays.length; i++) {
-      var id = overlays[i].getId();
-      if (!self._selectedOverlays[id] && self.layoutContainsOverlays(id)) {
-        promises.push(self.hideSelectedLayout(id));
-      }
-    }
-    return Promise.all(promises);
-  });
-};
-
-/**
- * Hides overlay on the map and all submaps
- *
- * @param {number} overlayId
- *          identifier of a overlay to hide
- *
- * @returns {Promise}
- */
-CustomMap.prototype.hideSelectedLayout = function (overlayId) {
-  var promises = [];
-  promises.push(this._hideSelectedLayout(overlayId));
-  for (var i = 0; i < this.submaps.length; i++) {
-    promises.push(this.submaps[i]._hideSelectedLayout(overlayId));
-  }
-  return Promise.all(promises);
-};
-
-/**
- * Resize(refresh) overlay on the map and all submaps. Resizing should be called
- * when number of overlays to visualize change.
- *
- * @param {number} overlayId
- *          identifier of overlay to refresh
- * @param {number} index
- *          position of the overlay in list of overlays that we visualize
- * @param {number} length
- *          number of overlays that we currently visualize
- *
- * @returns {PromiseLike}
- */
-CustomMap.prototype.resizeSelectedDataOverlay = function (overlayId, index, length) {
-  logger.debug("Resize overlay: " + overlayId);
-  var promises = [];
-  promises.push(this._resizeSelectedDataOverlay(overlayId, index, length));
-  for (var i = 0; i < this.submaps.length; i++) {
-    promises.push(this.submaps[i]._resizeSelectedDataOverlay(overlayId, index, length));
-  }
-  return Promise.all(promises);
-};
-
-/**
- * Show overlay on the map and all submaps.
- *
- * @param {number} overlayId
- *          identifier of overlay to show
- * @param {number} index
- *          position of the overlay in list of overlays that we visualize
- * @param {number} length
- *          number of overlays that we currently visualize
- *
- * @returns {PromiseLike}
- */
-CustomMap.prototype.showSelectedDataOverlay = function (overlayId, index, length) {
-  logger.debug("Show overlay: " + overlayId);
-  var promises = [];
-  promises.push(this._showSelectedDataOverlay(overlayId, index, length));
-
-  for (var i = 0; i < this.submaps.length; i++) {
-    promises.push(this.submaps[i]._showSelectedDataOverlay(overlayId, index, length));
-  }
-  return Promise.all(promises);
-};
-
-/**
- * This method checks if the overlay contains any overlays (like AliasSurface or
- * ReactionSurface) that is currently visible on the map.
- *
- * @param {number} overlayId
- *          identifier of the overlay
- * @returns {boolean} <code>true</code> if the overlay contains overlays to
- *          visualize, <code>false</code> otherwise
- */
-CustomMap.prototype.layoutContainsOverlays = function (overlayId) {
-
-  // first, check top map
-  if (this.selectedLayoutOverlays[overlayId] !== undefined && this.selectedLayoutOverlays[overlayId].length > 0) {
-    return true;
-  }
-
-  // now check all submaps
-  for (var i = 0; i < this.submaps.length; i++) {
-    if (this.submaps[i].isInitialized()) {
-      if (this.submaps[i].selectedLayoutOverlays[overlayId] !== undefined
-        && this.submaps[i].selectedLayoutOverlays[overlayId].length > 0) {
-        return true;
-      }
-    }
-  }
-  return false;
-};
-
-/**
- * Renders markers, lines, etc. for elements highlighted in OverlayCollection.
- *
- * @param {boolean} params.fitBounds <code>true</code> if the borders should fit bounds after creating
- *          all elements
- * @param {AbstractDbOverlay} params.overlayCollection to be processed
- *
- * @param params
- * @returns {PromiseLike}
- */
-CustomMap.prototype.renderOverlayCollection = function (params) {
-  var self = this;
-  var fitBounds = params.fitBounds;
-  var overlayCollection = params.overlayCollection;
-
-  var elements;
-  var submaps = self.getSubmaps().concat([self]);
-
-  return overlayCollection.getIdentifiedElements().then(function (identifiedElements) {
-    return self.appendElementsPointingToSubmap(identifiedElements, overlayCollection);
-  }).then(function (identifiedElements) {
-    elements = identifiedElements;
-    var promises = [];
-    for (var i = 0; i < submaps.length; i++) {
-      promises.push(submaps[i].getMarkerSurfaceCollection().renderOverlay(identifiedElements, overlayCollection));
-    }
-    return Promise.all(promises);
-  }).then(function () {
-    return self.fetchIdentifiedElements(elements, true);
-  }).then(function (fullElements) {
-    var promises = [];
-    if (elements.length > 0 && fitBounds) {
-      for (var j = 0; j < submaps.length; j++) {
-        promises.push(submaps[j].fitBounds(fullElements));
-      }
-    }
-    return Promise.all(promises);
-  });
-};
-
-/**
- *
- * @param {IdentifiedElement[]} identifiedElements
- * @param {AbstractDbOverlay} overlayDb
- * @returns {PromiseLike}
- */
-CustomMap.prototype.appendElementsPointingToSubmap = function (identifiedElements, overlayDb) {
-  var self = this;
-  var existingElements = {};
-  var i;
-  for (i = 0; i < identifiedElements.length; i++) {
-    var element = identifiedElements[i];
-    existingElements[element.getId() + "_" + element.getIcon() + "_" + element.getType()] = true;
-  }
-  return Promise.each(identifiedElements, function (ie) {
-    return self.getProject().getElementsPointingToSubmap(ie.getModelId()).then(function (elementsPointingToSubmap) {
-      for (var j = 0; j < elementsPointingToSubmap.length; j++) {
-        var element = elementsPointingToSubmap[j];
-        if (!existingElements[element.getId() + "_" + ie.getIcon() + "_" + element.getType()]) {
-          existingElements[element.getId() + "_" + ie.getIcon() + "_" + element.getType()] = true;
-          var newElement = new IdentifiedElement(elementsPointingToSubmap[j]);
-          if (ie.getIcon() === undefined) {
-            newElement.setIcon(overlayDb.getIcon(0));
-          } else {
-            newElement.setIcon(ie.getIcon());
-          }
-
-          identifiedElements.push(newElement);
-        }
-      }
-    })
-  });
-};
-
-
-/**
- * Opens {@link AbstractInfoWindow} for a marker.
- *
- * @param {Marker} [marker]
- *           for which info window should be opened
- * @param {IdentifiedElement} element
- *           for which info window should be opened
- *
- * @returns {PromiseLike<AbstractInfoWindow>|Promise<AbstractInfoWindow>}
- */
-CustomMap.prototype.openInfoWindowForIdentifiedElement = function (element, marker) {
-  var self = this;
-  var submap = self.getSubmapById(element.getModelId());
-  logger.debug(element + ": Opening info window");
-
-  var infoWindow;
-  return submap._openInfoWindowForIdentifiedElement(element, marker).then(function () {
-    infoWindow = submap.returnInfoWindowForIdentifiedElement(element);
-    return self.retrieveOverlayDetailDataForElement(element, infoWindow.getOverlayFullViewArray());
-  }).then(function () {
-    return infoWindow;
-  });
-};
-
-/**
- * Sends requests to download detailed data about element in all
- * {OverlayCollection}.
- *
- * @param {IdentifiedElement} element
- *          element for which we want to have detailed information
- * @param {Object.<string,boolean>} general
- */
-CustomMap.prototype.retrieveOverlayDetailDataForElement = function (element, general) {
-  var promises = [];
-  if (general === undefined) {
-    logger.warn("general param is undefined!");
-    general = {};
-  }
-  var overlays = this.getDbOverlays();
-  for (var i = 0; i < overlays.length; i++) {
-    var overlay = overlays[i];
-
-    var generalRequest = general[overlay.getName()];
-    if (generalRequest === undefined) {
-      logger.warn("No information about general overlay request for overlay: " + overlay.getName());
-      generalRequest = false;
-    }
-    generalRequest = generalRequest || (!overlay.allowSearchById() && overlay.allowGeneralSearch());
-
-    promises.push(overlay.getDetailDataByIdentifiedElement(element, generalRequest));
-  }
-  return Promise.all(promises);
-};
-
-/**
- * Returns data from all {OverlayCollection} for a given alias.
- *
- * @param {Alias} alias
- *           for which overlay data will be returned
- * @param {Object.<string,boolean>} general
- *          if true then all elements will be returned, if false then only ones
- *          available right now in the overlay
- * @returns {Promise} of the data from all {OverlayCollection} for a given alias
- */
-CustomMap.prototype.getOverlayDataForAlias = function (alias, general) {
-  var identifiedElement = new IdentifiedElement(alias);
-  return this.getOverlayDataForIdentifiedElement(identifiedElement, general);
-};
-
-/**
- * Returns data from all {OverlayCollection} for a given reaction.
- *
- * @param {Reaction} reaction
- *           for which overlay data will be returned
- * @param {Object.<string,boolean>} general
- * @returns {Promise} of data from all {OverlayCollection} for a given alias
- */
-CustomMap.prototype.getOverlayDataForReaction = function (reaction, general) {
-  var identifiedElement = new IdentifiedElement(reaction);
-  return this.getOverlayDataForIdentifiedElement(identifiedElement, general);
-};
-
-/**
- * Returns data from all {OverlayCollection} for a given {PointData}
- *
- * @param {Object.<string,boolean>} general
- * @param {PointData} point
- *           for which overlay data will be returned
- * @returns {Promise} of data from all {OverlayCollection} for a given
- *          {PointData}
- */
-CustomMap.prototype.getOverlayDataForPoint = function (point, general) {
-  var identifiedElement = new IdentifiedElement(point);
-  return this.getOverlayDataForIdentifiedElement(identifiedElement, general);
-};
-
-/**
- * Returns data from all {OverlayCollection} for element identified by the
- * parameter
- *
- * @param {Object.<string,boolean>} general
- * @param {IdentifiedElement} identifiedElement
- *           for which overlay data will be returned
- * @returns {Promise} of data from all {OverlayCollection} for a given
- *          {IdentifiedElement}
- */
-CustomMap.prototype.getOverlayDataForIdentifiedElement = function (identifiedElement, general) {
-  if (general === undefined) {
-    logger.warn("general parameter must be defined");
-    general = [];
-  }
-  var promises = [];
-  var overlays = [];
-  var allOverlays = this.getDbOverlays();
-  for (var i = 0; i < allOverlays.length; i++) {
-    var overlay = allOverlays[i];
-    if (overlay.allowGeneralSearch() || overlay.allowSearchById()) {
-      var generalFlag = general[overlay.getName()];
-      if (generalFlag === undefined) {
-        logger.warn("General flag for overlay: " + overlay.getName() + " is not defined, assuming false");
-        generalFlag = false;
-      }
-      overlays.push(overlay);
-      promises.push(overlay.getDetailDataByIdentifiedElement(identifiedElement, !overlay.allowSearchById()
-        || generalFlag));
-
-    }
-  }
-  return Promise.all(promises).then(function (values) {
-    var result = [];
-    for (var i = 0; i < values.length; i++) {
-      result.push({
-        overlay: overlays[i],
-        data: values[i]
-      });
-    }
-    return result;
-  });
-};
-
-/**
- *
- * @param {string} name
- * @returns {AbstractDbOverlay}
- */
-CustomMap.prototype.getOverlayByName = function (name) {
-  return this.overlayCollections[name];
-};
-
-/**
- *
- * @returns {AbstractDbOverlay[]}
- */
-CustomMap.prototype.getDbOverlays = function () {
-  var result = [];
-  for (var overlayName in this.overlayCollections) {
-    if (this.overlayCollections.hasOwnProperty(overlayName)) {
-      result.push(this.overlayCollections[overlayName]);
-    }
-  }
-  return result;
-};
-
-/**
- * Returns {@link AbstractInfoWindow} for element identified by the parameter.
- *
- * @param {IdentifiedElement} identifiedElement
- *           that determines for which element we want
- *          {AbstractInfoWindow}
- * @returns {AbstractInfoWindow} for element identified by the parameter
- */
-CustomMap.prototype.getInfoWindowForIdentifiedElement = function (identifiedElement) {
-  var model = this.getSubmapById(identifiedElement.modelId);
-  var infoWindow = null;
-  if (identifiedElement.type === "ALIAS") {
-    infoWindow = model.getAliasInfoWindowById(identifiedElement.getId());
-  } else if (identifiedElement.type === "POINT") {
-    infoWindow = model.getPointInfoWindowById(identifiedElement.getId());
-  } else if (identifiedElement.type === "REACTION") {
-    infoWindow = model.getReactionInfoWindowById(identifiedElement.getId());
-  } else {
-    throw new Error("Unknown type of IdentifiedElement: " + identifiedElement.type);
-  }
-  return infoWindow;
-};
-
-/**
- *
- * @returns {number}
- */
-CustomMap.prototype.getActiveSubmapId = function () {
-  return this._activeSubmapId;
-};
-
-/**
- *
- * @param {number} submapId
- */
-CustomMap.prototype.setActiveSubmapId = function (submapId) {
-  this._activeSubmapId = submapId;
-};
-
-/**
- *
- * @param {Point} coordinates
- */
-CustomMap.prototype.setActiveSubmapClickCoordinates = function (coordinates) {
-  if (!(coordinates instanceof Point)) {
-    throw new Error("Coordinates must be provided as Point object, but found: " + coordinates);
-  }
-  this._activeSubmapCoordinates = coordinates;
-};
-
-/**
- *
- * @returns {Point}
- */
-CustomMap.prototype.getActiveSubmapClickCoordinates = function () {
-  return this._activeSubmapCoordinates;
-};
-
-/**
- *
- * @param {string} type
- * @param {string} version
- * @returns {PromiseLike}
- */
-CustomMap.prototype.getReferenceGenome = function (type, version) {
-  var self = this;
-  if (self.getProject().getOrganism() === undefined) {
-    return Promise.resolve(new ReferenceGenome(null));
-  }
-
-  if (self._referenceGenome[type] === undefined) {
-    self._referenceGenome[type] = [];
-  }
-  if (self._referenceGenome[type][version] === undefined) {
-    return self.getServerConnector().getReferenceGenome({
-      type: type,
-      version: version,
-      organism: self.getProject().getOrganism().getResource()
-    }).then(function (genome) {
-      self._referenceGenome[type][version] = genome;
-      return genome;
-    });
-  } else {
-    return Promise.resolve(self._referenceGenome[type][version]);
-  }
-};
-
-/**
- *
- * @returns {CustomMap}
- */
-CustomMap.prototype.getTopMap = function () {
-  return this;
-};
-
-/**
- *
- * @param {HTMLElement} element
- */
-CustomMap.prototype.addControl = function (element) {
-  if (this._controls[element.id] !== undefined) {
-    throw new Error("Element with id " + element.id + " already added to controls");
-  }
-  if (ControlType[element.id] === undefined) {
-    throw new Error("Unknown control type: " + element.id);
-  }
-  this._controls[element.id] = element;
-};
-
-/**
- *
- * @param {string} type
- * @returns {HTMLElement}
- */
-CustomMap.prototype.getControl = function (type) {
-  if (ControlType[type] === undefined) {
-    throw new Error("Unknown control type: " + type);
-  }
-  return this._controls[type];
-};
-
-/**
- *
- * @param {CommentDialog} commentDialog
- */
-CustomMap.prototype.setCommentDialog = function (commentDialog) {
-  this._commentDialog = commentDialog;
-};
-
-/**
- *
- * @returns {CommentDialog}
- */
-CustomMap.prototype.getCommentDialog = function () {
-  return this._commentDialog;
-};
-
-/**
- *
- * @param {ContextMenu} contextMenu
- */
-CustomMap.prototype.setContextMenu = function (contextMenu) {
-  this._contextMenu = contextMenu;
-};
-
-/**
- *
- * @returns {ContextMenu}
- */
-CustomMap.prototype.getContextMenu = function () {
-  return this._contextMenu;
-};
-
-/**
- *
- * @param {SelectionContextMenu} selectionContextMenu
- */
-CustomMap.prototype.setSelectionContextMenu = function (selectionContextMenu) {
-  this._selectionContextMenu = selectionContextMenu;
-};
-
-/**
- *
- * @returns {SelectionContextMenu}
- */
-CustomMap.prototype.getSelectionContextMenu = function () {
-  return this._selectionContextMenu;
-};
-
-/**
- *
- * @returns {PromiseLike|Promise}
- */
-CustomMap.prototype.openCommentDialog = function () {
-  var self = this;
-  return self.getServerConnector().getClosestElementsByCoordinates({
-    modelId: this.getActiveSubmapId(),
-    coordinates: this.getActiveSubmapClickCoordinates()
-  }).then(function (elements) {
-    var commentDialog = self.getCommentDialog();
-    if (commentDialog === undefined) {
-      var div = Functions.createElement({
-        type: "div"
-      });
-      self.getElement().appendChild(div);
-      commentDialog = new CommentDialog({
-        element: div,
-        customMap: self
-      });
-      self.setCommentDialog(commentDialog);
-    }
-    self.setCommentDialog(commentDialog);
-
-    return commentDialog.open(elements);
-  });
-};
-
-/**
- *
- * @param {IdentifiedElement[]} elements
- * @param {boolean} complete
- * @returns {PromiseLike<BioEntity[]> | Promise<BioEntity[]>}
- */
-CustomMap.prototype.fetchIdentifiedElements = function (elements, complete) {
-  var modelIds = [];
-  var modelElements = [];
-  var i;
-  for (i = 0; i < elements.length; i++) {
-    var element = elements[i];
-    if (modelElements[element.getModelId()] === undefined) {
-      modelIds.push(element.getModelId());
-      modelElements[element.getModelId()] = [];
-    }
-    modelElements[element.getModelId()].push(element);
-  }
-
-  var promises = [];
-  for (i = 0; i < modelIds.length; i++) {
-    var modelId = modelIds[i];
-    promises.push(this.getSubmapById(modelId).getModel().getByIdentifiedElements(modelElements[modelId], complete));
-  }
-  var result = [];
-  return Promise.all(promises).then(function (data) {
-    for (var i = 0; i < data.length; i++) {
-      result.push.apply(result, data[i]);
-    }
-    return result;
-  });
-
-};
-
-
-/**
- *
- * @param {string} polygonData
- */
-CustomMap.prototype.setSelectedPolygon = function (polygonData) {
-  this._selectedPolygon = polygonData;
-};
-
-/**
- *
- * @returns {string}
- */
-CustomMap.prototype.getSelectedPolygon = function () {
-  return this._selectedPolygon;
-};
-
-/**
- *
- * @param {number} params.modelId
- * @param {IdentifiedElement} params.element
- * @param {Point} params.coordinates
- *
- * @returns {PromiseLike|Promise}
- */
-CustomMap.prototype.getDistance = function (params) {
-  var self = this;
-  var ie = params.element;
-  var model = self.getSubmapById(ie.getModelId()).getModel();
-  if (ie.getModelId() !== params.modelId) {
-    throw new Error("Element and coordinates are on different maps: " + ie.getModelId() + ", " + params.modelId);
-  }
-  var x = params.coordinates.x;
-  var y = params.coordinates.y;
-  var p1 = new Point(x, y);
-  return model.getByIdentifiedElement(ie).then(function (element) {
-    if (element instanceof Alias) {
-      if (element.getX() <= x && element.getX() + element.getWidth() >= x) {
-        if (element.getY() <= y && element.getY() + element.getHeight() >= y) {
-          return 0;
-        } else {
-          return Math.min( //
-            Math.abs(element.getY() - y), //
-            Math.abs(element.getY() + element.getHeight() - y) //
-          );
-        }
-      } else if (element.getY() <= y && element.getY() + element.getHeight() >= y) {
-        return Math.min( //
-          Math.abs(element.getX() - x), //
-          Math.abs(element.getX() + element.getWidth() - x) //
-        );
-      } else {
-        var elementX = element.getX();
-        var elementY = element.getY();
-        var elementWidth = element.getWidth();
-        var elementHeight = element.getHeight();
-        return Math.min( //
-          Functions.distance(p1, new Point(elementX, y)), //
-          Functions.distance(p1, new Point(elementX + elementWidth, elementY)), //
-          Functions.distance(p1, new Point(elementX, elementY + elementHeight)), //
-          Functions.distance(p1, new Point(elementX + elementWidth, elementY + elementHeight)) //
-        );
-      }
-    } else if (element instanceof Reaction) {
-      var distance = Number.POSITIVE_INFINITY;
-      var lines = element.getLines();
-      for (var i = 0; i < lines.length; i++) {
-        distance = Math.min(distance, Functions.distance(p1, lines[i]));
-      }
-      return distance;
-    } else {
-      throw new Error("Unknown element type: " + (typeof element));
-    }
-  });
-};
-
-/**
- *
- * @returns {Submap[]}
- */
-CustomMap.prototype.getSubmaps = function () {
-  var submaps = this.submaps;
-  if (submaps === undefined) {
-    submaps = [];
-  }
-  return submaps;
-};
-
-CustomMap.prototype.destroy = function () {
-  var self = this;
-  AbstractCustomMap.prototype.destroy.call(self);
-  var commentDialog = self.getCommentDialog();
-  if (commentDialog !== undefined) {
-    commentDialog.destroy();
-  }
-  var submaps = self.getSubmaps();
-  for (var i = 0; i < submaps.length; i++) {
-    submaps[i].destroy();
-  }
-  if (self.getContextMenu() !== undefined) {
-    self.getContextMenu().destroy();
-  }
-  if (self.getSelectionContextMenu() !== undefined) {
-    self.getSelectionContextMenu().destroy();
-  }
-};
-
-/**
- *
- * @returns {Promise<DataOverlay[]>}
- */
-CustomMap.prototype.getVisibleDataOverlays = function () {
-  var dataOverlayPromises = [];
-
-  for (var key in this._selectedOverlays) {
-    if (this._selectedOverlays.hasOwnProperty(key) && this._selectedOverlays[key] === true) {
-      dataOverlayPromises.push(this.getProject().getDataOverlayById(parseInt(key)));
-    }
-  }
-
-  return Promise.all(dataOverlayPromises).then(function (overlays) {
-    overlays.sort(function (dataOverlay1, dataOverlay2) {
-      if (dataOverlay1.getOrder() < dataOverlay2.getOrder())
-        return -1;
-      if (dataOverlay1.getOrder() > dataOverlay2.getOrder())
-        return 1;
-      return 0;
-    });
-
-    return overlays;
-  });
-};
-
-
-module.exports = CustomMap;
+"use strict";
+
+var Promise = require("bluebird");
+
+var logger = require('../logger');
+var Functions = require('../Functions');
+
+var AbstractCustomMap = require('./AbstractCustomMap');
+var Alias = require('./data/Alias');
+var CommentDialog = require('../gui/CommentDialog');
+var ConfigurationType = require('../ConfigurationType');
+var ControlType = require('./ControlType');
+var CustomMapOptions = require('./CustomMapOptions');
+var GuiConnector = require('../GuiConnector');
+var IdentifiedElement = require('./data/IdentifiedElement');
+var DataOverlay = require('./data/DataOverlay');
+var Reaction = require('./data/Reaction');
+var ReferenceGenome = require('./data/ReferenceGenome');
+var SecurityError = require('../SecurityError');
+var Submap = require('./Submap');
+
+var Bounds = require('./canvas/Bounds');
+var Point = require('./canvas/Point');
+
+/**
+ * Default constructor.
+ *
+ * @param {CustomMapOptions} options
+ *          CustomMapOptions object representing all parameters needed for map
+ *          creation
+ *
+ * @constructor
+ * @extends AbstractCustomMap
+ */
+function CustomMap(options) {
+  //@type {HTMLElement[]}
+  this._controls = [];
+
+  if (!(options instanceof CustomMapOptions)) {
+    options = new CustomMapOptions(options);
+  }
+  AbstractCustomMap.call(this, options.getProject().getModels()[0], options);
+
+  this.registerListenerType("onBioEntityClick");
+  this.registerListenerType("onShowOverlay");
+  this.registerListenerType("onHideOverlay");
+  this.registerListenerType("onBackgroundOverlayChange");
+
+  // @type {boolean[]}
+  this._selectedOverlays = [];
+
+  this.customizeGoogleMapView(options.getElement());
+
+  this.createMapChangedCallbacks();
+
+  /**
+   *
+   * @type {Object.<string, AbstractDbOverlay>}
+   */
+  this.overlayCollections = {};
+
+  // which submap is active (where user made interaction for the last time)
+  // @type {number}
+  this._activeSubmapId = null;
+
+  // @type {boolean}
+  this.initialized = true;
+
+  // list of reference genomes
+  this._referenceGenome = [];
+
+  this.createSubmaps();
+
+  //@type {HTMLElement[]}
+  this._dialogs = [];
+}
+
+CustomMap.prototype = Object.create(AbstractCustomMap.prototype);
+CustomMap.prototype.constructor = CustomMap;
+
+/**
+ * This code must be run after the object is created. It requires to download
+ * some data via promises.
+ *
+ * @return {PromiseLike} with empty result
+ */
+CustomMap.prototype.init = function () {
+  var self = this;
+  var sessionData = self.getServerConnector().getSessionData(self.getProject());
+
+  // if we have background overlay stored in the session then restore it
+  var mapType = sessionData.getSelectedBackgroundOverlay();
+  // if we have user data overlays stored in the session then restore it
+  var ids = sessionData.getVisibleOverlays();
+  if (mapType !== undefined) {
+    ids.push(mapType);
+  }
+
+  return Promise.all([self.getMapCanvas().triggerListeners('resize'),
+    // noinspection SpellCheckingInspection
+    self.getMapCanvas().triggerListeners('maptypeid_changed'),
+    self.getMapCanvas().triggerListeners('projection_changed')
+  ]).then(function () {
+
+    // center map and zoom in to fit into browser window if there is no
+    // information about coordinates in the session
+
+    var x = self.getModel().getDefaultCenterX();
+    var y = self.getModel().getDefaultCenterY();
+    var zoom = self.getModel().getDefaultZoomLevel();
+    if (self.getServerConnector().getSessionData(self.getProject()).getCenter(self.getModel()) === undefined &&
+      (x === undefined || y === undefined || zoom === undefined ||
+        x === null || y === null || zoom === null
+      )) {
+      var bounds = new Bounds();
+      bounds.extend(self.getTopLeft());
+      bounds.extend(self.getBottomRight());
+
+      self.getMapCanvas().fitBounds(bounds);
+    }
+
+
+    return Promise.each(ids, function (overlayId) {
+      try {
+        return self.openDataOverlay(overlayId);
+      } catch (e) {
+        if (e instanceof SecurityError) {
+          logger.debug(e.message);
+          sessionData.setSelectedBackgroundOverlay(self.getProject().getDataOverlays()[0].getId());
+        } else {
+          return Promise.reject(e);
+        }
+      }
+    });
+  }).then(function () {
+    return self.getServerConnector().getLogoImg();
+  }).then(function (url) {
+    var logo2 = self.getControl(ControlType.LOGO_2_IMG);
+    if (!/^(f|ht)tps?:\/\//i.test(url)) {
+      url = GuiConnector.getImgPrefix() + url;
+    }
+    logo2.src = url;
+    logo2.setAttribute('title', self.getConfiguration().getOption(ConfigurationType.LOGO_TEXT).getValue());
+    logo2.setAttribute('alt', self.getConfiguration().getOption(ConfigurationType.LOGO_TEXT).getValue());
+  });
+};
+
+/**
+ * Create submaps.
+ */
+CustomMap.prototype.createSubmaps = function () {
+  this.submaps = [];
+  for (var i = 1; i < this.getProject().getModels().length; i++) {
+    this.submaps.push(new Submap(this, this.getProject().getModels()[i]));
+  }
+};
+
+/**
+ * Creates logo and put it on the google map.
+ */
+CustomMap.prototype.createLogo = function () {
+  var self = this;
+  var logoControlDiv2 = Functions.createElement({type: "div", index: 0});
+  var logo2 = Functions.createElement({
+    type: 'IMG',
+    style: "cursor: pointer; width: 80px",
+    id: ControlType.LOGO_2_IMG,
+    onclick: function () {
+      return self.getServerConnector().getLogoLink().then(function (url) {
+        var win = window.open(url, '_blank');
+        win.focus();
+      }).catch(GuiConnector.alert);
+    }
+  });
+  this.addControl(logo2);
+
+  logoControlDiv2.appendChild(logo2);
+
+  this.getMapCanvas().addLeftBottomControl(logoControlDiv2);
+
+  var logoControlDiv = Functions.createElement({type: "div", style: "padding: 5px", index: 1});
+  var logo = Functions.createElement({
+    type: "IMG",
+    src: GuiConnector.getImgPrefix() + GuiConnector.getLcsbLogoImg(this.bigButtons),
+    style: "cursor: pointer",
+    id: ControlType.LOGO_IMG,
+    onclick: function () {
+      var win = window.open('http://wwwen.uni.lu/lcsb/', '_blank');
+      win.focus();
+    }
+  });
+  this.addControl(logo);
+  logoControlDiv.appendChild(logo);
+
+  this.getMapCanvas().addRightBottomControl(logoControlDiv);
+};
+
+/**
+ * Clear all AbstractDbOverlay.
+ *
+ * @returns {PromiseLike}
+ */
+CustomMap.prototype.clearDbOverlays = function () {
+  var promises = [];
+  var overlays = this.getDbOverlays();
+  for (var i = 0; i < overlays.length; i++) {
+    promises.push(overlays[i].clear());
+  }
+  return Promise.all(promises);
+};
+
+/**
+ * Open data overlay given in the parameter.
+ *
+ * @param {DataOverlay|number|string} param
+ *          identifier or DataOverlay identifying data overlay to open
+ *
+ * @returns {PromiseLike|Promise}
+ */
+CustomMap.prototype.openDataOverlay = function (param) {
+  logger.debug("Opening data overlay: " + param);
+
+  var self = this;
+  var identifier = param;
+  if (param instanceof DataOverlay) {
+    identifier = param.getId();
+  }
+  identifier = parseInt(identifier);
+
+  if (isNaN(identifier)) {
+    throw new Error("invalid id: " + param);
+  }
+
+  var overlayToOpen = null;
+  var overlays = self.getProject().getDataOverlays();
+  for (var j = 0; j < overlays.length; j++) {
+    var overlay = overlays[j];
+    if (overlay.getId() === identifier) {
+      overlayToOpen = overlay;
+    }
+  }
+
+  if (overlayToOpen === null) {
+    throw new SecurityError("You have no privileges for selected overlay");
+  } else {
+    return overlayToOpen.init().then(function () {
+      if (overlayToOpen.getInputDataAvailable()) {
+        if (self._selectedOverlays[identifier] === true) {
+          logger.warn("Overlay " + identifier + " already selected");
+          return Promise.resolve();
+        } else {
+          self._selectedOverlays[identifier] = true;
+          return self.getVisibleDataOverlays().then(function (visibleDataOverlays) {
+            var ids = [];
+            for (var i = 0; i < visibleDataOverlays.length; i++) {
+              ids.push(visibleDataOverlays[i].getId());
+            }
+            self.getServerConnector().getSessionData(self.getProject()).setVisibleOverlays(ids);
+            return self.redrawSelectedDataOverlays();
+          }).then(function () {
+            var backgroundToOpen;
+            var overlays = self.getProject().getDataOverlays();
+            for (var i = 0; i < overlays.length; i++) {
+              var overlay = overlays[i];
+              if (overlay.getName().toLowerCase() === "empty") {
+                backgroundToOpen = overlay;
+              }
+            }
+            if (backgroundToOpen === undefined) {
+              logger.warn("Cannot find empty background overlay");
+            } else {
+              return self.openDataOverlay(backgroundToOpen.getId());
+            }
+          });
+        }
+      } else {
+        if (identifier.toString() === self.getMapCanvas().getBackgroundId()) {
+          return Promise.resolve();
+        } else {
+          self.getMapCanvas().setBackgroundId(identifier.toString());
+
+          var submaps = self.getSubmaps();
+          for (var i = 0; i < submaps.length; i++) {
+            var submap = submaps[i];
+            submap.openDataOverlay(identifier);
+          }
+          return self.callListeners("onBackgroundOverlayChange", identifier);
+        }
+      }
+    }).then(function () {
+      return self.callListeners("onShowOverlay", overlayToOpen);
+    });
+  }
+};
+
+/**
+ * Returns {DataOverlay} that is used as a background.
+ *
+ * @returns {DataOverlay}
+ */
+CustomMap.prototype.getBackgroundDataOverlay = function () {
+  var identifier = parseInt(this.getMapCanvas().getBackgroundId());
+  var overlays = this.getProject().getDataOverlays();
+  for (var i = 0; i < overlays.length; i++) {
+    var overlay = overlays[i];
+    if (overlay.getId() === identifier) {
+      return overlay;
+    }
+  }
+  return null;
+};
+
+/**
+ * Register AbstractDbOverlay in the map.
+ *
+ * @param {AbstractDbOverlay} dbOverlay
+ *          database overlay to be connected to the map
+ */
+CustomMap.prototype.registerDbOverlay = function (dbOverlay) {
+  var self = this;
+
+  this.overlayCollections[dbOverlay.getName()] = dbOverlay;
+
+
+  if (dbOverlay.getName() !== undefined) {
+    if (dbOverlay.getName() === "search" || dbOverlay.getName().indexOf("plugin") === 0) {
+      dbOverlay.addListener("onSearch", function (e) {
+        return self.renderOverlayCollection({
+          overlayCollection: dbOverlay,
+          fitBounds: e.arg.fitBounds
+        });
+      });
+    }
+    if (dbOverlay.getName() === "drug" || dbOverlay.getName() === "chemical" || dbOverlay.getName() === "mirna") {
+      dbOverlay.addListener("onSearch", function (e) {
+        return self.renderOverlayCollection({
+          overlayCollection: dbOverlay,
+          fitBounds: e.arg.fitBounds
+        });
+      });
+
+      dbOverlay.addListener("onTargetVisibilityChange", function () {
+        return self.renderOverlayCollection({
+          overlayCollection: dbOverlay,
+          fitBounds: false
+        });
+      });
+    }
+    if (dbOverlay.getName() === "comment") {
+      var listener = function () {
+        return self.renderOverlayCollection({
+          overlayCollection: dbOverlay,
+          fitBounds: false
+        });
+      };
+      dbOverlay.addListener("onRefresh", listener);
+      dbOverlay.addListener("onClear", listener);
+    }
+  }
+
+};
+
+/**
+ * Refresh comment list.
+ *
+ * @return {PromiseLike} promise that is resolved when comment list is refreshed
+ */
+CustomMap.prototype.refreshComments = function () {
+  var self = this;
+
+  var commentDbOverlay = self.getOverlayByName("comment");
+  if (commentDbOverlay !== undefined) {
+    if (self.getServerConnector().getSessionData(self.getProject()).getShowComments()) {
+      return commentDbOverlay.refresh();
+    } else {
+      return commentDbOverlay.clear();
+    }
+  }
+  throw new Error("comment DbOverlay not found");
+};
+
+/**
+ * Turns on/off drawing module on google maps.
+ */
+CustomMap.prototype.toggleDrawing = function () {
+  var submap = this.getSubmapById(this.getActiveSubmapId());
+  if (submap !== undefined) {
+    submap.getMapCanvas().toggleDrawing();
+  } else {
+    throw new Error("Cannot find submodel with id: " + this.getActiveSubmapId());
+  }
+};
+
+/**
+ *
+ * @returns {PromiseLike}
+ */
+CustomMap.prototype.refreshMarkers = function () {
+  var promises = [];
+  logger.debug("Refresh Markers: ");
+
+  var overlays = this.getDbOverlays();
+  for (var i = 0; i < overlays.length; i++) {
+    promises.push(this.refreshOverlayMarkers(overlays[i]));
+  }
+
+  return Promise.all(promises);
+};
+
+/**
+ *
+ * @param {AbstractDbOverlay} overlay
+ * @returns {PromiseLike}
+ */
+CustomMap.prototype.refreshOverlayMarkers = function (overlay) {
+  var promises = [];
+  var self = this;
+  logger.debug("Refresh overlay: " + overlay.getName());
+
+  promises.push(self.getMarkerSurfaceCollection().refreshOverlayMarkers(overlay));
+  var submaps = self.getSubmaps();
+  for (var i = 0; i < submaps.length; i++) {
+    if (submaps[i].isInitialized()) {
+      promises.push(submaps[i].getMarkerSurfaceCollection().refreshOverlayMarkers(overlay));
+    }
+  }
+  return Promise.all(promises);
+};
+
+/**
+ * Returns HTML div that is attached to jQuery dialog that should be used for
+ * opening submap.
+ *
+ * @param {number} id
+ *          identifier of the submap
+ *
+ * @returns {HTMLElement}
+ */
+CustomMap.prototype.getSubmapDialogDiv = function (id) {
+  var dialogDiv = this._dialogs[id];
+
+  if (dialogDiv === undefined) {
+    dialogDiv = document.createElement("div");
+    dialogDiv.setAttribute("name", "dialog-" + id);
+
+    this._dialogs[id] = dialogDiv;
+
+    $(dialogDiv).dialog({
+      autoOpen: false
+    });
+  }
+  return dialogDiv;
+};
+
+/**
+ * Opens a dialog with a submodel.
+ *
+ * @param {number} id
+ * @returns {PromiseLike}
+ */
+CustomMap.prototype.openSubmap = function (id) {
+  var self = this;
+  var submap = self.getSubmapById(id);
+  if (submap === null) {
+    throw new Error("Unknown submap for id: " + id);
+  } else if (submap !== this) {
+    var wasInitialized = submap.isInitialized();
+
+    var dialogDiv = self.getSubmapDialogDiv(id);
+
+    submap.open(dialogDiv);
+
+    return this.openDataOverlay(self.getMapCanvas().getBackgroundId()).then(function () {
+      if (!wasInitialized) {
+        // now we have to visualize overlays
+        return self.getVisibleDataOverlays().then(function (overlays) {
+          var promises = [];
+          // show overlays that should be visualized (resize or show them)
+          for (var i = 0; i < overlays.length; i++) {
+            promises.push(submap._showSelectedDataOverlay(overlays[i].getId(), i, overlays.length));
+          }
+          return Promise.all(promises);
+        }).then(function () {
+          return self.refreshMarkers();
+        });
+      }
+    });
+  } else {
+    return Promise.resolve();
+  }
+
+};
+
+/**
+ *
+ * @param {HTMLElement} div
+ */
+CustomMap.prototype.customizeGoogleMapView = function (div) {
+  var self = this;
+
+  self.createMapCanvas(div);
+
+  self.createLogo();
+};
+
+/**
+ * Creates listeners for google.maps.Map object that will actualize the data in
+ * user session.
+ */
+CustomMap.prototype.createMapChangedCallbacks = function () {
+  this._createMapChangedCallbacks();
+  var self = this;
+  var sessionData = self.getServerConnector().getSessionData(self.getProject());
+
+  // listener for changing type of background overlay
+  // noinspection SpellCheckingInspection
+  this.getMapCanvas().addListener('maptypeid_changed', function () {
+    sessionData.setSelectedBackgroundOverlay(self.getMapCanvas().getBackgroundId());
+  });
+
+};
+
+/**
+ * Returns submap (or this map) by id.
+ *
+ * @param {number|string} identifier
+ *          identifier of the submap
+ * @returns {AbstractCustomMap} (submap or this map) with given identifier of the model
+ */
+CustomMap.prototype.getSubmapById = function (identifier) {
+  identifier = parseInt(identifier);
+  if (this.getId() === identifier) {
+    return this;
+  }
+  for (var i = 0; i < this.submaps.length; i++) {
+    if (this.submaps[i].getId() === identifier) {
+      return this.submaps[i];
+    }
+  }
+  logger.warn("Cannot find submodel with id: " + identifier);
+  return null;
+};
+
+/**
+ *
+ */
+CustomMap.prototype.removeSelection = function () {
+  var model = this.getSubmapById(this.getActiveSubmapId());
+  if (model !== null) {
+    model.getMapCanvas().removeSelection();
+  } else {
+    throw new Error("Cannot find submap with id: " + this.getActiveSubmapId());
+  }
+};
+
+/**
+ * Removes overlay from visualization.
+ *
+ * @param {number} identifier
+ *          identifier of overlay to remove
+ *
+ * @returns {PromiseLike}
+ */
+CustomMap.prototype.hideDataOverlay = function (identifier) {
+  var self = this;
+  logger.debug("Hiding overlay: " + identifier);
+
+  if (this._selectedOverlays[identifier] !== true) {
+    logger.warn("Overlay " + identifier + " is not selected");
+    return Promise.resolve();
+  } else {
+    self._selectedOverlays[identifier] = false;
+    return self.redrawSelectedDataOverlays().then(function () {
+      return self.getVisibleDataOverlays();
+    }).then(function (visibleDataOverlays) {
+      var ids = [];
+      for (var i = 0; i < visibleDataOverlays.length; i++) {
+        ids.push(visibleDataOverlays[i].getId());
+      }
+      self.getServerConnector().getSessionData(self.getProject()).setVisibleOverlays(ids);
+      return self.redrawSelectedDataOverlays();
+    }).then(function () {
+      return self.getProject().getDataOverlayById(identifier);
+    }).then(function (overlay) {
+      return self.callListeners("onHideOverlay", overlay);
+    });
+  }
+};
+
+/**
+ * Redrawing selected overlays.
+ *
+ * @returns {PromiseLike|Promise}
+ */
+CustomMap.prototype.redrawSelectedDataOverlays = function () {
+  logger.debug("Redrawing overlays");
+  var self = this;
+  return self.getVisibleDataOverlays().then(function (visibleDataOverlays) {
+    // show overlays that should be visualized (resize or show them)
+    var promises = [];
+    for (var i = 0; i < visibleDataOverlays.length; i++) {
+      var overlayId = visibleDataOverlays[i].getId();
+      if (self.layoutContainsOverlays(overlayId)) {
+        // resize element on the map
+        promises.push(self.resizeSelectedDataOverlay(overlayId, i, visibleDataOverlays.length));
+      } else {
+        promises.push(self.showSelectedDataOverlay(overlayId, i, visibleDataOverlays.length));
+      }
+    }
+    return Promise.all(promises);
+  }).then(function () {
+    var promises = [];
+    // hide overlays that were visible
+    var overlays = self.getProject().getDataOverlays();
+    for (var i = 0; i < overlays.length; i++) {
+      var id = overlays[i].getId();
+      if (!self._selectedOverlays[id] && self.layoutContainsOverlays(id)) {
+        promises.push(self.hideSelectedLayout(id));
+      }
+    }
+    return Promise.all(promises);
+  });
+};
+
+/**
+ * Hides overlay on the map and all submaps
+ *
+ * @param {number} overlayId
+ *          identifier of a overlay to hide
+ *
+ * @returns {Promise}
+ */
+CustomMap.prototype.hideSelectedLayout = function (overlayId) {
+  var promises = [];
+  promises.push(this._hideSelectedLayout(overlayId));
+  for (var i = 0; i < this.submaps.length; i++) {
+    promises.push(this.submaps[i]._hideSelectedLayout(overlayId));
+  }
+  return Promise.all(promises);
+};
+
+/**
+ * Resize(refresh) overlay on the map and all submaps. Resizing should be called
+ * when number of overlays to visualize change.
+ *
+ * @param {number} overlayId
+ *          identifier of overlay to refresh
+ * @param {number} index
+ *          position of the overlay in list of overlays that we visualize
+ * @param {number} length
+ *          number of overlays that we currently visualize
+ *
+ * @returns {PromiseLike}
+ */
+CustomMap.prototype.resizeSelectedDataOverlay = function (overlayId, index, length) {
+  logger.debug("Resize overlay: " + overlayId);
+  var promises = [];
+  promises.push(this._resizeSelectedDataOverlay(overlayId, index, length));
+  for (var i = 0; i < this.submaps.length; i++) {
+    promises.push(this.submaps[i]._resizeSelectedDataOverlay(overlayId, index, length));
+  }
+  return Promise.all(promises);
+};
+
+/**
+ * Show overlay on the map and all submaps.
+ *
+ * @param {number} overlayId
+ *          identifier of overlay to show
+ * @param {number} index
+ *          position of the overlay in list of overlays that we visualize
+ * @param {number} length
+ *          number of overlays that we currently visualize
+ *
+ * @returns {PromiseLike}
+ */
+CustomMap.prototype.showSelectedDataOverlay = function (overlayId, index, length) {
+  logger.debug("Show overlay: " + overlayId);
+  var promises = [];
+  promises.push(this._showSelectedDataOverlay(overlayId, index, length));
+
+  for (var i = 0; i < this.submaps.length; i++) {
+    promises.push(this.submaps[i]._showSelectedDataOverlay(overlayId, index, length));
+  }
+  return Promise.all(promises);
+};
+
+/**
+ * This method checks if the overlay contains any overlays (like AliasSurface or
+ * ReactionSurface) that is currently visible on the map.
+ *
+ * @param {number} overlayId
+ *          identifier of the overlay
+ * @returns {boolean} <code>true</code> if the overlay contains overlays to
+ *          visualize, <code>false</code> otherwise
+ */
+CustomMap.prototype.layoutContainsOverlays = function (overlayId) {
+
+  // first, check top map
+  if (this.selectedLayoutOverlays[overlayId] !== undefined && this.selectedLayoutOverlays[overlayId].length > 0) {
+    return true;
+  }
+
+  // now check all submaps
+  for (var i = 0; i < this.submaps.length; i++) {
+    if (this.submaps[i].isInitialized()) {
+      if (this.submaps[i].selectedLayoutOverlays[overlayId] !== undefined
+        && this.submaps[i].selectedLayoutOverlays[overlayId].length > 0) {
+        return true;
+      }
+    }
+  }
+  return false;
+};
+
+/**
+ * Renders markers, lines, etc. for elements highlighted in OverlayCollection.
+ *
+ * @param {boolean} params.fitBounds <code>true</code> if the borders should fit bounds after creating
+ *          all elements
+ * @param {AbstractDbOverlay} params.overlayCollection to be processed
+ *
+ * @param params
+ * @returns {PromiseLike}
+ */
+CustomMap.prototype.renderOverlayCollection = function (params) {
+  var self = this;
+  var fitBounds = params.fitBounds;
+  var overlayCollection = params.overlayCollection;
+
+  var elements;
+  var submaps = self.getSubmaps().concat([self]);
+
+  return overlayCollection.getIdentifiedElements().then(function (identifiedElements) {
+    return self.appendElementsPointingToSubmap(identifiedElements, overlayCollection);
+  }).then(function (identifiedElements) {
+    elements = identifiedElements;
+    var promises = [];
+    for (var i = 0; i < submaps.length; i++) {
+      promises.push(submaps[i].getMarkerSurfaceCollection().renderOverlay(identifiedElements, overlayCollection));
+    }
+    return Promise.all(promises);
+  }).then(function () {
+    return self.fetchIdentifiedElements(elements, true);
+  }).then(function (fullElements) {
+    var promises = [];
+    if (elements.length > 0 && fitBounds) {
+      for (var j = 0; j < submaps.length; j++) {
+        promises.push(submaps[j].fitBounds(fullElements));
+      }
+    }
+    return Promise.all(promises);
+  });
+};
+
+/**
+ *
+ * @param {IdentifiedElement[]} identifiedElements
+ * @param {AbstractDbOverlay} overlayDb
+ * @returns {PromiseLike}
+ */
+CustomMap.prototype.appendElementsPointingToSubmap = function (identifiedElements, overlayDb) {
+  var self = this;
+  var existingElements = {};
+  var i;
+  for (i = 0; i < identifiedElements.length; i++) {
+    var element = identifiedElements[i];
+    existingElements[element.getId() + "_" + element.getIcon() + "_" + element.getType()] = true;
+  }
+  return Promise.each(identifiedElements, function (ie) {
+    return self.getProject().getElementsPointingToSubmap(ie.getModelId()).then(function (elementsPointingToSubmap) {
+      for (var j = 0; j < elementsPointingToSubmap.length; j++) {
+        var element = elementsPointingToSubmap[j];
+        if (!existingElements[element.getId() + "_" + ie.getIcon() + "_" + element.getType()]) {
+          existingElements[element.getId() + "_" + ie.getIcon() + "_" + element.getType()] = true;
+          var newElement = new IdentifiedElement(elementsPointingToSubmap[j]);
+          if (ie.getIcon() === undefined) {
+            newElement.setIcon(overlayDb.getIcon(0));
+          } else {
+            newElement.setIcon(ie.getIcon());
+          }
+
+          identifiedElements.push(newElement);
+        }
+      }
+    })
+  });
+};
+
+
+/**
+ * Opens {@link AbstractInfoWindow} for a marker.
+ *
+ * @param {Marker} [marker]
+ *           for which info window should be opened
+ * @param {IdentifiedElement} element
+ *           for which info window should be opened
+ *
+ * @returns {PromiseLike<AbstractInfoWindow>|Promise<AbstractInfoWindow>}
+ */
+CustomMap.prototype.openInfoWindowForIdentifiedElement = function (element, marker) {
+  var self = this;
+  var submap = self.getSubmapById(element.getModelId());
+  logger.debug(element + ": Opening info window");
+
+  var infoWindow;
+  return submap._openInfoWindowForIdentifiedElement(element, marker).then(function () {
+    infoWindow = submap.returnInfoWindowForIdentifiedElement(element);
+    return self.retrieveOverlayDetailDataForElement(element, infoWindow.getOverlayFullViewArray());
+  }).then(function () {
+    return infoWindow;
+  });
+};
+
+/**
+ * Sends requests to download detailed data about element in all
+ * {OverlayCollection}.
+ *
+ * @param {IdentifiedElement} element
+ *          element for which we want to have detailed information
+ * @param {Object.<string,boolean>} general
+ */
+CustomMap.prototype.retrieveOverlayDetailDataForElement = function (element, general) {
+  var promises = [];
+  if (general === undefined) {
+    logger.warn("general param is undefined!");
+    general = {};
+  }
+  var overlays = this.getDbOverlays();
+  for (var i = 0; i < overlays.length; i++) {
+    var overlay = overlays[i];
+
+    var generalRequest = general[overlay.getName()];
+    if (generalRequest === undefined) {
+      logger.warn("No information about general overlay request for overlay: " + overlay.getName());
+      generalRequest = false;
+    }
+    generalRequest = generalRequest || (!overlay.allowSearchById() && overlay.allowGeneralSearch());
+
+    promises.push(overlay.getDetailDataByIdentifiedElement(element, generalRequest));
+  }
+  return Promise.all(promises);
+};
+
+/**
+ * Returns data from all {OverlayCollection} for a given alias.
+ *
+ * @param {Alias} alias
+ *           for which overlay data will be returned
+ * @param {Object.<string,boolean>} general
+ *          if true then all elements will be returned, if false then only ones
+ *          available right now in the overlay
+ * @returns {Promise} of the data from all {OverlayCollection} for a given alias
+ */
+CustomMap.prototype.getOverlayDataForAlias = function (alias, general) {
+  var identifiedElement = new IdentifiedElement(alias);
+  return this.getOverlayDataForIdentifiedElement(identifiedElement, general);
+};
+
+/**
+ * Returns data from all {OverlayCollection} for a given reaction.
+ *
+ * @param {Reaction} reaction
+ *           for which overlay data will be returned
+ * @param {Object.<string,boolean>} general
+ * @returns {Promise} of data from all {OverlayCollection} for a given alias
+ */
+CustomMap.prototype.getOverlayDataForReaction = function (reaction, general) {
+  var identifiedElement = new IdentifiedElement(reaction);
+  return this.getOverlayDataForIdentifiedElement(identifiedElement, general);
+};
+
+/**
+ * Returns data from all {OverlayCollection} for a given {PointData}
+ *
+ * @param {Object.<string,boolean>} general
+ * @param {PointData} point
+ *           for which overlay data will be returned
+ * @returns {Promise} of data from all {OverlayCollection} for a given
+ *          {PointData}
+ */
+CustomMap.prototype.getOverlayDataForPoint = function (point, general) {
+  var identifiedElement = new IdentifiedElement(point);
+  return this.getOverlayDataForIdentifiedElement(identifiedElement, general);
+};
+
+/**
+ * Returns data from all {OverlayCollection} for element identified by the
+ * parameter
+ *
+ * @param {Object.<string,boolean>} general
+ * @param {IdentifiedElement} identifiedElement
+ *           for which overlay data will be returned
+ * @returns {Promise} of data from all {OverlayCollection} for a given
+ *          {IdentifiedElement}
+ */
+CustomMap.prototype.getOverlayDataForIdentifiedElement = function (identifiedElement, general) {
+  if (general === undefined) {
+    logger.warn("general parameter must be defined");
+    general = [];
+  }
+  var promises = [];
+  var overlays = [];
+  var allOverlays = this.getDbOverlays();
+  for (var i = 0; i < allOverlays.length; i++) {
+    var overlay = allOverlays[i];
+    if (overlay.allowGeneralSearch() || overlay.allowSearchById()) {
+      var generalFlag = general[overlay.getName()];
+      if (generalFlag === undefined) {
+        logger.warn("General flag for overlay: " + overlay.getName() + " is not defined, assuming false");
+        generalFlag = false;
+      }
+      overlays.push(overlay);
+      promises.push(overlay.getDetailDataByIdentifiedElement(identifiedElement, !overlay.allowSearchById()
+        || generalFlag));
+
+    }
+  }
+  return Promise.all(promises).then(function (values) {
+    var result = [];
+    for (var i = 0; i < values.length; i++) {
+      result.push({
+        overlay: overlays[i],
+        data: values[i]
+      });
+    }
+    return result;
+  });
+};
+
+/**
+ *
+ * @param {string} name
+ * @returns {AbstractDbOverlay}
+ */
+CustomMap.prototype.getOverlayByName = function (name) {
+  return this.overlayCollections[name];
+};
+
+/**
+ *
+ * @returns {AbstractDbOverlay[]}
+ */
+CustomMap.prototype.getDbOverlays = function () {
+  var result = [];
+  for (var overlayName in this.overlayCollections) {
+    if (this.overlayCollections.hasOwnProperty(overlayName)) {
+      result.push(this.overlayCollections[overlayName]);
+    }
+  }
+  return result;
+};
+
+/**
+ * Returns {@link AbstractInfoWindow} for element identified by the parameter.
+ *
+ * @param {IdentifiedElement} identifiedElement
+ *           that determines for which element we want
+ *          {AbstractInfoWindow}
+ * @returns {AbstractInfoWindow} for element identified by the parameter
+ */
+CustomMap.prototype.getInfoWindowForIdentifiedElement = function (identifiedElement) {
+  var model = this.getSubmapById(identifiedElement.modelId);
+  var infoWindow = null;
+  if (identifiedElement.type === "ALIAS") {
+    infoWindow = model.getAliasInfoWindowById(identifiedElement.getId());
+  } else if (identifiedElement.type === "POINT") {
+    infoWindow = model.getPointInfoWindowById(identifiedElement.getId());
+  } else if (identifiedElement.type === "REACTION") {
+    infoWindow = model.getReactionInfoWindowById(identifiedElement.getId());
+  } else {
+    throw new Error("Unknown type of IdentifiedElement: " + identifiedElement.type);
+  }
+  return infoWindow;
+};
+
+/**
+ *
+ * @returns {number}
+ */
+CustomMap.prototype.getActiveSubmapId = function () {
+  return this._activeSubmapId;
+};
+
+/**
+ *
+ * @param {number} submapId
+ */
+CustomMap.prototype.setActiveSubmapId = function (submapId) {
+  this._activeSubmapId = submapId;
+};
+
+/**
+ *
+ * @param {Point} coordinates
+ */
+CustomMap.prototype.setActiveSubmapClickCoordinates = function (coordinates) {
+  if (!(coordinates instanceof Point)) {
+    throw new Error("Coordinates must be provided as Point object, but found: " + coordinates);
+  }
+  this._activeSubmapCoordinates = coordinates;
+};
+
+/**
+ *
+ * @returns {Point}
+ */
+CustomMap.prototype.getActiveSubmapClickCoordinates = function () {
+  return this._activeSubmapCoordinates;
+};
+
+/**
+ *
+ * @param {string} type
+ * @param {string} version
+ * @returns {PromiseLike}
+ */
+CustomMap.prototype.getReferenceGenome = function (type, version) {
+  var self = this;
+  if (self.getProject().getOrganism() === undefined) {
+    return Promise.resolve(new ReferenceGenome(null));
+  }
+
+  if (self._referenceGenome[type] === undefined) {
+    self._referenceGenome[type] = [];
+  }
+  if (self._referenceGenome[type][version] === undefined) {
+    return self.getServerConnector().getReferenceGenome({
+      type: type,
+      version: version,
+      organism: self.getProject().getOrganism().getResource()
+    }).then(function (genome) {
+      self._referenceGenome[type][version] = genome;
+      return genome;
+    });
+  } else {
+    return Promise.resolve(self._referenceGenome[type][version]);
+  }
+};
+
+/**
+ *
+ * @returns {CustomMap}
+ */
+CustomMap.prototype.getTopMap = function () {
+  return this;
+};
+
+/**
+ *
+ * @param {HTMLElement} element
+ */
+CustomMap.prototype.addControl = function (element) {
+  if (this._controls[element.id] !== undefined) {
+    throw new Error("Element with id " + element.id + " already added to controls");
+  }
+  if (ControlType[element.id] === undefined) {
+    throw new Error("Unknown control type: " + element.id);
+  }
+  this._controls[element.id] = element;
+};
+
+/**
+ *
+ * @param {string} type
+ * @returns {HTMLElement}
+ */
+CustomMap.prototype.getControl = function (type) {
+  if (ControlType[type] === undefined) {
+    throw new Error("Unknown control type: " + type);
+  }
+  return this._controls[type];
+};
+
+/**
+ *
+ * @param {CommentDialog} commentDialog
+ */
+CustomMap.prototype.setCommentDialog = function (commentDialog) {
+  this._commentDialog = commentDialog;
+};
+
+/**
+ *
+ * @returns {CommentDialog}
+ */
+CustomMap.prototype.getCommentDialog = function () {
+  return this._commentDialog;
+};
+
+/**
+ *
+ * @param {ContextMenu} contextMenu
+ */
+CustomMap.prototype.setContextMenu = function (contextMenu) {
+  this._contextMenu = contextMenu;
+};
+
+/**
+ *
+ * @returns {ContextMenu}
+ */
+CustomMap.prototype.getContextMenu = function () {
+  return this._contextMenu;
+};
+
+/**
+ *
+ * @param {SelectionContextMenu} selectionContextMenu
+ */
+CustomMap.prototype.setSelectionContextMenu = function (selectionContextMenu) {
+  this._selectionContextMenu = selectionContextMenu;
+};
+
+/**
+ *
+ * @returns {SelectionContextMenu}
+ */
+CustomMap.prototype.getSelectionContextMenu = function () {
+  return this._selectionContextMenu;
+};
+
+/**
+ *
+ * @returns {PromiseLike|Promise}
+ */
+CustomMap.prototype.openCommentDialog = function () {
+  var self = this;
+  return self.getServerConnector().getClosestElementsByCoordinates({
+    modelId: this.getActiveSubmapId(),
+    coordinates: this.getActiveSubmapClickCoordinates()
+  }).then(function (elements) {
+    var commentDialog = self.getCommentDialog();
+    if (commentDialog === undefined) {
+      var div = Functions.createElement({
+        type: "div"
+      });
+      self.getElement().appendChild(div);
+      commentDialog = new CommentDialog({
+        element: div,
+        customMap: self
+      });
+      self.setCommentDialog(commentDialog);
+    }
+    self.setCommentDialog(commentDialog);
+
+    return commentDialog.open(elements);
+  });
+};
+
+/**
+ *
+ * @param {IdentifiedElement[]} elements
+ * @param {boolean} complete
+ * @returns {PromiseLike<BioEntity[]> | Promise<BioEntity[]>}
+ */
+CustomMap.prototype.fetchIdentifiedElements = function (elements, complete) {
+  var modelIds = [];
+  var modelElements = [];
+  var i;
+  for (i = 0; i < elements.length; i++) {
+    var element = elements[i];
+    if (modelElements[element.getModelId()] === undefined) {
+      modelIds.push(element.getModelId());
+      modelElements[element.getModelId()] = [];
+    }
+    modelElements[element.getModelId()].push(element);
+  }
+
+  var promises = [];
+  for (i = 0; i < modelIds.length; i++) {
+    var modelId = modelIds[i];
+    promises.push(this.getSubmapById(modelId).getModel().getByIdentifiedElements(modelElements[modelId], complete));
+  }
+  var result = [];
+  return Promise.all(promises).then(function (data) {
+    for (var i = 0; i < data.length; i++) {
+      result.push.apply(result, data[i]);
+    }
+    return result;
+  });
+
+};
+
+
+/**
+ *
+ * @param {string} polygonData
+ */
+CustomMap.prototype.setSelectedPolygon = function (polygonData) {
+  this._selectedPolygon = polygonData;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+CustomMap.prototype.getSelectedPolygon = function () {
+  return this._selectedPolygon;
+};
+
+/**
+ *
+ * @param {number} params.modelId
+ * @param {IdentifiedElement} params.element
+ * @param {Point} params.coordinates
+ *
+ * @returns {PromiseLike|Promise}
+ */
+CustomMap.prototype.getDistance = function (params) {
+  var self = this;
+  var ie = params.element;
+  var model = self.getSubmapById(ie.getModelId()).getModel();
+  if (ie.getModelId() !== params.modelId) {
+    throw new Error("Element and coordinates are on different maps: " + ie.getModelId() + ", " + params.modelId);
+  }
+  var x = params.coordinates.x;
+  var y = params.coordinates.y;
+  var p1 = new Point(x, y);
+  return model.getByIdentifiedElement(ie).then(function (element) {
+    if (element instanceof Alias) {
+      if (element.getX() <= x && element.getX() + element.getWidth() >= x) {
+        if (element.getY() <= y && element.getY() + element.getHeight() >= y) {
+          return 0;
+        } else {
+          return Math.min( //
+            Math.abs(element.getY() - y), //
+            Math.abs(element.getY() + element.getHeight() - y) //
+          );
+        }
+      } else if (element.getY() <= y && element.getY() + element.getHeight() >= y) {
+        return Math.min( //
+          Math.abs(element.getX() - x), //
+          Math.abs(element.getX() + element.getWidth() - x) //
+        );
+      } else {
+        var elementX = element.getX();
+        var elementY = element.getY();
+        var elementWidth = element.getWidth();
+        var elementHeight = element.getHeight();
+        return Math.min( //
+          Functions.distance(p1, new Point(elementX, y)), //
+          Functions.distance(p1, new Point(elementX + elementWidth, elementY)), //
+          Functions.distance(p1, new Point(elementX, elementY + elementHeight)), //
+          Functions.distance(p1, new Point(elementX + elementWidth, elementY + elementHeight)) //
+        );
+      }
+    } else if (element instanceof Reaction) {
+      var distance = Number.POSITIVE_INFINITY;
+      var lines = element.getLines();
+      for (var i = 0; i < lines.length; i++) {
+        distance = Math.min(distance, Functions.distance(p1, lines[i]));
+      }
+      return distance;
+    } else {
+      throw new Error("Unknown element type: " + (typeof element));
+    }
+  });
+};
+
+/**
+ *
+ * @returns {Submap[]}
+ */
+CustomMap.prototype.getSubmaps = function () {
+  var submaps = this.submaps;
+  if (submaps === undefined) {
+    submaps = [];
+  }
+  return submaps;
+};
+
+CustomMap.prototype.destroy = function () {
+  var self = this;
+  AbstractCustomMap.prototype.destroy.call(self);
+  var commentDialog = self.getCommentDialog();
+  if (commentDialog !== undefined) {
+    commentDialog.destroy();
+  }
+  var submaps = self.getSubmaps();
+  for (var i = 0; i < submaps.length; i++) {
+    submaps[i].destroy();
+  }
+  if (self.getContextMenu() !== undefined) {
+    self.getContextMenu().destroy();
+  }
+  if (self.getSelectionContextMenu() !== undefined) {
+    self.getSelectionContextMenu().destroy();
+  }
+};
+
+/**
+ *
+ * @returns {Promise<DataOverlay[]>}
+ */
+CustomMap.prototype.getVisibleDataOverlays = function () {
+  var dataOverlayPromises = [];
+
+  for (var key in this._selectedOverlays) {
+    if (this._selectedOverlays.hasOwnProperty(key) && this._selectedOverlays[key] === true) {
+      dataOverlayPromises.push(this.getProject().getDataOverlayById(parseInt(key)));
+    }
+  }
+
+  return Promise.all(dataOverlayPromises).then(function (overlays) {
+    overlays.sort(function (dataOverlay1, dataOverlay2) {
+      if (dataOverlay1.getOrder() < dataOverlay2.getOrder())
+        return -1;
+      if (dataOverlay1.getOrder() > dataOverlay2.getOrder())
+        return 1;
+      return 0;
+    });
+
+    return overlays;
+  });
+};
+
+
+module.exports = CustomMap;
diff --git a/frontend-js/src/main/js/map/CustomMapOptions.js b/frontend-js/src/main/js/map/CustomMapOptions.js
index e992f2a2e7237dce44b26653de114abe9e2ce35f..900823b53a48303f61ae66ea47b9d544e89aed58 100644
--- a/frontend-js/src/main/js/map/CustomMapOptions.js
+++ b/frontend-js/src/main/js/map/CustomMapOptions.js
@@ -1,170 +1,170 @@
-"use strict";
-
-var logger = require('./../logger');
-
-/**
- * Object representing information needed for constructing {@link CustomMap}
- * objects.
- *
- * @param {Object|CustomMapOptions} params
- * @param {HTMLElement} params.element
- * @param {Configuration} params.configuration
- * @param {Project} [params.project]
- * @param {string} params.projectId
- * @param {ServerConnector} params.serverConnector
- * @param {boolean} [params.bigLogo]
- * @param {boolean} [params.debug]
- * @param {Object} [params.plugins]
- *
- * @constructor
- */
-function CustomMapOptions(params) {
-  if (params.element === undefined) {
-    throw new Error("element must be defined");
-  }
-  this.setElement(params.element);
-  this.setConfiguration(params.configuration);
-  this.setProject(params.project);
-  this.setProjectId(params.projectId);
-  this.setServerConnector(params.serverConnector);
-
-  if (params.bigLogo !== undefined) {
-    if (typeof params.bigLogo === "boolean") {
-      this._bigLogo = params.bigLogo;
-    } else {
-      logger.warn("bigLogo must be of type boolean");
-      this._bigLogo = false;
-    }
-  } else {
-    this._bigLogo = false;
-  }
-
-  this.setDebug(params.debug);
-  this.setPlugins(params.plugins);
-
-}
-
-/**
- *
- * @returns {boolean}
- */
-CustomMapOptions.prototype.isBigLogo = function () {
-  return this._bigLogo;
-};
-
-/**
- *
- * @returns {Project}
- */
-CustomMapOptions.prototype.getProject = function () {
-  return this._project;
-};
-
-/**
- *
- * @param {Project} project
- */
-CustomMapOptions.prototype.setProject = function (project) {
-  this._project = project;
-};
-
-/**
- *
- * @returns {ServerConnector}
- */
-CustomMapOptions.prototype.getServerConnector = function () {
-  return this._serverConnector;
-};
-
-/**
- *
- * @param {ServerConnector} serverConnector
- */
-CustomMapOptions.prototype.setServerConnector = function (serverConnector) {
-  this._serverConnector = serverConnector;
-};
-
-CustomMapOptions.prototype.getPlugins = function () {
-  return this._plugins;
-};
-CustomMapOptions.prototype.setPlugins = function (plugins) {
-  if (plugins === undefined) {
-    plugins = [];
-  }
-  this._plugins = plugins;
-};
-
-/**
- *
- * @returns {Configuration}
- */
-CustomMapOptions.prototype.getConfiguration = function () {
-  return this._configuration;
-};
-
-/**
- *
- * @param {Configuration} configuration
- */
-CustomMapOptions.prototype.setConfiguration = function (configuration) {
-  this._configuration = configuration;
-};
-
-/**
- *
- * @returns {string}
- */
-CustomMapOptions.prototype.getProjectId = function () {
-  if (this.getProject() !== undefined) {
-    return this.getProject().getProjectId();
-  } else {
-    return this._projectId;
-  }
-};
-
-/**
- *
- * @param {string} projectId
- */
-CustomMapOptions.prototype.setProjectId = function (projectId) {
-  this._projectId = projectId;
-};
-
-/**
- *
- * @param {boolean} debug
- */
-CustomMapOptions.prototype.setDebug = function (debug) {
-  if (debug !== undefined) {
-    if (typeof debug !== "boolean") {
-      logger.warn("Params must be boolean");
-    }
-    this._debug = debug;
-  }
-};
-
-/**
- *
- * @returns {boolean}
- */
-CustomMapOptions.prototype.isDebug = function () {
-  return this._debug === true;
-};
-
-/**
- *
- * @param {HTMLElement} element
- */
-CustomMapOptions.prototype.setElement = function (element) {
-  this._element = element;
-};
-
-/**
- *
- * @returns {HTMLElement}
- */
-CustomMapOptions.prototype.getElement = function () {
-  return this._element;
-};
-
-module.exports = CustomMapOptions;
+"use strict";
+
+var logger = require('./../logger');
+
+/**
+ * Object representing information needed for constructing {@link CustomMap}
+ * objects.
+ *
+ * @param {Object|CustomMapOptions} params
+ * @param {HTMLElement} params.element
+ * @param {Configuration} params.configuration
+ * @param {Project} [params.project]
+ * @param {string} params.projectId
+ * @param {ServerConnector} params.serverConnector
+ * @param {boolean} [params.bigLogo]
+ * @param {boolean} [params.debug]
+ * @param {Object} [params.plugins]
+ *
+ * @constructor
+ */
+function CustomMapOptions(params) {
+  if (params.element === undefined) {
+    throw new Error("element must be defined");
+  }
+  this.setElement(params.element);
+  this.setConfiguration(params.configuration);
+  this.setProject(params.project);
+  this.setProjectId(params.projectId);
+  this.setServerConnector(params.serverConnector);
+
+  if (params.bigLogo !== undefined) {
+    if (typeof params.bigLogo === "boolean") {
+      this._bigLogo = params.bigLogo;
+    } else {
+      logger.warn("bigLogo must be of type boolean");
+      this._bigLogo = false;
+    }
+  } else {
+    this._bigLogo = false;
+  }
+
+  this.setDebug(params.debug);
+  this.setPlugins(params.plugins);
+
+}
+
+/**
+ *
+ * @returns {boolean}
+ */
+CustomMapOptions.prototype.isBigLogo = function () {
+  return this._bigLogo;
+};
+
+/**
+ *
+ * @returns {Project}
+ */
+CustomMapOptions.prototype.getProject = function () {
+  return this._project;
+};
+
+/**
+ *
+ * @param {Project} project
+ */
+CustomMapOptions.prototype.setProject = function (project) {
+  this._project = project;
+};
+
+/**
+ *
+ * @returns {ServerConnector}
+ */
+CustomMapOptions.prototype.getServerConnector = function () {
+  return this._serverConnector;
+};
+
+/**
+ *
+ * @param {ServerConnector} serverConnector
+ */
+CustomMapOptions.prototype.setServerConnector = function (serverConnector) {
+  this._serverConnector = serverConnector;
+};
+
+CustomMapOptions.prototype.getPlugins = function () {
+  return this._plugins;
+};
+CustomMapOptions.prototype.setPlugins = function (plugins) {
+  if (plugins === undefined) {
+    plugins = [];
+  }
+  this._plugins = plugins;
+};
+
+/**
+ *
+ * @returns {Configuration}
+ */
+CustomMapOptions.prototype.getConfiguration = function () {
+  return this._configuration;
+};
+
+/**
+ *
+ * @param {Configuration} configuration
+ */
+CustomMapOptions.prototype.setConfiguration = function (configuration) {
+  this._configuration = configuration;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+CustomMapOptions.prototype.getProjectId = function () {
+  if (this.getProject() !== undefined) {
+    return this.getProject().getProjectId();
+  } else {
+    return this._projectId;
+  }
+};
+
+/**
+ *
+ * @param {string} projectId
+ */
+CustomMapOptions.prototype.setProjectId = function (projectId) {
+  this._projectId = projectId;
+};
+
+/**
+ *
+ * @param {boolean} debug
+ */
+CustomMapOptions.prototype.setDebug = function (debug) {
+  if (debug !== undefined) {
+    if (typeof debug !== "boolean") {
+      logger.warn("Params must be boolean");
+    }
+    this._debug = debug;
+  }
+};
+
+/**
+ *
+ * @returns {boolean}
+ */
+CustomMapOptions.prototype.isDebug = function () {
+  return this._debug === true;
+};
+
+/**
+ *
+ * @param {HTMLElement} element
+ */
+CustomMapOptions.prototype.setElement = function (element) {
+  this._element = element;
+};
+
+/**
+ *
+ * @returns {HTMLElement}
+ */
+CustomMapOptions.prototype.getElement = function () {
+  return this._element;
+};
+
+module.exports = CustomMapOptions;
diff --git a/frontend-js/src/main/js/map/OverlayParser.js b/frontend-js/src/main/js/map/OverlayParser.js
index 239de8d595203d790a3d6ec10662ce9c0c8c1dfe..b785ca26b205f407e0c8c9254f1272fa34ee23a0 100644
--- a/frontend-js/src/main/js/map/OverlayParser.js
+++ b/frontend-js/src/main/js/map/OverlayParser.js
@@ -1,88 +1,88 @@
-"use strict";
-
-var logger = require('./../logger');
-var DataOverlay = require('./data/DataOverlay');
-var TextDecoder = require('text-encoding').TextDecoder;
-
-function OverlayParser() {
-}
-
-/**
- *
- * @param {string| Uint8Array | ArrayBuffer} content
- * @returns {string}
- * @private
- */
-OverlayParser.prototype._extractContent = function (content) {
-  if (content instanceof Uint8Array || content instanceof ArrayBuffer) {
-    content = new TextDecoder("UTF8").decode(content);
-  }
-  return content;
-};
-
-/**
- *
- * @param {string| Uint8Array|ArrayBuffer} content
- * @returns {DataOverlay}
- */
-OverlayParser.prototype.parse = function (content) {
-  content = this._extractContent(content);
-  var data = {content: content};
-  var lines = content.split("\n");
-  for (var i = 0; i < lines.length; i++) {
-    var line = lines[i];
-    if (line.indexOf("#") === 0) {
-      if (line.indexOf("=") > 0) {
-        var name = line.substring(1, line.indexOf("=")).trim();
-        var value = line.substring(line.indexOf("=") + 1).trim();
-        if (name === "NAME") {
-          data.name = value;
-        } else if (name === "DESCRIPTION") {
-          data.description = value;
-        } else if (name === "TYPE") {
-          data.type = value;
-        }
-      } else {
-        logger.warn("Invalid overlay header line: " + line);
-      }
-    } else {
-      break;
-    }
-  }
-
-  return new DataOverlay(data);
-};
-
-/**
- *
- * @param {string| Uint8Array | ArrayBuffer} content
- * @returns {boolean}
- */
-OverlayParser.prototype.containsMixedNewLineCharacters = function (content) {
-  content = this._extractContent(content);
-  var newLineRegEx = /[\r\n]+/g;
-  var match = newLineRegEx.exec(content);
-  var newLineFormats = {};
-  var counter = 0;
-  while (match !== null && match !== undefined) {
-    var foundMultiplication = false;
-    var key = '';
-    //this is just a heuristic - let's assume there are at most 10 empty lines in a file
-    for (var i = 0; i < 10; i++) {
-      key += match[0];
-      if (newLineFormats[key]) {
-        foundMultiplication = true;
-      } else {
-        newLineFormats[key] = true;
-      }
-    }
-    if (!foundMultiplication) {
-      counter++;
-    }
-    match = newLineRegEx.exec(content);
-  }
-  return counter > 1;
-};
-
-
-module.exports = OverlayParser;
+"use strict";
+
+var logger = require('./../logger');
+var DataOverlay = require('./data/DataOverlay');
+var TextDecoder = require('text-encoding').TextDecoder;
+
+function OverlayParser() {
+}
+
+/**
+ *
+ * @param {string| Uint8Array | ArrayBuffer} content
+ * @returns {string}
+ * @private
+ */
+OverlayParser.prototype._extractContent = function (content) {
+  if (content instanceof Uint8Array || content instanceof ArrayBuffer) {
+    content = new TextDecoder("UTF8").decode(content);
+  }
+  return content;
+};
+
+/**
+ *
+ * @param {string| Uint8Array|ArrayBuffer} content
+ * @returns {DataOverlay}
+ */
+OverlayParser.prototype.parse = function (content) {
+  content = this._extractContent(content);
+  var data = {content: content};
+  var lines = content.split("\n");
+  for (var i = 0; i < lines.length; i++) {
+    var line = lines[i];
+    if (line.indexOf("#") === 0) {
+      if (line.indexOf("=") > 0) {
+        var name = line.substring(1, line.indexOf("=")).trim();
+        var value = line.substring(line.indexOf("=") + 1).trim();
+        if (name === "NAME") {
+          data.name = value;
+        } else if (name === "DESCRIPTION") {
+          data.description = value;
+        } else if (name === "TYPE") {
+          data.type = value;
+        }
+      } else {
+        logger.warn("Invalid overlay header line: " + line);
+      }
+    } else {
+      break;
+    }
+  }
+
+  return new DataOverlay(data);
+};
+
+/**
+ *
+ * @param {string| Uint8Array | ArrayBuffer} content
+ * @returns {boolean}
+ */
+OverlayParser.prototype.containsMixedNewLineCharacters = function (content) {
+  content = this._extractContent(content);
+  var newLineRegEx = /[\r\n]+/g;
+  var match = newLineRegEx.exec(content);
+  var newLineFormats = {};
+  var counter = 0;
+  while (match !== null && match !== undefined) {
+    var foundMultiplication = false;
+    var key = '';
+    //this is just a heuristic - let's assume there are at most 10 empty lines in a file
+    for (var i = 0; i < 10; i++) {
+      key += match[0];
+      if (newLineFormats[key]) {
+        foundMultiplication = true;
+      } else {
+        newLineFormats[key] = true;
+      }
+    }
+    if (!foundMultiplication) {
+      counter++;
+    }
+    match = newLineRegEx.exec(content);
+  }
+  return counter > 1;
+};
+
+
+module.exports = OverlayParser;
diff --git a/frontend-js/src/main/js/map/Submap.js b/frontend-js/src/main/js/map/Submap.js
index 4811edf5c65d21de79eaa296ef65a820bfb5c222..59ebc5073017f87586196b571f0eece06c90de12 100644
--- a/frontend-js/src/main/js/map/Submap.js
+++ b/frontend-js/src/main/js/map/Submap.js
@@ -1,145 +1,145 @@
-"use strict";
-
-/* exported logger */
-
-// noinspection JSUnusedLocalSymbols
-var logger = require('../logger');
-var AbstractCustomMap = require('./AbstractCustomMap');
-var CustomMapOptions = require('./CustomMapOptions');
-
-/**
- * Constructor of a submap. Submaps are created on application start. But dialog
- * (popup window) is initialized on demand using init function.
- *
- * @param {CustomMap} customMap
- *          parent CustomMap
- * @param {MapModel} model
- *
- * @constructor
- * @extends AbstractCustomMap
- */
-function Submap(customMap, model) {
-  this.setCustomMap(customMap);
-
-  AbstractCustomMap.call(this, model, new CustomMapOptions({
-    element: customMap.getElement(),
-    bigLogo: customMap.isBigLogo(),
-    project: customMap.getProject(),
-    configuration: customMap.getConfiguration(),
-    projectId: customMap.getProject().getProjectId(),
-    debug: customMap.isDebug(),
-    serverConnector: customMap.getServerConnector()
-  }));
-
-  this.initialized = false;
-}
-
-// implementation of object inheritance
-Submap.prototype = Object.create(AbstractCustomMap.prototype);
-Submap.prototype.constructor = Submap;
-
-/**
- * This method initializes submap with gui component. Before this point submap
- * is created and contains data, but cannot be visualized in the browser.
- *
- * @param {HTMLElement} htmlTag
- *          html div tag where google map should be placed
- */
-Submap.prototype.open = function (htmlTag) {
-  var self = this;
-
-  if (!this.isInitialized()) {
-    self.setElement(htmlTag);
-
-    var contentDiv = document.createElement("div");
-    contentDiv.setAttribute("name", "submap-div-" + self.getId());
-    contentDiv.style.width = "100%";
-    contentDiv.style.height = "100%";
-    htmlTag.appendChild(contentDiv);
-
-    var mapDiv = document.createElement("div");
-    mapDiv.style.width = "100%";
-    mapDiv.style.height = "100%";
-    contentDiv.appendChild(mapDiv);
-
-    $(self.getElement()).dialog({
-      title: self.getModel().getName(),
-      width: Math.floor(window.innerWidth * 2 / 3),
-      height: Math.floor(window.innerHeight * 2 / 3),
-      position: {
-        my: "center",
-        at: "center",
-        of: $(self.getTopMap().getElement())
-      },
-      resize: function () {
-        self.getMapCanvas().triggerListeners('resize');
-      }
-    });
-
-    $(self.getElement()).dialog("open");
-
-    self.createMapCanvas(mapDiv);
-
-    self._createMapChangedCallbacks();
-
-    self.getMapCanvas().triggerListeners('resize');
-    self.getMapCanvas().setBackgroundId(self.getTopMap().getBackgroundDataOverlay().getId());
-
-    self.initialized = true;
-  } else {
-    $(self.getElement()).dialog("open");
-  }
-
-};
-
-/**
- *
- * @param {number} identifier
- */
-Submap.prototype.openDataOverlay = function (identifier) {
-  if (this.isInitialized()) {
-    this.getMapCanvas().setBackgroundId(identifier.toString());
-  }
-};
-
-/**
- *
- * @returns {CustomMap}
- */
-Submap.prototype.getTopMap = function () {
-  return this.getCustomMap();
-};
-
-/**
- *
- * @returns {CustomMap}
- */
-Submap.prototype.getCustomMap = function () {
-  return this._customMap;
-};
-
-/**
- *
- * @param {CustomMap} customMap
- */
-Submap.prototype.setCustomMap = function (customMap) {
-  this._customMap = customMap;
-};
-
-/**
- *
- * @returns {Project}
- */
-Submap.prototype.getProject = function () {
-  return this.getCustomMap().getProject();
-};
-
-Submap.prototype.destroy = function () {
-  var self = this;
-  AbstractCustomMap.prototype.destroy.call(self);
-  if (self.isInitialized()) {
-    $(self.getElement()).dialog("destroy");
-  }
-};
-
-module.exports = Submap;
+"use strict";
+
+/* exported logger */
+
+// noinspection JSUnusedLocalSymbols
+var logger = require('../logger');
+var AbstractCustomMap = require('./AbstractCustomMap');
+var CustomMapOptions = require('./CustomMapOptions');
+
+/**
+ * Constructor of a submap. Submaps are created on application start. But dialog
+ * (popup window) is initialized on demand using init function.
+ *
+ * @param {CustomMap} customMap
+ *          parent CustomMap
+ * @param {MapModel} model
+ *
+ * @constructor
+ * @extends AbstractCustomMap
+ */
+function Submap(customMap, model) {
+  this.setCustomMap(customMap);
+
+  AbstractCustomMap.call(this, model, new CustomMapOptions({
+    element: customMap.getElement(),
+    bigLogo: customMap.isBigLogo(),
+    project: customMap.getProject(),
+    configuration: customMap.getConfiguration(),
+    projectId: customMap.getProject().getProjectId(),
+    debug: customMap.isDebug(),
+    serverConnector: customMap.getServerConnector()
+  }));
+
+  this.initialized = false;
+}
+
+// implementation of object inheritance
+Submap.prototype = Object.create(AbstractCustomMap.prototype);
+Submap.prototype.constructor = Submap;
+
+/**
+ * This method initializes submap with gui component. Before this point submap
+ * is created and contains data, but cannot be visualized in the browser.
+ *
+ * @param {HTMLElement} htmlTag
+ *          html div tag where google map should be placed
+ */
+Submap.prototype.open = function (htmlTag) {
+  var self = this;
+
+  if (!this.isInitialized()) {
+    self.setElement(htmlTag);
+
+    var contentDiv = document.createElement("div");
+    contentDiv.setAttribute("name", "submap-div-" + self.getId());
+    contentDiv.style.width = "100%";
+    contentDiv.style.height = "100%";
+    htmlTag.appendChild(contentDiv);
+
+    var mapDiv = document.createElement("div");
+    mapDiv.style.width = "100%";
+    mapDiv.style.height = "100%";
+    contentDiv.appendChild(mapDiv);
+
+    $(self.getElement()).dialog({
+      title: self.getModel().getName(),
+      width: Math.floor(window.innerWidth * 2 / 3),
+      height: Math.floor(window.innerHeight * 2 / 3),
+      position: {
+        my: "center",
+        at: "center",
+        of: $(self.getTopMap().getElement())
+      },
+      resize: function () {
+        self.getMapCanvas().triggerListeners('resize');
+      }
+    });
+
+    $(self.getElement()).dialog("open");
+
+    self.createMapCanvas(mapDiv);
+
+    self._createMapChangedCallbacks();
+
+    self.getMapCanvas().triggerListeners('resize');
+    self.getMapCanvas().setBackgroundId(self.getTopMap().getBackgroundDataOverlay().getId());
+
+    self.initialized = true;
+  } else {
+    $(self.getElement()).dialog("open");
+  }
+
+};
+
+/**
+ *
+ * @param {number} identifier
+ */
+Submap.prototype.openDataOverlay = function (identifier) {
+  if (this.isInitialized()) {
+    this.getMapCanvas().setBackgroundId(identifier.toString());
+  }
+};
+
+/**
+ *
+ * @returns {CustomMap}
+ */
+Submap.prototype.getTopMap = function () {
+  return this.getCustomMap();
+};
+
+/**
+ *
+ * @returns {CustomMap}
+ */
+Submap.prototype.getCustomMap = function () {
+  return this._customMap;
+};
+
+/**
+ *
+ * @param {CustomMap} customMap
+ */
+Submap.prototype.setCustomMap = function (customMap) {
+  this._customMap = customMap;
+};
+
+/**
+ *
+ * @returns {Project}
+ */
+Submap.prototype.getProject = function () {
+  return this.getCustomMap().getProject();
+};
+
+Submap.prototype.destroy = function () {
+  var self = this;
+  AbstractCustomMap.prototype.destroy.call(self);
+  if (self.isInitialized()) {
+    $(self.getElement()).dialog("destroy");
+  }
+};
+
+module.exports = Submap;
diff --git a/frontend-js/src/main/js/map/data/Alias.js b/frontend-js/src/main/js/map/data/Alias.js
index 1bfd76989315b1d645d6a6438a4fad8556fbe213..2dbe094b08b8b8da240ce033edf43fe526a99a06 100644
--- a/frontend-js/src/main/js/map/data/Alias.js
+++ b/frontend-js/src/main/js/map/data/Alias.js
@@ -1,403 +1,403 @@
-"use strict";
-
-var BioEntity = require("./BioEntity");
-var Point = require("../canvas/Point");
-
-// noinspection JSUnusedLocalSymbols
-var logger = require('../../logger');
-
-/**
- * Class representing alias data.
- *
- * @param {Alias|Object} javaObject
- *          object de-serialized ajax query to the server side
- */
-function Alias(javaObject) {
-  BioEntity.call(this, javaObject);
-  if (javaObject.idObject !== undefined) {
-    this.setId(javaObject.idObject);
-  } else {
-    this.setId(javaObject.id);
-  }
-  this.setModelId(javaObject.modelId);
-  if (javaObject.bounds !== undefined) {
-    this.setX(javaObject.bounds.x);
-    this.setY(javaObject.bounds.y);
-    this.setWidth(javaObject.bounds.width);
-    this.setHeight(javaObject.bounds.height);
-  }
-  this.setLinkedSubmodelId(javaObject.linkedSubmodel);
-
-  if (this._modelId === undefined) {
-    throw new Error("ModelId is not defined for alias" + javaObject);
-  }
-
-  if (javaObject.name === undefined) {
-    this.setIsComplete(false);
-  } else {
-    this.update(javaObject);
-  }
-}
-
-Alias.prototype = Object.create(BioEntity.prototype);
-Alias.prototype.constructor = Alias;
-
-/**
- * Updates alias with full data information. This function should be called when
- * full information about alias is retrieved from server.
- *
- * @param {Alias|Object} javaObject
- *          object representing data from server side
- */
-Alias.prototype.update = function (javaObject) {
-  if (javaObject instanceof Alias) {
-    if (javaObject.getName() === undefined) {
-      return;
-    }
-    this.setDescription(javaObject.getDescription());
-    this.setElementId(javaObject.getElementId());
-    this.setType(javaObject.getType());
-    this.setCharge(javaObject.getCharge());
-    this.setSymbol(javaObject.getSymbol());
-    this.setFullName(javaObject.getFullName());
-    this.setAbbreviation(javaObject.getAbbreviation());
-    this.setFormula(javaObject.getFormula());
-    this.setName(javaObject.getName());
-    this.setSynonyms(javaObject.getSynonyms());
-    this.setFormerSymbols(javaObject.getFormerSymbols());
-    this.setReferences(javaObject.getReferences());
-    this.setOther(javaObject.getOther());
-    this.setHierarchyVisibilityLevel(javaObject.getHierarchyVisibilityLevel());
-    this.setComplexId(javaObject.getComplexId());
-    this.setTransparencyLevel(javaObject.getTransparencyLevel());
-    this.setLinkedSubmodelId(javaObject.getLinkedSubmodelId());
-    this.setCompartmentId(javaObject.getCompartmentId());
-    this.setDescription(javaObject.getDescription());
-
-    this.setConstant(javaObject.getConstant());
-    this.setBoundaryCondition(javaObject.getBoundaryCondition());
-    this.setInitialAmount(javaObject.getInitialAmount());
-    this.setInitialConcentration(javaObject.getInitialConcentration());
-
-    this.setX(javaObject.getX());
-    this.setY(javaObject.getY());
-    this.setWidth(javaObject.getWidth());
-    this.setHeight(javaObject.getHeight());
-
-    this.setIsComplete(true);
-  } else {
-    if (javaObject.name === undefined) {
-      return;
-    }
-    this.setDescription(javaObject.notes);
-    this.setElementId(javaObject.elementId);
-    this.setType(javaObject.type);
-    this.setCharge(javaObject.charge);
-    this.setSymbol(javaObject.symbol);
-    this.setFullName(javaObject.fullName);
-    this.setAbbreviation(javaObject.abbreviation);
-    this.setFormula(javaObject.formula);
-    this.setName(javaObject.name);
-    this.setSynonyms(javaObject.synonyms);
-    this.setFormerSymbols(javaObject.formerSymbols);
-    this.setReferences(javaObject.references);
-    this.setOther(javaObject.other);
-    this.setHierarchyVisibilityLevel(javaObject.hierarchyVisibilityLevel);
-    this.setComplexId(javaObject.complexId);
-    this.setTransparencyLevel(javaObject.transparencyLevel);
-    this.setLinkedSubmodelId(javaObject.linkedSubmodel);
-    this.setCompartmentId(javaObject.compartmentId);
-
-    this.setConstant(javaObject.constant);
-    this.setBoundaryCondition(javaObject.boundaryCondition);
-    this.setInitialAmount(javaObject.initialAmount);
-    this.setInitialConcentration(javaObject.initialConcentration);
-
-
-    if (javaObject.bounds !== undefined) {
-      this.setX(javaObject.bounds.x);
-      this.setY(javaObject.bounds.y);
-      this.setWidth(javaObject.bounds.width);
-      this.setHeight(javaObject.bounds.height);
-    }
-    this.setIsComplete(true);
-  }
-};
-
-/**
- *
- * @returns {number}
- */
-Alias.prototype.getCharge = function () {
-  return this.charge;
-};
-
-/**
- *
- * @param {number} charge
- */
-Alias.prototype.setCharge = function (charge) {
-  this.charge = charge;
-};
-
-/**
- *
- * @returns {boolean}
- */
-Alias.prototype.getConstant = function () {
-  return this._constant;
-};
-
-/**
- *
- * @param {boolean} constant
- */
-Alias.prototype.setConstant = function (constant) {
-  this._constant = constant;
-};
-
-/**
- *
- * @returns {boolean}
- */
-Alias.prototype.getBoundaryCondition = function () {
-  return this._boundaryCondition;
-};
-
-/**
- *
- * @param {boolean} boundaryCondition
- */
-Alias.prototype.setBoundaryCondition = function (boundaryCondition) {
-  this._boundaryCondition = boundaryCondition;
-};
-
-/**
- *
- * @returns {number}
- */
-Alias.prototype.getInitialAmount = function () {
-  return this._initialAmount;
-};
-
-/**
- *
- * @param {number} initialAmount
- */
-Alias.prototype.setInitialAmount = function (initialAmount) {
-  this._initialAmount = initialAmount;
-};
-
-/**
- *
- * @returns {number}
- */
-Alias.prototype.getInitialConcentration = function () {
-  return this._initialConcentration;
-};
-
-/**
- *
- * @param {number} initialConcentration
- */
-Alias.prototype.setInitialConcentration = function (initialConcentration) {
-  this._initialConcentration = initialConcentration;
-};
-
-/**
- *
- * @returns {string[]}
- */
-Alias.prototype.getFormerSymbols = function () {
-  return this.formerSymbols;
-};
-
-/**
- *
- * @param {string[]} formerSymbols
- */
-Alias.prototype.setFormerSymbols = function (formerSymbols) {
-  this.formerSymbols = formerSymbols;
-};
-
-/**
- *
- * @returns {number}
- */
-Alias.prototype.getX = function () {
-  return this.x;
-};
-
-/**
- *
- * @param {number} x
- */
-Alias.prototype.setX = function (x) {
-  if (x !== undefined) {
-    this.x = x;
-  }
-};
-
-/**
- *
- * @param {number}  y
- */
-Alias.prototype.setY = function (y) {
-  if (y !== undefined) {
-    this.y = y;
-  }
-};
-
-/**
- *
- * @returns {number}
- */
-Alias.prototype.getY = function () {
-  return this.y;
-};
-
-/**
- *
- * @param {number} elementId
- */
-Alias.prototype.setElementId = function (elementId) {
-  this._elementId = elementId;
-};
-
-/**
- *
- * @returns {number}
- */
-Alias.prototype.getElementId = function () {
-  return this._elementId;
-};
-
-/**
- *
- * @param {number} width
- */
-Alias.prototype.setWidth = function (width) {
-  if (width !== undefined) {
-    this.width = width;
-  }
-};
-
-/**
- *
- * @param {number} height
- */
-Alias.prototype.setHeight = function (height) {
-  if (height !== undefined) {
-    this.height = height;
-  }
-};
-
-/**
- *
- * @returns {number}
- */
-Alias.prototype.getWidth = function () {
-  return this.width;
-};
-
-/**
- *
- * @returns {number}
- */
-Alias.prototype.getHeight = function () {
-  return this.height;
-};
-
-/**
- *
- * @returns {string}
- */
-Alias.prototype.getName = function () {
-  return this.name;
-};
-
-/**
- *
- * @param {string} name
- */
-Alias.prototype.setName = function (name) {
-  this.name = name;
-};
-
-/**
- *
- * @returns {string}
- */
-Alias.prototype.getFullName = function () {
-  return this.fullName;
-};
-
-/**
- *
- * @param {string} fullName
- */
-Alias.prototype.setFullName = function (fullName) {
-  this.fullName = fullName;
-};
-
-/**
- *
- * @returns {number|undefined}
- */
-Alias.prototype.getCompartmentId = function () {
-  return this._compartmentId;
-};
-
-/**
- *
- * @param {number} compartmentId
- */
-Alias.prototype.setCompartmentId = function (compartmentId) {
-  if (compartmentId !== null) {
-    this._compartmentId = compartmentId;
-  }
-};
-
-/**
- *
- * @returns {number}
- */
-Alias.prototype.getComplexId = function () {
-  return this._complexId;
-};
-
-/**
- *
- * @param {number} complexId
- */
-Alias.prototype.setComplexId = function (complexId) {
-  if (complexId !== null) {
-    this._complexId = complexId;
-  }
-};
-
-/**
- *
- * @returns {number}
- */
-Alias.prototype.getTransparencyLevel = function () {
-  return this._transparencyLevel;
-};
-
-/**
- *
- * @param {number} transparencyLevel
- */
-Alias.prototype.setTransparencyLevel = function (transparencyLevel) {
-  this._transparencyLevel = transparencyLevel;
-};
-
-/**
- *
- * @returns {Point}
- */
-Alias.prototype.getCenter = function () {
-  return new Point(this.getX() + this.getWidth() / 2, this.getY() + this.getHeight() / 2);
-};
-
-module.exports = Alias;
+"use strict";
+
+var BioEntity = require("./BioEntity");
+var Point = require("../canvas/Point");
+
+// noinspection JSUnusedLocalSymbols
+var logger = require('../../logger');
+
+/**
+ * Class representing alias data.
+ *
+ * @param {Alias|Object} javaObject
+ *          object de-serialized ajax query to the server side
+ */
+function Alias(javaObject) {
+  BioEntity.call(this, javaObject);
+  if (javaObject.idObject !== undefined) {
+    this.setId(javaObject.idObject);
+  } else {
+    this.setId(javaObject.id);
+  }
+  this.setModelId(javaObject.modelId);
+  if (javaObject.bounds !== undefined) {
+    this.setX(javaObject.bounds.x);
+    this.setY(javaObject.bounds.y);
+    this.setWidth(javaObject.bounds.width);
+    this.setHeight(javaObject.bounds.height);
+  }
+  this.setLinkedSubmodelId(javaObject.linkedSubmodel);
+
+  if (this._modelId === undefined) {
+    throw new Error("ModelId is not defined for alias" + javaObject);
+  }
+
+  if (javaObject.name === undefined) {
+    this.setIsComplete(false);
+  } else {
+    this.update(javaObject);
+  }
+}
+
+Alias.prototype = Object.create(BioEntity.prototype);
+Alias.prototype.constructor = Alias;
+
+/**
+ * Updates alias with full data information. This function should be called when
+ * full information about alias is retrieved from server.
+ *
+ * @param {Alias|Object} javaObject
+ *          object representing data from server side
+ */
+Alias.prototype.update = function (javaObject) {
+  if (javaObject instanceof Alias) {
+    if (javaObject.getName() === undefined) {
+      return;
+    }
+    this.setDescription(javaObject.getDescription());
+    this.setElementId(javaObject.getElementId());
+    this.setType(javaObject.getType());
+    this.setCharge(javaObject.getCharge());
+    this.setSymbol(javaObject.getSymbol());
+    this.setFullName(javaObject.getFullName());
+    this.setAbbreviation(javaObject.getAbbreviation());
+    this.setFormula(javaObject.getFormula());
+    this.setName(javaObject.getName());
+    this.setSynonyms(javaObject.getSynonyms());
+    this.setFormerSymbols(javaObject.getFormerSymbols());
+    this.setReferences(javaObject.getReferences());
+    this.setOther(javaObject.getOther());
+    this.setHierarchyVisibilityLevel(javaObject.getHierarchyVisibilityLevel());
+    this.setComplexId(javaObject.getComplexId());
+    this.setTransparencyLevel(javaObject.getTransparencyLevel());
+    this.setLinkedSubmodelId(javaObject.getLinkedSubmodelId());
+    this.setCompartmentId(javaObject.getCompartmentId());
+    this.setDescription(javaObject.getDescription());
+
+    this.setConstant(javaObject.getConstant());
+    this.setBoundaryCondition(javaObject.getBoundaryCondition());
+    this.setInitialAmount(javaObject.getInitialAmount());
+    this.setInitialConcentration(javaObject.getInitialConcentration());
+
+    this.setX(javaObject.getX());
+    this.setY(javaObject.getY());
+    this.setWidth(javaObject.getWidth());
+    this.setHeight(javaObject.getHeight());
+
+    this.setIsComplete(true);
+  } else {
+    if (javaObject.name === undefined) {
+      return;
+    }
+    this.setDescription(javaObject.notes);
+    this.setElementId(javaObject.elementId);
+    this.setType(javaObject.type);
+    this.setCharge(javaObject.charge);
+    this.setSymbol(javaObject.symbol);
+    this.setFullName(javaObject.fullName);
+    this.setAbbreviation(javaObject.abbreviation);
+    this.setFormula(javaObject.formula);
+    this.setName(javaObject.name);
+    this.setSynonyms(javaObject.synonyms);
+    this.setFormerSymbols(javaObject.formerSymbols);
+    this.setReferences(javaObject.references);
+    this.setOther(javaObject.other);
+    this.setHierarchyVisibilityLevel(javaObject.hierarchyVisibilityLevel);
+    this.setComplexId(javaObject.complexId);
+    this.setTransparencyLevel(javaObject.transparencyLevel);
+    this.setLinkedSubmodelId(javaObject.linkedSubmodel);
+    this.setCompartmentId(javaObject.compartmentId);
+
+    this.setConstant(javaObject.constant);
+    this.setBoundaryCondition(javaObject.boundaryCondition);
+    this.setInitialAmount(javaObject.initialAmount);
+    this.setInitialConcentration(javaObject.initialConcentration);
+
+
+    if (javaObject.bounds !== undefined) {
+      this.setX(javaObject.bounds.x);
+      this.setY(javaObject.bounds.y);
+      this.setWidth(javaObject.bounds.width);
+      this.setHeight(javaObject.bounds.height);
+    }
+    this.setIsComplete(true);
+  }
+};
+
+/**
+ *
+ * @returns {number}
+ */
+Alias.prototype.getCharge = function () {
+  return this.charge;
+};
+
+/**
+ *
+ * @param {number} charge
+ */
+Alias.prototype.setCharge = function (charge) {
+  this.charge = charge;
+};
+
+/**
+ *
+ * @returns {boolean}
+ */
+Alias.prototype.getConstant = function () {
+  return this._constant;
+};
+
+/**
+ *
+ * @param {boolean} constant
+ */
+Alias.prototype.setConstant = function (constant) {
+  this._constant = constant;
+};
+
+/**
+ *
+ * @returns {boolean}
+ */
+Alias.prototype.getBoundaryCondition = function () {
+  return this._boundaryCondition;
+};
+
+/**
+ *
+ * @param {boolean} boundaryCondition
+ */
+Alias.prototype.setBoundaryCondition = function (boundaryCondition) {
+  this._boundaryCondition = boundaryCondition;
+};
+
+/**
+ *
+ * @returns {number}
+ */
+Alias.prototype.getInitialAmount = function () {
+  return this._initialAmount;
+};
+
+/**
+ *
+ * @param {number} initialAmount
+ */
+Alias.prototype.setInitialAmount = function (initialAmount) {
+  this._initialAmount = initialAmount;
+};
+
+/**
+ *
+ * @returns {number}
+ */
+Alias.prototype.getInitialConcentration = function () {
+  return this._initialConcentration;
+};
+
+/**
+ *
+ * @param {number} initialConcentration
+ */
+Alias.prototype.setInitialConcentration = function (initialConcentration) {
+  this._initialConcentration = initialConcentration;
+};
+
+/**
+ *
+ * @returns {string[]}
+ */
+Alias.prototype.getFormerSymbols = function () {
+  return this.formerSymbols;
+};
+
+/**
+ *
+ * @param {string[]} formerSymbols
+ */
+Alias.prototype.setFormerSymbols = function (formerSymbols) {
+  this.formerSymbols = formerSymbols;
+};
+
+/**
+ *
+ * @returns {number}
+ */
+Alias.prototype.getX = function () {
+  return this.x;
+};
+
+/**
+ *
+ * @param {number} x
+ */
+Alias.prototype.setX = function (x) {
+  if (x !== undefined) {
+    this.x = x;
+  }
+};
+
+/**
+ *
+ * @param {number}  y
+ */
+Alias.prototype.setY = function (y) {
+  if (y !== undefined) {
+    this.y = y;
+  }
+};
+
+/**
+ *
+ * @returns {number}
+ */
+Alias.prototype.getY = function () {
+  return this.y;
+};
+
+/**
+ *
+ * @param {number} elementId
+ */
+Alias.prototype.setElementId = function (elementId) {
+  this._elementId = elementId;
+};
+
+/**
+ *
+ * @returns {number}
+ */
+Alias.prototype.getElementId = function () {
+  return this._elementId;
+};
+
+/**
+ *
+ * @param {number} width
+ */
+Alias.prototype.setWidth = function (width) {
+  if (width !== undefined) {
+    this.width = width;
+  }
+};
+
+/**
+ *
+ * @param {number} height
+ */
+Alias.prototype.setHeight = function (height) {
+  if (height !== undefined) {
+    this.height = height;
+  }
+};
+
+/**
+ *
+ * @returns {number}
+ */
+Alias.prototype.getWidth = function () {
+  return this.width;
+};
+
+/**
+ *
+ * @returns {number}
+ */
+Alias.prototype.getHeight = function () {
+  return this.height;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+Alias.prototype.getName = function () {
+  return this.name;
+};
+
+/**
+ *
+ * @param {string} name
+ */
+Alias.prototype.setName = function (name) {
+  this.name = name;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+Alias.prototype.getFullName = function () {
+  return this.fullName;
+};
+
+/**
+ *
+ * @param {string} fullName
+ */
+Alias.prototype.setFullName = function (fullName) {
+  this.fullName = fullName;
+};
+
+/**
+ *
+ * @returns {number|undefined}
+ */
+Alias.prototype.getCompartmentId = function () {
+  return this._compartmentId;
+};
+
+/**
+ *
+ * @param {number} compartmentId
+ */
+Alias.prototype.setCompartmentId = function (compartmentId) {
+  if (compartmentId !== null) {
+    this._compartmentId = compartmentId;
+  }
+};
+
+/**
+ *
+ * @returns {number}
+ */
+Alias.prototype.getComplexId = function () {
+  return this._complexId;
+};
+
+/**
+ *
+ * @param {number} complexId
+ */
+Alias.prototype.setComplexId = function (complexId) {
+  if (complexId !== null) {
+    this._complexId = complexId;
+  }
+};
+
+/**
+ *
+ * @returns {number}
+ */
+Alias.prototype.getTransparencyLevel = function () {
+  return this._transparencyLevel;
+};
+
+/**
+ *
+ * @param {number} transparencyLevel
+ */
+Alias.prototype.setTransparencyLevel = function (transparencyLevel) {
+  this._transparencyLevel = transparencyLevel;
+};
+
+/**
+ *
+ * @returns {Point}
+ */
+Alias.prototype.getCenter = function () {
+  return new Point(this.getX() + this.getWidth() / 2, this.getY() + this.getHeight() / 2);
+};
+
+module.exports = Alias;
diff --git a/frontend-js/src/main/js/map/data/Annotation.js b/frontend-js/src/main/js/map/data/Annotation.js
index 7b6f82bef9bf4a6518da736cb18df40c06c23303..ea2c3d71f43e792a40ea8f7dc63a58a8e080d17b 100644
--- a/frontend-js/src/main/js/map/data/Annotation.js
+++ b/frontend-js/src/main/js/map/data/Annotation.js
@@ -1,149 +1,149 @@
-"use strict";
-
-/* exported logger */
-
-var Article = require("./Article");
-
-// noinspection JSUnusedLocalSymbols
-var logger = require('../../logger');
-
-/**
- * @typedef {Object} AnnotationOptions
- * @property {string} link
- * @property {number} id
- * @property {Article|ArticleOptions} [article]
- * @property {string} type
- * @property {string} resource
- * @property {string} [annotatorClassName]
- */
-
-/**
- *
- * @param {AnnotationOptions|Annotation} javaObject
- * @constructor
- */
-function Annotation(javaObject) {
-  if (javaObject instanceof Annotation) {
-    this.setLink(javaObject.getLink());
-    this.setId(javaObject.getId());
-    if (javaObject.getArticle() !== undefined) {
-      this.setArticle(new Article(javaObject.getArticle()));
-    }
-    this.setType(javaObject.getType());
-    this.setResource(javaObject.getResource());
-    this.setAnnotatorClassName(javaObject.getAnnotatorClassName());
-  } else {
-    this.setLink(javaObject.link);
-    this.setId(javaObject.id);
-    if (javaObject.article !== undefined && javaObject.article !== null) {
-      this.setArticle(new Article(javaObject.article));
-    }
-    this.setType(javaObject.type);
-    this.setResource(javaObject.resource);
-    this.setAnnotatorClassName(javaObject.annotatorClassName);
-  }
-}
-
-/**
- *
- * @param {string} link
- */
-Annotation.prototype.setLink = function (link) {
-  this._link = link;
-};
-
-/**
- *
- * @returns {string}
- */
-Annotation.prototype.getLink = function () {
-  return this._link;
-};
-
-/**
- *
- * @param {number} id
- */
-Annotation.prototype.setId = function (id) {
-  this._id = id;
-};
-
-/**
- *
- * @returns {number}
- */
-Annotation.prototype.getId = function () {
-  return this._id;
-};
-
-/**
- *
- * @param {string} resource
- */
-Annotation.prototype.setResource = function (resource) {
-  if (resource === undefined) {
-    throw new Error("resource cannot be undefined");
-  }
-  this._resource = resource;
-};
-
-/**
- *
- * @returns {string}
- */
-Annotation.prototype.getResource = function () {
-  return this._resource;
-};
-
-/**
- *
- * @param {string} type
- */
-Annotation.prototype.setType = function (type) {
-  if (type === undefined) {
-    throw new Error("type cannot be undefined");
-  }
-  this._type = type;
-};
-
-/**
- *
- * @returns {string}
- */
-Annotation.prototype.getType = function () {
-  return this._type;
-};
-
-/**
- *
- * @param {Article} article
- */
-Annotation.prototype.setArticle = function (article) {
-  this._article = article;
-};
-
-/**
- *
- * @returns {Article}
- */
-Annotation.prototype.getArticle = function () {
-  return this._article;
-};
-
-/**
- *
- * @param {string} annotatorClassName
- */
-Annotation.prototype.setAnnotatorClassName = function (annotatorClassName) {
-  this._annotatorClassName = annotatorClassName;
-};
-
-/**
- *
- * @returns {string|undefined}
- */
-Annotation.prototype.getAnnotatorClassName = function () {
-  return this._annotatorClassName;
-};
-
-module.exports = Annotation;
+"use strict";
+
+/* exported logger */
+
+var Article = require("./Article");
+
+// noinspection JSUnusedLocalSymbols
+var logger = require('../../logger');
+
+/**
+ * @typedef {Object} AnnotationOptions
+ * @property {string} link
+ * @property {number} id
+ * @property {Article|ArticleOptions} [article]
+ * @property {string} type
+ * @property {string} resource
+ * @property {string} [annotatorClassName]
+ */
+
+/**
+ *
+ * @param {AnnotationOptions|Annotation} javaObject
+ * @constructor
+ */
+function Annotation(javaObject) {
+  if (javaObject instanceof Annotation) {
+    this.setLink(javaObject.getLink());
+    this.setId(javaObject.getId());
+    if (javaObject.getArticle() !== undefined) {
+      this.setArticle(new Article(javaObject.getArticle()));
+    }
+    this.setType(javaObject.getType());
+    this.setResource(javaObject.getResource());
+    this.setAnnotatorClassName(javaObject.getAnnotatorClassName());
+  } else {
+    this.setLink(javaObject.link);
+    this.setId(javaObject.id);
+    if (javaObject.article !== undefined && javaObject.article !== null) {
+      this.setArticle(new Article(javaObject.article));
+    }
+    this.setType(javaObject.type);
+    this.setResource(javaObject.resource);
+    this.setAnnotatorClassName(javaObject.annotatorClassName);
+  }
+}
+
+/**
+ *
+ * @param {string} link
+ */
+Annotation.prototype.setLink = function (link) {
+  this._link = link;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+Annotation.prototype.getLink = function () {
+  return this._link;
+};
+
+/**
+ *
+ * @param {number} id
+ */
+Annotation.prototype.setId = function (id) {
+  this._id = id;
+};
+
+/**
+ *
+ * @returns {number}
+ */
+Annotation.prototype.getId = function () {
+  return this._id;
+};
+
+/**
+ *
+ * @param {string} resource
+ */
+Annotation.prototype.setResource = function (resource) {
+  if (resource === undefined) {
+    throw new Error("resource cannot be undefined");
+  }
+  this._resource = resource;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+Annotation.prototype.getResource = function () {
+  return this._resource;
+};
+
+/**
+ *
+ * @param {string} type
+ */
+Annotation.prototype.setType = function (type) {
+  if (type === undefined) {
+    throw new Error("type cannot be undefined");
+  }
+  this._type = type;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+Annotation.prototype.getType = function () {
+  return this._type;
+};
+
+/**
+ *
+ * @param {Article} article
+ */
+Annotation.prototype.setArticle = function (article) {
+  this._article = article;
+};
+
+/**
+ *
+ * @returns {Article}
+ */
+Annotation.prototype.getArticle = function () {
+  return this._article;
+};
+
+/**
+ *
+ * @param {string} annotatorClassName
+ */
+Annotation.prototype.setAnnotatorClassName = function (annotatorClassName) {
+  this._annotatorClassName = annotatorClassName;
+};
+
+/**
+ *
+ * @returns {string|undefined}
+ */
+Annotation.prototype.getAnnotatorClassName = function () {
+  return this._annotatorClassName;
+};
+
+module.exports = Annotation;
diff --git a/frontend-js/src/main/js/map/data/Annotator.js b/frontend-js/src/main/js/map/data/Annotator.js
index 0905f0f7b4e5960b348a2496080dcb03ab732994..e5653d2b4105f70e9eed69f4803ac17a4e056576 100644
--- a/frontend-js/src/main/js/map/data/Annotator.js
+++ b/frontend-js/src/main/js/map/data/Annotator.js
@@ -1,98 +1,98 @@
-"use strict";
-
-/* exported logger */
-
-var Article = require("./Article");
-
-var logger = require('../../logger');
-
-function Annotator(javaObject, configuration) {
-  var self = this;
-  if (javaObject instanceof Annotator) {
-    self.setClassName(javaObject.getClassName());
-    this._elementTypes = javaObject.getElementTypes();
-    self.setName(javaObject.getName());
-    self.setDescription(javaObject.getDescription());
-    self.setParametersDefinitions(javaObject.getParametersDefinitions());
-    self.setUrl(javaObject.getUrl());
-  } else {
-    self.setClassName(javaObject.className);
-    self.setElementTypes(javaObject.elementClassNames, configuration);
-    self.setName(javaObject.name);
-    self.setDescription(javaObject.description);
-    self.setParametersDefinitions(javaObject.parametersDefinitions);
-    self.setUrl(javaObject.url);
-  }
-}
-
-Annotator.prototype.setClassName = function (className) {
-  this._className = className;
-};
-
-Annotator.prototype.getClassName = function () {
-  return this._className;
-};
-
-Annotator.prototype.setName = function (name) {
-  this._name = name;
-};
-
-Annotator.prototype.getName = function () {
-  return this._name;
-};
-
-Annotator.prototype.setDescription = function (description) {
-  this._description = description;
-};
-
-Annotator.prototype.getDescription = function () {
-  return this._description;
-};
-
-Annotator.prototype.setUrl = function (url) {
-  this._url = url;
-};
-
-Annotator.prototype.getUrl = function () {
-  return this._url;
-};
-
-Annotator.prototype.getParametersDefinitions = function () {
-  return this._parametersDefinitions;
-};
-
-Annotator.prototype.setParametersDefinitions = function (parametersDefinitions) {
-  this._parametersDefinitions = parametersDefinitions;
-};
-
-Annotator.prototype.setElementTypes = function (elementTypesClassNames, configuration) {
-  this._elementTypes = [];
-  var typeByClassName = {};
-  var types = configuration.getElementTypes();
-  var i, type;
-  for (i = 0; i < types.length; i++) {
-    type = types[i];
-    typeByClassName[type.className] = type;
-  }
-  types = configuration.getReactionTypes();
-  for (i = 0; i < types.length; i++) {
-    type = types[i];
-    typeByClassName[type.className] = type;
-  }
-
-  for (i = 0; i < elementTypesClassNames.length; i++) {
-    type = typeByClassName[elementTypesClassNames[i]];
-    if (type !== undefined) {
-      this._elementTypes.push(type)
-    } else {
-      throw new Error("Unknown elementType: " + elementTypesClassNames[i]);
-    }
-  }
-};
-
-Annotator.prototype.getElementTypes = function () {
-  return this._elementTypes;
-};
-
-
-module.exports = Annotator;
+"use strict";
+
+/* exported logger */
+
+var Article = require("./Article");
+
+var logger = require('../../logger');
+
+function Annotator(javaObject, configuration) {
+  var self = this;
+  if (javaObject instanceof Annotator) {
+    self.setClassName(javaObject.getClassName());
+    this._elementTypes = javaObject.getElementTypes();
+    self.setName(javaObject.getName());
+    self.setDescription(javaObject.getDescription());
+    self.setParametersDefinitions(javaObject.getParametersDefinitions());
+    self.setUrl(javaObject.getUrl());
+  } else {
+    self.setClassName(javaObject.className);
+    self.setElementTypes(javaObject.elementClassNames, configuration);
+    self.setName(javaObject.name);
+    self.setDescription(javaObject.description);
+    self.setParametersDefinitions(javaObject.parametersDefinitions);
+    self.setUrl(javaObject.url);
+  }
+}
+
+Annotator.prototype.setClassName = function (className) {
+  this._className = className;
+};
+
+Annotator.prototype.getClassName = function () {
+  return this._className;
+};
+
+Annotator.prototype.setName = function (name) {
+  this._name = name;
+};
+
+Annotator.prototype.getName = function () {
+  return this._name;
+};
+
+Annotator.prototype.setDescription = function (description) {
+  this._description = description;
+};
+
+Annotator.prototype.getDescription = function () {
+  return this._description;
+};
+
+Annotator.prototype.setUrl = function (url) {
+  this._url = url;
+};
+
+Annotator.prototype.getUrl = function () {
+  return this._url;
+};
+
+Annotator.prototype.getParametersDefinitions = function () {
+  return this._parametersDefinitions;
+};
+
+Annotator.prototype.setParametersDefinitions = function (parametersDefinitions) {
+  this._parametersDefinitions = parametersDefinitions;
+};
+
+Annotator.prototype.setElementTypes = function (elementTypesClassNames, configuration) {
+  this._elementTypes = [];
+  var typeByClassName = {};
+  var types = configuration.getElementTypes();
+  var i, type;
+  for (i = 0; i < types.length; i++) {
+    type = types[i];
+    typeByClassName[type.className] = type;
+  }
+  types = configuration.getReactionTypes();
+  for (i = 0; i < types.length; i++) {
+    type = types[i];
+    typeByClassName[type.className] = type;
+  }
+
+  for (i = 0; i < elementTypesClassNames.length; i++) {
+    type = typeByClassName[elementTypesClassNames[i]];
+    if (type !== undefined) {
+      this._elementTypes.push(type)
+    } else {
+      throw new Error("Unknown elementType: " + elementTypesClassNames[i]);
+    }
+  }
+};
+
+Annotator.prototype.getElementTypes = function () {
+  return this._elementTypes;
+};
+
+
+module.exports = Annotator;
diff --git a/frontend-js/src/main/js/map/data/Article.js b/frontend-js/src/main/js/map/data/Article.js
index 584cd35a1eff35bd56791234b8cb3decd78c4336..92f4beb6b50fea6a2f671358dcfee3cc5e68447b 100644
--- a/frontend-js/src/main/js/map/data/Article.js
+++ b/frontend-js/src/main/js/map/data/Article.js
@@ -1,159 +1,159 @@
-"use strict";
-
-/**
- * @typedef {Object} ArticleOptions
- * @property {string} title
- * @property {string[]} authors
- * @property {string} journal
- * @property {number} year
- * @property {string} link
- * @property {number} citationCount
- * @property {string} id
- */
-
-/**
- *
- * @param {Article|ArticleOptions} javaObject
- * @constructor
- */
-function Article(javaObject) {
-  if (javaObject instanceof Article) {
-    this.setTitle(javaObject.getTitle());
-    this.setAuthors(javaObject.getAuthors());
-    this.setJournal(javaObject.getJournal());
-    this.setYear(javaObject.getYear());
-    this.setLink(javaObject.getLink());
-    this.setCitationCount(javaObject.getCitationCount());
-    this.setId(javaObject.getId());
-  } else {
-    this.setTitle(javaObject.title);
-    this.setAuthors(javaObject.authors);
-    this.setJournal(javaObject.journal);
-    this.setYear(javaObject.year);
-    this.setLink(javaObject.link);
-    this.setCitationCount(javaObject.citationCount);
-    this.setId(javaObject.id);
-  }
-}
-
-/**
- *
- * @param {string} title
- */
-Article.prototype.setTitle = function (title) {
-  this._title = title;
-};
-
-/**
- *
- * @returns {string}
- */
-Article.prototype.getTitle = function () {
-  return this._title;
-};
-
-/**
- *
- * @param {string} id
- */
-Article.prototype.setId = function (id) {
-  this._id = id;
-};
-
-/**
- *
- * @returns {string[]}
- */
-Article.prototype.getAuthors = function () {
-  return this._authors;
-};
-
-/**
- *
- * @param {string[]} authors
- */
-Article.prototype.setAuthors = function (authors) {
-  this._authors = authors;
-};
-
-/**
- *
- * @param {string} id
- */
-Article.prototype.setId = function (id) {
-  this._id = id;
-};
-
-/**
- *
- * @returns {string}
- */
-Article.prototype.getId = function () {
-  return this._id;
-};
-
-/**
- *
- * @param {string} journal
- */
-Article.prototype.setJournal = function (journal) {
-  this._journal = journal;
-};
-
-/**
- *
- * @returns {string}
- */
-Article.prototype.getJournal = function () {
-  return this._journal;
-};
-
-/**
- *
- * @param {number} year
- */
-Article.prototype.setYear = function (year) {
-  this._year = year;
-};
-
-/**
- *
- * @returns {number}
- */
-Article.prototype.getYear = function () {
-  return this._year;
-};
-
-/**
- *
- * @param {string} link
- */
-Article.prototype.setLink = function (link) {
-  this._link = link;
-};
-
-/**
- *
- * @returns {string}
- */
-Article.prototype.getLink = function () {
-  return this._link;
-};
-
-/**
- *
- * @param {number} citationCount
- */
-Article.prototype.setCitationCount = function (citationCount) {
-  this._citationCount = citationCount;
-};
-
-/**
- *
- * @returns {number}
- */
-Article.prototype.getCitationCount = function () {
-  return this._citationCount;
-};
-
-module.exports = Article;
+"use strict";
+
+/**
+ * @typedef {Object} ArticleOptions
+ * @property {string} title
+ * @property {string[]} authors
+ * @property {string} journal
+ * @property {number} year
+ * @property {string} link
+ * @property {number} citationCount
+ * @property {string} id
+ */
+
+/**
+ *
+ * @param {Article|ArticleOptions} javaObject
+ * @constructor
+ */
+function Article(javaObject) {
+  if (javaObject instanceof Article) {
+    this.setTitle(javaObject.getTitle());
+    this.setAuthors(javaObject.getAuthors());
+    this.setJournal(javaObject.getJournal());
+    this.setYear(javaObject.getYear());
+    this.setLink(javaObject.getLink());
+    this.setCitationCount(javaObject.getCitationCount());
+    this.setId(javaObject.getId());
+  } else {
+    this.setTitle(javaObject.title);
+    this.setAuthors(javaObject.authors);
+    this.setJournal(javaObject.journal);
+    this.setYear(javaObject.year);
+    this.setLink(javaObject.link);
+    this.setCitationCount(javaObject.citationCount);
+    this.setId(javaObject.id);
+  }
+}
+
+/**
+ *
+ * @param {string} title
+ */
+Article.prototype.setTitle = function (title) {
+  this._title = title;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+Article.prototype.getTitle = function () {
+  return this._title;
+};
+
+/**
+ *
+ * @param {string} id
+ */
+Article.prototype.setId = function (id) {
+  this._id = id;
+};
+
+/**
+ *
+ * @returns {string[]}
+ */
+Article.prototype.getAuthors = function () {
+  return this._authors;
+};
+
+/**
+ *
+ * @param {string[]} authors
+ */
+Article.prototype.setAuthors = function (authors) {
+  this._authors = authors;
+};
+
+/**
+ *
+ * @param {string} id
+ */
+Article.prototype.setId = function (id) {
+  this._id = id;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+Article.prototype.getId = function () {
+  return this._id;
+};
+
+/**
+ *
+ * @param {string} journal
+ */
+Article.prototype.setJournal = function (journal) {
+  this._journal = journal;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+Article.prototype.getJournal = function () {
+  return this._journal;
+};
+
+/**
+ *
+ * @param {number} year
+ */
+Article.prototype.setYear = function (year) {
+  this._year = year;
+};
+
+/**
+ *
+ * @returns {number}
+ */
+Article.prototype.getYear = function () {
+  return this._year;
+};
+
+/**
+ *
+ * @param {string} link
+ */
+Article.prototype.setLink = function (link) {
+  this._link = link;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+Article.prototype.getLink = function () {
+  return this._link;
+};
+
+/**
+ *
+ * @param {number} citationCount
+ */
+Article.prototype.setCitationCount = function (citationCount) {
+  this._citationCount = citationCount;
+};
+
+/**
+ *
+ * @returns {number}
+ */
+Article.prototype.getCitationCount = function () {
+  return this._citationCount;
+};
+
+module.exports = Article;
diff --git a/frontend-js/src/main/js/map/data/BioEntity.js b/frontend-js/src/main/js/map/data/BioEntity.js
index f2deb9b7686a2f9fc60e57f141c172d0b665ebba..bacd7e36e82ca036f8bdf9da282890b45f9bf77f 100644
--- a/frontend-js/src/main/js/map/data/BioEntity.js
+++ b/frontend-js/src/main/js/map/data/BioEntity.js
@@ -1,243 +1,243 @@
-"use strict";
-
-var Annotation = require("./Annotation");
-var Functions = require("../../Functions");
-
-/**
- * Class representing BioEntity.
- *
- * @constructor
- */
-function BioEntity() {
-}
-
-/**
- *
- * @returns {number|undefined}
- */
-BioEntity.prototype.getLinkedSubmodelId = function () {
-  return this._linkedSubmodelId;
-};
-
-/**
- *
- * @param {number} linkedSubmodelId
- */
-BioEntity.prototype.setLinkedSubmodelId = function (linkedSubmodelId) {
-  this._linkedSubmodelId = Functions.getIntOrUndefined(linkedSubmodelId);
-};
-
-/**
- * Returns identifier of the BioEntity.
- *
- * @returns {number} identifier of the BioEntity
- */
-BioEntity.prototype.getId = function () {
-  return this.id;
-};
-
-/**
- *
- * @param {number} id
- */
-BioEntity.prototype.setId = function (id) {
-  this.id = id;
-};
-
-/**
- * Returns model identifier where {@link BioEntity} is located.
- *
- * @returns {number} model identifier where {@link BioEntity} is located
- */
-BioEntity.prototype.getModelId = function () {
-  return this._modelId;
-};
-
-/**
- *
- * @param {number} modelId
- */
-BioEntity.prototype.setModelId = function (modelId) {
-  this._modelId = modelId;
-};
-
-/**
- *
- * @returns {boolean}
- */
-BioEntity.prototype.isComplete = function () {
-  return this._complete;
-};
-
-/**
- *
- * @param {boolean} complete
- */
-BioEntity.prototype.setIsComplete = function (complete) {
-  this._complete = complete;
-};
-
-/**
- *
- * @returns {string}
- */
-BioEntity.prototype.getSymbol = function () {
-  return this.symbol;
-};
-
-/**
- *
- * @param {string} symbol
- */
-BioEntity.prototype.setSymbol = function (symbol) {
-  this.symbol = symbol;
-};
-
-/**
- *
- * @returns {string}
- */
-BioEntity.prototype.getAbbreviation = function () {
-  return this._abbreviation;
-};
-
-/**
- *
- * @param {string} abbreviation
- */
-BioEntity.prototype.setAbbreviation = function (abbreviation) {
-  this._abbreviation = abbreviation;
-};
-
-/**
- *
- * @returns {string}
- */
-BioEntity.prototype.getFormula = function () {
-  return this._formula;
-};
-
-/**
- *
- * @param {string} formula
- */
-BioEntity.prototype.setFormula = function (formula) {
-  this._formula = formula;
-};
-
-/**
- *
- * @param {string[]} synonyms
- */
-BioEntity.prototype.setSynonyms = function (synonyms) {
-  this._synonyms = synonyms;
-};
-
-/**
- *
- * @returns {string[]}
- */
-BioEntity.prototype.getSynonyms = function () {
-  return this._synonyms;
-};
-
-/**
- *
- * @param {string} description
- */
-BioEntity.prototype.setDescription = function (description) {
-  this._description = description;
-};
-
-/**
- *
- * @returns {string}
- */
-BioEntity.prototype.getDescription = function () {
-  return this._description;
-};
-
-/**
- *
- * @param {string} type
- */
-BioEntity.prototype.setType = function (type) {
-  if (type === undefined) {
-    throw new Error("type cannot be undefined");
-  }
-  this._type = type;
-};
-
-/**
- *
- * @returns {string}
- */
-BioEntity.prototype.getType = function () {
-  return this._type;
-};
-
-/**
- *
- * @param {string} type
- * @returns {Object}
- */
-BioEntity.prototype.getOther = function (type) {
-  if (this._other !== undefined) {
-    return (type === undefined) ? this._other : this._other[type];
-  }
-};
-
-/**
- *
- * @param {Object} other
- */
-BioEntity.prototype.setOther = function (other) {
-  this._other = other;
-};
-
-/**
- *
- * @returns {number}
- */
-BioEntity.prototype.getHierarchyVisibilityLevel = function () {
-  return this._hierarchyVisibilityLevel;
-};
-
-/**
- *
- * @param {number} hierarchyVisibilityLevel
- */
-BioEntity.prototype.setHierarchyVisibilityLevel = function (hierarchyVisibilityLevel) {
-  this._hierarchyVisibilityLevel = hierarchyVisibilityLevel;
-};
-
-/**
- *
- * @returns {Annotation[]}
- */
-BioEntity.prototype.getReferences = function () {
-  return this.references;
-};
-
-/**
- *
- * @param {Annotation[]} references
- */
-BioEntity.prototype.setReferences = function (references) {
-  if (references === undefined) {
-    throw new Error("references must be defined");
-  }
-  this.references = [];
-  for (var i = 0; i < references.length; i++) {
-    this.references.push(new Annotation(references[i]));
-  }
-};
-
-/**
- * @returns {Point}
- */
-BioEntity.prototype.getCenter = function () {
-  throw new Error("Not implemented");
-};
-
-module.exports = BioEntity;
+"use strict";
+
+var Annotation = require("./Annotation");
+var Functions = require("../../Functions");
+
+/**
+ * Class representing BioEntity.
+ *
+ * @constructor
+ */
+function BioEntity() {
+}
+
+/**
+ *
+ * @returns {number|undefined}
+ */
+BioEntity.prototype.getLinkedSubmodelId = function () {
+  return this._linkedSubmodelId;
+};
+
+/**
+ *
+ * @param {number} linkedSubmodelId
+ */
+BioEntity.prototype.setLinkedSubmodelId = function (linkedSubmodelId) {
+  this._linkedSubmodelId = Functions.getIntOrUndefined(linkedSubmodelId);
+};
+
+/**
+ * Returns identifier of the BioEntity.
+ *
+ * @returns {number} identifier of the BioEntity
+ */
+BioEntity.prototype.getId = function () {
+  return this.id;
+};
+
+/**
+ *
+ * @param {number} id
+ */
+BioEntity.prototype.setId = function (id) {
+  this.id = id;
+};
+
+/**
+ * Returns model identifier where {@link BioEntity} is located.
+ *
+ * @returns {number} model identifier where {@link BioEntity} is located
+ */
+BioEntity.prototype.getModelId = function () {
+  return this._modelId;
+};
+
+/**
+ *
+ * @param {number} modelId
+ */
+BioEntity.prototype.setModelId = function (modelId) {
+  this._modelId = modelId;
+};
+
+/**
+ *
+ * @returns {boolean}
+ */
+BioEntity.prototype.isComplete = function () {
+  return this._complete;
+};
+
+/**
+ *
+ * @param {boolean} complete
+ */
+BioEntity.prototype.setIsComplete = function (complete) {
+  this._complete = complete;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+BioEntity.prototype.getSymbol = function () {
+  return this.symbol;
+};
+
+/**
+ *
+ * @param {string} symbol
+ */
+BioEntity.prototype.setSymbol = function (symbol) {
+  this.symbol = symbol;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+BioEntity.prototype.getAbbreviation = function () {
+  return this._abbreviation;
+};
+
+/**
+ *
+ * @param {string} abbreviation
+ */
+BioEntity.prototype.setAbbreviation = function (abbreviation) {
+  this._abbreviation = abbreviation;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+BioEntity.prototype.getFormula = function () {
+  return this._formula;
+};
+
+/**
+ *
+ * @param {string} formula
+ */
+BioEntity.prototype.setFormula = function (formula) {
+  this._formula = formula;
+};
+
+/**
+ *
+ * @param {string[]} synonyms
+ */
+BioEntity.prototype.setSynonyms = function (synonyms) {
+  this._synonyms = synonyms;
+};
+
+/**
+ *
+ * @returns {string[]}
+ */
+BioEntity.prototype.getSynonyms = function () {
+  return this._synonyms;
+};
+
+/**
+ *
+ * @param {string} description
+ */
+BioEntity.prototype.setDescription = function (description) {
+  this._description = description;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+BioEntity.prototype.getDescription = function () {
+  return this._description;
+};
+
+/**
+ *
+ * @param {string} type
+ */
+BioEntity.prototype.setType = function (type) {
+  if (type === undefined) {
+    throw new Error("type cannot be undefined");
+  }
+  this._type = type;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+BioEntity.prototype.getType = function () {
+  return this._type;
+};
+
+/**
+ *
+ * @param {string} type
+ * @returns {Object}
+ */
+BioEntity.prototype.getOther = function (type) {
+  if (this._other !== undefined) {
+    return (type === undefined) ? this._other : this._other[type];
+  }
+};
+
+/**
+ *
+ * @param {Object} other
+ */
+BioEntity.prototype.setOther = function (other) {
+  this._other = other;
+};
+
+/**
+ *
+ * @returns {number}
+ */
+BioEntity.prototype.getHierarchyVisibilityLevel = function () {
+  return this._hierarchyVisibilityLevel;
+};
+
+/**
+ *
+ * @param {number} hierarchyVisibilityLevel
+ */
+BioEntity.prototype.setHierarchyVisibilityLevel = function (hierarchyVisibilityLevel) {
+  this._hierarchyVisibilityLevel = hierarchyVisibilityLevel;
+};
+
+/**
+ *
+ * @returns {Annotation[]}
+ */
+BioEntity.prototype.getReferences = function () {
+  return this.references;
+};
+
+/**
+ *
+ * @param {Annotation[]} references
+ */
+BioEntity.prototype.setReferences = function (references) {
+  if (references === undefined) {
+    throw new Error("references must be defined");
+  }
+  this.references = [];
+  for (var i = 0; i < references.length; i++) {
+    this.references.push(new Annotation(references[i]));
+  }
+};
+
+/**
+ * @returns {Point}
+ */
+BioEntity.prototype.getCenter = function () {
+  throw new Error("Not implemented");
+};
+
+module.exports = BioEntity;
diff --git a/frontend-js/src/main/js/map/data/Chemical.js b/frontend-js/src/main/js/map/data/Chemical.js
index b81080341613ea28776fca293cfeea911c381cc5..1bb0049a9631c423eb8c5469f929ae4bedb212a4 100644
--- a/frontend-js/src/main/js/map/data/Chemical.js
+++ b/frontend-js/src/main/js/map/data/Chemical.js
@@ -1,113 +1,113 @@
-"use strict";
-
-var Annotation = require("./Annotation");
-var TargettingStructure = require("./TargettingStructure");
-
-/**
- *
- * @param javaObject
- * @constructor
- */
-function Chemical(javaObject) {
-  TargettingStructure.call(this, javaObject);
-  if (javaObject !== undefined) {
-    this.setReferences(javaObject.references);
-    this.setDescription(javaObject.description);
-    this.setSynonyms(javaObject.synonyms);
-
-    this.setDirectEvidence(javaObject.directEvidence);
-    this.setDirectEvidenceReferences(javaObject.directEvidenceReferences);
-  }
-}
-
-Chemical.prototype = Object.create(TargettingStructure.prototype);
-Chemical.prototype.constructor = Chemical;
-
-/**
- *
- * @param {string} directEvidence
- */
-Chemical.prototype.setDirectEvidence = function (directEvidence) {
-  this._directEvidence = directEvidence;
-};
-
-/**
- *
- * @returns {string}
- */
-Chemical.prototype.getDirectEvidence = function () {
-  return this._directEvidence;
-};
-
-/**
- *
- * @param {Annotation[]} directEvidenceReferences
- */
-Chemical.prototype.setDirectEvidenceReferences = function (directEvidenceReferences) {
-  this._directEvidenceReferences = [];
-  for (var i = 0; i < directEvidenceReferences.length; i++) {
-    this._directEvidenceReferences.push(new Annotation(directEvidenceReferences[i]));
-  }
-};
-
-
-/**
- *
- * @returns {Annotation[]}
- */
-Chemical.prototype.getDirectEvidenceReferences = function () {
-  return this._directEvidenceReferences;
-};
-
-/**
- *
- * @param {Annotation[]} references
- */
-Chemical.prototype.setReferences = function (references) {
-  this._references = [];
-  for (var i = 0; i < references.length; i++) {
-    this._references.push(new Annotation(references[i]));
-  }
-};
-
-/**
- *
- * @returns {Annotation[]}
- */
-Chemical.prototype.getReferences = function () {
-  return this._references;
-};
-
-/**
- *
- * @param {string[]} synonyms
- */
-Chemical.prototype.setSynonyms = function (synonyms) {
-  this._synonyms = synonyms;
-};
-
-/**
- *
- * @returns {string[]}
- */
-Chemical.prototype.getSynonyms = function () {
-  return this._synonyms;
-};
-
-/**
- *
- * @param {string} description
- */
-Chemical.prototype.setDescription = function (description) {
-  this._description = description;
-};
-
-/**
- *
- * @returns {string}
- */
-Chemical.prototype.getDescription = function () {
-  return this._description;
-};
-
-module.exports = Chemical;
+"use strict";
+
+var Annotation = require("./Annotation");
+var TargettingStructure = require("./TargettingStructure");
+
+/**
+ *
+ * @param javaObject
+ * @constructor
+ */
+function Chemical(javaObject) {
+  TargettingStructure.call(this, javaObject);
+  if (javaObject !== undefined) {
+    this.setReferences(javaObject.references);
+    this.setDescription(javaObject.description);
+    this.setSynonyms(javaObject.synonyms);
+
+    this.setDirectEvidence(javaObject.directEvidence);
+    this.setDirectEvidenceReferences(javaObject.directEvidenceReferences);
+  }
+}
+
+Chemical.prototype = Object.create(TargettingStructure.prototype);
+Chemical.prototype.constructor = Chemical;
+
+/**
+ *
+ * @param {string} directEvidence
+ */
+Chemical.prototype.setDirectEvidence = function (directEvidence) {
+  this._directEvidence = directEvidence;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+Chemical.prototype.getDirectEvidence = function () {
+  return this._directEvidence;
+};
+
+/**
+ *
+ * @param {Annotation[]} directEvidenceReferences
+ */
+Chemical.prototype.setDirectEvidenceReferences = function (directEvidenceReferences) {
+  this._directEvidenceReferences = [];
+  for (var i = 0; i < directEvidenceReferences.length; i++) {
+    this._directEvidenceReferences.push(new Annotation(directEvidenceReferences[i]));
+  }
+};
+
+
+/**
+ *
+ * @returns {Annotation[]}
+ */
+Chemical.prototype.getDirectEvidenceReferences = function () {
+  return this._directEvidenceReferences;
+};
+
+/**
+ *
+ * @param {Annotation[]} references
+ */
+Chemical.prototype.setReferences = function (references) {
+  this._references = [];
+  for (var i = 0; i < references.length; i++) {
+    this._references.push(new Annotation(references[i]));
+  }
+};
+
+/**
+ *
+ * @returns {Annotation[]}
+ */
+Chemical.prototype.getReferences = function () {
+  return this._references;
+};
+
+/**
+ *
+ * @param {string[]} synonyms
+ */
+Chemical.prototype.setSynonyms = function (synonyms) {
+  this._synonyms = synonyms;
+};
+
+/**
+ *
+ * @returns {string[]}
+ */
+Chemical.prototype.getSynonyms = function () {
+  return this._synonyms;
+};
+
+/**
+ *
+ * @param {string} description
+ */
+Chemical.prototype.setDescription = function (description) {
+  this._description = description;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+Chemical.prototype.getDescription = function () {
+  return this._description;
+};
+
+module.exports = Chemical;
diff --git a/frontend-js/src/main/js/map/data/Comment.js b/frontend-js/src/main/js/map/data/Comment.js
index 526ef4294432e5f00a22d020e1e47397c4d7bafd..78c6e950a557af1fc83406cef79d623b7ecc2abd 100644
--- a/frontend-js/src/main/js/map/data/Comment.js
+++ b/frontend-js/src/main/js/map/data/Comment.js
@@ -1,192 +1,192 @@
-"use strict";
-
-var IdentifiedElement = require('./IdentifiedElement');
-var Point = require('../canvas/Point');
-
-/**
- *
- * @param javaObject
- * @constructor
- */
-function Comment(javaObject) {
-  this.setIdentifiedElement(new IdentifiedElement({
-    id: javaObject.elementId,
-    type: javaObject.type,
-    modelId: javaObject.modelId,
-    icon: javaObject.icon
-  }));
-  this.setId(javaObject.id);
-  this.setRemoved(javaObject.removed);
-  this.setRemoveReason(javaObject.removeReason);
-  this.setPinned(javaObject.pinned);
-
-  if (javaObject.title !== undefined) {
-    this.setCoordinates(javaObject.coord);
-    this.setTitle(javaObject.title);
-    this.setContent(javaObject.content);
-  }
-  this.setAuthor(javaObject.author);
-  this.setEmail(javaObject.email);
-}
-
-/**
- *
- * @param {IdentifiedElement} ie
- */
-Comment.prototype.setIdentifiedElement = function (ie) {
-  this._ie = ie;
-};
-
-/**
- *
- * @returns {IdentifiedElement}
- */
-Comment.prototype.getIdentifiedElement = function () {
-  return this._ie;
-};
-
-/**
- *
- * @param {boolean} pinned
- */
-Comment.prototype.setPinned = function (pinned) {
-  this._pinned = (pinned === true);
-};
-
-/**
- *
- * @param {{x:number, y:number}} coordinates
- */
-Comment.prototype.setCoordinates = function (coordinates) {
-  this._coordinates = new Point(coordinates.x, coordinates.y);
-};
-
-/**
- *
- * @param {boolean} removed
- */
-Comment.prototype.setRemoved = function (removed) {
-  this._removed = (removed === true);
-};
-
-/**
- *
- * @param {number} id
- */
-Comment.prototype.setId = function (id) {
-  this._id = id;
-};
-
-/**
- *
- * @param {string} content
- */
-Comment.prototype.setContent = function (content) {
-  this._content = content;
-};
-
-/**
- *
- * @returns {boolean}
- */
-Comment.prototype.isPinned = function () {
-  return this._pinned;
-};
-
-/**
- *
- * @returns {Point}
- */
-Comment.prototype.getCoordinates = function () {
-  return this._coordinates;
-};
-
-/**
- *
- * @returns {boolean}
- */
-Comment.prototype.isRemoved = function () {
-  return this._removed;
-};
-
-/**
- *
- * @returns {number}
- */
-Comment.prototype.getId = function () {
-  return this._id;
-};
-
-/**
- *
- * @param {string} title
- */
-Comment.prototype.setTitle = function (title) {
-  this._title = title;
-};
-
-/**
- *
- * @returns {string}
- */
-Comment.prototype.getTitle = function () {
-  return this._title;
-};
-
-/**
- *
- * @returns {string}
- */
-Comment.prototype.getContent = function () {
-  return this._content;
-};
-
-/**
- *
- * @param {string} author
- */
-Comment.prototype.setAuthor = function (author) {
-  this._author = author;
-};
-
-/**
- *
- * @returns {string}
- */
-Comment.prototype.getAuthor = function () {
-  return this._author;
-};
-
-/**
- *
- * @param {string} email
- */
-Comment.prototype.setEmail = function (email) {
-  this._email = email;
-};
-
-/**
- *
- * @returns {string}
- */
-Comment.prototype.getEmail = function () {
-  return this._email;
-};
-
-/**
- *
- * @param {string} removeReason
- */
-Comment.prototype.setRemoveReason = function (removeReason) {
-  this._removeReason = removeReason;
-};
-
-/**
- *
- * @returns {string}
- */
-Comment.prototype.getRemoveReason = function () {
-  return this._removeReason;
-};
-
-module.exports = Comment;
+"use strict";
+
+var IdentifiedElement = require('./IdentifiedElement');
+var Point = require('../canvas/Point');
+
+/**
+ *
+ * @param javaObject
+ * @constructor
+ */
+function Comment(javaObject) {
+  this.setIdentifiedElement(new IdentifiedElement({
+    id: javaObject.elementId,
+    type: javaObject.type,
+    modelId: javaObject.modelId,
+    icon: javaObject.icon
+  }));
+  this.setId(javaObject.id);
+  this.setRemoved(javaObject.removed);
+  this.setRemoveReason(javaObject.removeReason);
+  this.setPinned(javaObject.pinned);
+
+  if (javaObject.title !== undefined) {
+    this.setCoordinates(javaObject.coord);
+    this.setTitle(javaObject.title);
+    this.setContent(javaObject.content);
+  }
+  this.setAuthor(javaObject.author);
+  this.setEmail(javaObject.email);
+}
+
+/**
+ *
+ * @param {IdentifiedElement} ie
+ */
+Comment.prototype.setIdentifiedElement = function (ie) {
+  this._ie = ie;
+};
+
+/**
+ *
+ * @returns {IdentifiedElement}
+ */
+Comment.prototype.getIdentifiedElement = function () {
+  return this._ie;
+};
+
+/**
+ *
+ * @param {boolean} pinned
+ */
+Comment.prototype.setPinned = function (pinned) {
+  this._pinned = (pinned === true);
+};
+
+/**
+ *
+ * @param {{x:number, y:number}} coordinates
+ */
+Comment.prototype.setCoordinates = function (coordinates) {
+  this._coordinates = new Point(coordinates.x, coordinates.y);
+};
+
+/**
+ *
+ * @param {boolean} removed
+ */
+Comment.prototype.setRemoved = function (removed) {
+  this._removed = (removed === true);
+};
+
+/**
+ *
+ * @param {number} id
+ */
+Comment.prototype.setId = function (id) {
+  this._id = id;
+};
+
+/**
+ *
+ * @param {string} content
+ */
+Comment.prototype.setContent = function (content) {
+  this._content = content;
+};
+
+/**
+ *
+ * @returns {boolean}
+ */
+Comment.prototype.isPinned = function () {
+  return this._pinned;
+};
+
+/**
+ *
+ * @returns {Point}
+ */
+Comment.prototype.getCoordinates = function () {
+  return this._coordinates;
+};
+
+/**
+ *
+ * @returns {boolean}
+ */
+Comment.prototype.isRemoved = function () {
+  return this._removed;
+};
+
+/**
+ *
+ * @returns {number}
+ */
+Comment.prototype.getId = function () {
+  return this._id;
+};
+
+/**
+ *
+ * @param {string} title
+ */
+Comment.prototype.setTitle = function (title) {
+  this._title = title;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+Comment.prototype.getTitle = function () {
+  return this._title;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+Comment.prototype.getContent = function () {
+  return this._content;
+};
+
+/**
+ *
+ * @param {string} author
+ */
+Comment.prototype.setAuthor = function (author) {
+  this._author = author;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+Comment.prototype.getAuthor = function () {
+  return this._author;
+};
+
+/**
+ *
+ * @param {string} email
+ */
+Comment.prototype.setEmail = function (email) {
+  this._email = email;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+Comment.prototype.getEmail = function () {
+  return this._email;
+};
+
+/**
+ *
+ * @param {string} removeReason
+ */
+Comment.prototype.setRemoveReason = function (removeReason) {
+  this._removeReason = removeReason;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+Comment.prototype.getRemoveReason = function () {
+  return this._removeReason;
+};
+
+module.exports = Comment;
diff --git a/frontend-js/src/main/js/map/data/DataOverlay.js b/frontend-js/src/main/js/map/data/DataOverlay.js
index c957147c37c78b05fc84220366908b2f2aa5ab7f..2e8b47eacd0cc9f65b75fba0c38b0517337dc621 100644
--- a/frontend-js/src/main/js/map/data/DataOverlay.js
+++ b/frontend-js/src/main/js/map/data/DataOverlay.js
@@ -1,397 +1,397 @@
-"use strict";
-
-var Promise = require("bluebird");
-
-var IdentifiedElement = require('./IdentifiedElement');
-var LayoutAlias = require('./LayoutAlias');
-var LayoutReaction = require('./LayoutReaction');
-var logger = require('../../logger');
-
-/**
- * Class representing data in a specific overlay.
- *
- * @param {number|Object} overlayId
- * @param {string} [name]
- * @constructor
- */
-function DataOverlay(overlayId, name) {
-  this.setInitialized(false);
-
-  if (name === undefined) {
-    // from json structure
-    var object = overlayId;
-    this.setId(object.idObject);
-    this.setOrder(object.order);
-    this.setName(object.name);
-    this.setImagesDirectory(object.images);
-    this.setDescription(object.description);
-    this.setCreator(object.creator);
-    this.setContent(object.content);
-    this.setFilename(object.filename);
-    this.setPublicOverlay(object.publicOverlay);
-    this.setDefaultOverlay(object.defaultOverlay);
-    this.setGoogleLicenseConsent(object.googleLicenseConsent);
-    this.setInputDataAvailable(object.inputDataAvailable);
-    this.setType(object.type);
-    if (!this.getInputDataAvailable()) {
-      this.setInitialized(true);
-    }
-  } else {
-    // default two param call
-    this.setId(overlayId);
-    this.setName(name);
-  }
-  this.aliases = [];
-  this.aliasById = [];
-  this.reactions = [];
-}
-
-/**
- * Adds alias to the {@link DataOverlay}
- *
- * @param {LayoutAlias} overlayAlias
- *          information about alias in the overlay
- */
-DataOverlay.prototype.addAlias = function (overlayAlias) {
-  this.aliases.push(overlayAlias);
-  this.aliasById[overlayAlias.getId()] = overlayAlias;
-};
-
-/**
- * Adds reaction to the {@link DataOverlay}
- *
- * @param {LayoutReaction} overlayReaction
- *          information about reaction in the overlay
- */
-DataOverlay.prototype.addReaction = function (overlayReaction) {
-  this.reactions.push(overlayReaction);
-};
-
-/**
- *
- * @returns {number}
- */
-DataOverlay.prototype.getId = function () {
-  return this.id;
-};
-
-/**
- *
- * @param {number|string} id
- */
-DataOverlay.prototype.setId = function (id) {
-  this.id = parseInt(id);
-};
-
-/**
- *
- * @returns {string}
- */
-DataOverlay.prototype.getDescription = function () {
-  return this._description;
-};
-
-/**
- *
- * @param {string} description
- */
-DataOverlay.prototype.setDescription = function (description) {
-  this._description = description;
-};
-
-/**
- *
- * @returns {string}
- */
-DataOverlay.prototype.getCreator = function () {
-  return this._creator;
-};
-
-/**
- *
- * @param {string} creator
- */
-DataOverlay.prototype.setCreator = function (creator) {
-  this._creator = creator;
-};
-
-/**
- *
- * @returns {boolean}
- */
-DataOverlay.prototype.getInputDataAvailable = function () {
-  return this._inputDataAvailable;
-};
-
-/**
- *
- * @param {string|boolean} inputDataAvailable
- */
-DataOverlay.prototype.setInputDataAvailable = function (inputDataAvailable) {
-  var value = inputDataAvailable;
-  if (inputDataAvailable === undefined) {
-    value = false;
-  } else if (inputDataAvailable === "true") {
-    value = true;
-  } else if (inputDataAvailable === "false") {
-    value = false;
-  } else if (typeof (inputDataAvailable) !== "boolean") {
-    logger.warn("inputDataAvailable should be boolean");
-    value = false;
-  }
-  this._inputDataAvailable = value;
-};
-
-/**
- *
- * @returns {string}
- */
-DataOverlay.prototype.getName = function () {
-  return this.name;
-};
-
-/**
- *
- * @param {string} name
- */
-DataOverlay.prototype.setName = function (name) {
-  this.name = name;
-};
-
-/**
- *
- * @param {number} modelId
- * @returns {string|null}
- */
-DataOverlay.prototype.getImagesDirectory = function (modelId) {
-  for (var i = 0; i < this._imagesDirectory.length; i++) {
-    if (parseInt(this._imagesDirectory[i].modelId) === modelId) {
-      return this._imagesDirectory[i].path;
-    }
-  }
-  return null;
-};
-
-/**
- *
- * @param {Object.<number,string>} imagesDirectory
- */
-DataOverlay.prototype.setImagesDirectory = function (imagesDirectory) {
-  this._imagesDirectory = imagesDirectory;
-};
-
-/**
- *
- * @param {LayoutAlias} overlayAlias
- */
-DataOverlay.prototype.updateAlias = function (overlayAlias) {
-  if (this.aliasById[overlayAlias.getId()] === undefined) {
-    logger.warn("Cannot update alias, it doesn't exist. Alias: " + overlayAlias.getId());
-  } else {
-    this.aliasById[overlayAlias.getId()].update(overlayAlias);
-  }
-};
-
-/**
- *
- * @param {number} id
- * @returns {LayoutAlias}
- */
-DataOverlay.prototype.getAliasById = function (id) {
-  return this.aliasById[id];
-};
-
-/**
- *
- * @param {number} id
- * @returns {Promise<LayoutAlias>}
- */
-DataOverlay.prototype.getFullAliasById = function (id) {
-  var self = this;
-  var alias = self.getAliasById(id);
-  if (alias !== undefined) {
-    if (alias.getType() === LayoutAlias.LIGHT) {
-      return ServerConnector.getFullOverlayElement({
-        element: new IdentifiedElement(alias),
-        overlay: self
-      }).then(function (data) {
-        self.updateAlias(data);
-        return alias;
-      });
-    }
-  }
-  return Promise.resolve(alias);
-};
-
-/**
- *
- * @param {boolean} value
- */
-DataOverlay.prototype.setInitialized = function (value) {
-  this._initialized = value;
-};
-
-/**
- *
- * @returns {boolean}
- */
-DataOverlay.prototype.isInitialized = function () {
-  return this._initialized;
-};
-
-/**
- *
- * @returns {LayoutAlias[]}
- */
-DataOverlay.prototype.getAliases = function () {
-  return this.aliases;
-};
-
-/**
- *
- * @returns {LayoutReaction[]}
- */
-DataOverlay.prototype.getReactions = function () {
-  return this.reactions;
-};
-
-/**
- *
- * @returns {Promise}
- */
-DataOverlay.prototype.init = function () {
-  var self = this;
-  if (this.isInitialized()) {
-    return Promise.resolve();
-  }
-  return ServerConnector.getOverlayElements(self.getId()).then(function (data) {
-    for (var i = 0; i < data.length; i++) {
-      if (data[i] instanceof LayoutAlias) {
-        self.addAlias(data[i]);
-      } else if (data[i] instanceof LayoutReaction) {
-        self.addReaction(data[i]);
-      } else {
-        return Promise.reject("Unknown element type: " + typeof (data[i]));
-      }
-
-    }
-    self.setInitialized(true);
-  });
-
-};
-
-/**
- *
- * @returns {boolean}
- */
-DataOverlay.prototype.getPublicOverlay = function () {
-  return this._publicOverlay;
-};
-
-/**
- *
- * @param {boolean} publicOverlay
- */
-DataOverlay.prototype.setPublicOverlay = function (publicOverlay) {
-  this._publicOverlay = publicOverlay;
-};
-
-/**
- *
- * @returns {boolean}
- */
-DataOverlay.prototype.isDefaultOverlay = function () {
-  return this._defaultOverlay;
-};
-
-/**
- *
- * @param {boolean} defaultOverlay
- */
-DataOverlay.prototype.setDefaultOverlay = function (defaultOverlay) {
-  this._defaultOverlay = defaultOverlay;
-};
-
-/**
- *
- * @returns {string}
- */
-DataOverlay.prototype.getContent = function () {
-  return this._content;
-};
-
-/**
- *
- * @param {string} content
- */
-DataOverlay.prototype.setContent = function (content) {
-  this._content = content;
-};
-
-/**
- *
- * @returns {number}
- */
-DataOverlay.prototype.getOrder = function () {
-  return this._order;
-};
-
-/**
- *
- * @param {number} order
- */
-DataOverlay.prototype.setOrder = function (order) {
-  this._order = order;
-};
-
-/**
- *
- * @returns {string}
- */
-DataOverlay.prototype.getFilename = function () {
-  return this._filename;
-};
-
-/**
- *
- * @param {string} filename
- */
-DataOverlay.prototype.setFilename = function (filename) {
-  this._filename = filename;
-};
-
-/**
- *
- * @returns {string}
- */
-DataOverlay.prototype.getType = function () {
-  return this._type;
-};
-
-/**
- *
- * @param {string} type
- */
-DataOverlay.prototype.setType = function (type) {
-  this._type = type;
-};
-
-DataOverlay.prototype.setGoogleLicenseConsent = function(value) {
-  this._googleLicenseConsent = value;
-};
-
-DataOverlay.prototype.isGoogleLicenseConsent = function() {
-  return this._googleLicenseConsent;
-};
-
-/**
- *
- * @param {DataOverlay} overlay
- */
-DataOverlay.prototype.update = function (overlay) {
-  this.setName(overlay.getName());
-  this.setDescription(overlay.getDescription());
-};
-
-
-module.exports = DataOverlay;
+"use strict";
+
+var Promise = require("bluebird");
+
+var IdentifiedElement = require('./IdentifiedElement');
+var LayoutAlias = require('./LayoutAlias');
+var LayoutReaction = require('./LayoutReaction');
+var logger = require('../../logger');
+
+/**
+ * Class representing data in a specific overlay.
+ *
+ * @param {number|Object} overlayId
+ * @param {string} [name]
+ * @constructor
+ */
+function DataOverlay(overlayId, name) {
+  this.setInitialized(false);
+
+  if (name === undefined) {
+    // from json structure
+    var object = overlayId;
+    this.setId(object.idObject);
+    this.setOrder(object.order);
+    this.setName(object.name);
+    this.setImagesDirectory(object.images);
+    this.setDescription(object.description);
+    this.setCreator(object.creator);
+    this.setContent(object.content);
+    this.setFilename(object.filename);
+    this.setPublicOverlay(object.publicOverlay);
+    this.setDefaultOverlay(object.defaultOverlay);
+    this.setGoogleLicenseConsent(object.googleLicenseConsent);
+    this.setInputDataAvailable(object.inputDataAvailable);
+    this.setType(object.type);
+    if (!this.getInputDataAvailable()) {
+      this.setInitialized(true);
+    }
+  } else {
+    // default two param call
+    this.setId(overlayId);
+    this.setName(name);
+  }
+  this.aliases = [];
+  this.aliasById = [];
+  this.reactions = [];
+}
+
+/**
+ * Adds alias to the {@link DataOverlay}
+ *
+ * @param {LayoutAlias} overlayAlias
+ *          information about alias in the overlay
+ */
+DataOverlay.prototype.addAlias = function (overlayAlias) {
+  this.aliases.push(overlayAlias);
+  this.aliasById[overlayAlias.getId()] = overlayAlias;
+};
+
+/**
+ * Adds reaction to the {@link DataOverlay}
+ *
+ * @param {LayoutReaction} overlayReaction
+ *          information about reaction in the overlay
+ */
+DataOverlay.prototype.addReaction = function (overlayReaction) {
+  this.reactions.push(overlayReaction);
+};
+
+/**
+ *
+ * @returns {number}
+ */
+DataOverlay.prototype.getId = function () {
+  return this.id;
+};
+
+/**
+ *
+ * @param {number|string} id
+ */
+DataOverlay.prototype.setId = function (id) {
+  this.id = parseInt(id);
+};
+
+/**
+ *
+ * @returns {string}
+ */
+DataOverlay.prototype.getDescription = function () {
+  return this._description;
+};
+
+/**
+ *
+ * @param {string} description
+ */
+DataOverlay.prototype.setDescription = function (description) {
+  this._description = description;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+DataOverlay.prototype.getCreator = function () {
+  return this._creator;
+};
+
+/**
+ *
+ * @param {string} creator
+ */
+DataOverlay.prototype.setCreator = function (creator) {
+  this._creator = creator;
+};
+
+/**
+ *
+ * @returns {boolean}
+ */
+DataOverlay.prototype.getInputDataAvailable = function () {
+  return this._inputDataAvailable;
+};
+
+/**
+ *
+ * @param {string|boolean} inputDataAvailable
+ */
+DataOverlay.prototype.setInputDataAvailable = function (inputDataAvailable) {
+  var value = inputDataAvailable;
+  if (inputDataAvailable === undefined) {
+    value = false;
+  } else if (inputDataAvailable === "true") {
+    value = true;
+  } else if (inputDataAvailable === "false") {
+    value = false;
+  } else if (typeof (inputDataAvailable) !== "boolean") {
+    logger.warn("inputDataAvailable should be boolean");
+    value = false;
+  }
+  this._inputDataAvailable = value;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+DataOverlay.prototype.getName = function () {
+  return this.name;
+};
+
+/**
+ *
+ * @param {string} name
+ */
+DataOverlay.prototype.setName = function (name) {
+  this.name = name;
+};
+
+/**
+ *
+ * @param {number} modelId
+ * @returns {string|null}
+ */
+DataOverlay.prototype.getImagesDirectory = function (modelId) {
+  for (var i = 0; i < this._imagesDirectory.length; i++) {
+    if (parseInt(this._imagesDirectory[i].modelId) === modelId) {
+      return this._imagesDirectory[i].path;
+    }
+  }
+  return null;
+};
+
+/**
+ *
+ * @param {Object.<number,string>} imagesDirectory
+ */
+DataOverlay.prototype.setImagesDirectory = function (imagesDirectory) {
+  this._imagesDirectory = imagesDirectory;
+};
+
+/**
+ *
+ * @param {LayoutAlias} overlayAlias
+ */
+DataOverlay.prototype.updateAlias = function (overlayAlias) {
+  if (this.aliasById[overlayAlias.getId()] === undefined) {
+    logger.warn("Cannot update alias, it doesn't exist. Alias: " + overlayAlias.getId());
+  } else {
+    this.aliasById[overlayAlias.getId()].update(overlayAlias);
+  }
+};
+
+/**
+ *
+ * @param {number} id
+ * @returns {LayoutAlias}
+ */
+DataOverlay.prototype.getAliasById = function (id) {
+  return this.aliasById[id];
+};
+
+/**
+ *
+ * @param {number} id
+ * @returns {Promise<LayoutAlias>}
+ */
+DataOverlay.prototype.getFullAliasById = function (id) {
+  var self = this;
+  var alias = self.getAliasById(id);
+  if (alias !== undefined) {
+    if (alias.getType() === LayoutAlias.LIGHT) {
+      return ServerConnector.getFullOverlayElement({
+        element: new IdentifiedElement(alias),
+        overlay: self
+      }).then(function (data) {
+        self.updateAlias(data);
+        return alias;
+      });
+    }
+  }
+  return Promise.resolve(alias);
+};
+
+/**
+ *
+ * @param {boolean} value
+ */
+DataOverlay.prototype.setInitialized = function (value) {
+  this._initialized = value;
+};
+
+/**
+ *
+ * @returns {boolean}
+ */
+DataOverlay.prototype.isInitialized = function () {
+  return this._initialized;
+};
+
+/**
+ *
+ * @returns {LayoutAlias[]}
+ */
+DataOverlay.prototype.getAliases = function () {
+  return this.aliases;
+};
+
+/**
+ *
+ * @returns {LayoutReaction[]}
+ */
+DataOverlay.prototype.getReactions = function () {
+  return this.reactions;
+};
+
+/**
+ *
+ * @returns {Promise}
+ */
+DataOverlay.prototype.init = function () {
+  var self = this;
+  if (this.isInitialized()) {
+    return Promise.resolve();
+  }
+  return ServerConnector.getOverlayElements(self.getId()).then(function (data) {
+    for (var i = 0; i < data.length; i++) {
+      if (data[i] instanceof LayoutAlias) {
+        self.addAlias(data[i]);
+      } else if (data[i] instanceof LayoutReaction) {
+        self.addReaction(data[i]);
+      } else {
+        return Promise.reject("Unknown element type: " + typeof (data[i]));
+      }
+
+    }
+    self.setInitialized(true);
+  });
+
+};
+
+/**
+ *
+ * @returns {boolean}
+ */
+DataOverlay.prototype.getPublicOverlay = function () {
+  return this._publicOverlay;
+};
+
+/**
+ *
+ * @param {boolean} publicOverlay
+ */
+DataOverlay.prototype.setPublicOverlay = function (publicOverlay) {
+  this._publicOverlay = publicOverlay;
+};
+
+/**
+ *
+ * @returns {boolean}
+ */
+DataOverlay.prototype.isDefaultOverlay = function () {
+  return this._defaultOverlay;
+};
+
+/**
+ *
+ * @param {boolean} defaultOverlay
+ */
+DataOverlay.prototype.setDefaultOverlay = function (defaultOverlay) {
+  this._defaultOverlay = defaultOverlay;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+DataOverlay.prototype.getContent = function () {
+  return this._content;
+};
+
+/**
+ *
+ * @param {string} content
+ */
+DataOverlay.prototype.setContent = function (content) {
+  this._content = content;
+};
+
+/**
+ *
+ * @returns {number}
+ */
+DataOverlay.prototype.getOrder = function () {
+  return this._order;
+};
+
+/**
+ *
+ * @param {number} order
+ */
+DataOverlay.prototype.setOrder = function (order) {
+  this._order = order;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+DataOverlay.prototype.getFilename = function () {
+  return this._filename;
+};
+
+/**
+ *
+ * @param {string} filename
+ */
+DataOverlay.prototype.setFilename = function (filename) {
+  this._filename = filename;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+DataOverlay.prototype.getType = function () {
+  return this._type;
+};
+
+/**
+ *
+ * @param {string} type
+ */
+DataOverlay.prototype.setType = function (type) {
+  this._type = type;
+};
+
+DataOverlay.prototype.setGoogleLicenseConsent = function(value) {
+  this._googleLicenseConsent = value;
+};
+
+DataOverlay.prototype.isGoogleLicenseConsent = function() {
+  return this._googleLicenseConsent;
+};
+
+/**
+ *
+ * @param {DataOverlay} overlay
+ */
+DataOverlay.prototype.update = function (overlay) {
+  this.setName(overlay.getName());
+  this.setDescription(overlay.getDescription());
+};
+
+
+module.exports = DataOverlay;
diff --git a/frontend-js/src/main/js/map/data/Drug.js b/frontend-js/src/main/js/map/data/Drug.js
index cebafe5a1cac2227db9a1e0f8496d22fa35b751d..3addb61d5c5ae5ac878e3a8be9683ebf277d776a 100644
--- a/frontend-js/src/main/js/map/data/Drug.js
+++ b/frontend-js/src/main/js/map/data/Drug.js
@@ -1,108 +1,108 @@
-"use strict";
-
-var Annotation = require("./Annotation");
-var TargettingStructure = require("./TargettingStructure");
-
-/**
- *
- * @param javaObject
- * @constructor
- */
-function Drug(javaObject) {
-  TargettingStructure.call(this, javaObject);
-  if (javaObject !== undefined) {
-    this.setBrandNames(javaObject.brandNames);
-    this.setReferences(javaObject.references);
-    this.setSynonyms(javaObject.synonyms);
-    this.setDescription(javaObject.description);
-    this.setBloodBrainBarrier(javaObject.bloodBrainBarrier);
-  }
-}
-
-Drug.prototype = Object.create(TargettingStructure.prototype);
-Drug.prototype.constructor = Drug;
-
-/**
- *
- * @param {string[]} brandNames
- */
-Drug.prototype.setBrandNames = function (brandNames) {
-  this._brandNames = brandNames;
-};
-
-/**
- *
- * @returns {string[]}
- */
-Drug.prototype.getBrandNames = function () {
-  return this._brandNames;
-};
-
-/**
- *
- * @param {Annotation[]}references
- */
-Drug.prototype.setReferences = function (references) {
-  this._references = [];
-  for (var i = 0; i < references.length; i++) {
-    this._references.push(new Annotation(references[i]));
-  }
-};
-
-/**
- *
- * @returns {Annotation[]}
- */
-Drug.prototype.getReferences = function () {
-  return this._references;
-};
-
-/**
- *
- * @param {string[]} synonyms
- */
-Drug.prototype.setSynonyms = function (synonyms) {
-  this._synonyms = synonyms;
-};
-
-/**
- *
- * @returns {string[]}
- */
-Drug.prototype.getSynonyms = function () {
-  return this._synonyms;
-};
-
-/**
- *
- * @param {string} description
- */
-Drug.prototype.setDescription = function (description) {
-  this._description = description;
-};
-
-/**
- *
- * @returns {string}
- */
-Drug.prototype.getDescription = function () {
-  return this._description;
-};
-
-/**
- *
- * @param {boolean} bloodBrainBarrier
- */
-Drug.prototype.setBloodBrainBarrier = function (bloodBrainBarrier) {
-  this._bloodBrainBarrier = bloodBrainBarrier;
-};
-
-/**
- *
- * @returns {boolean}
- */
-Drug.prototype.getBloodBrainBarrier = function () {
-  return this._bloodBrainBarrier;
-};
-
-module.exports = Drug;
+"use strict";
+
+var Annotation = require("./Annotation");
+var TargettingStructure = require("./TargettingStructure");
+
+/**
+ *
+ * @param javaObject
+ * @constructor
+ */
+function Drug(javaObject) {
+  TargettingStructure.call(this, javaObject);
+  if (javaObject !== undefined) {
+    this.setBrandNames(javaObject.brandNames);
+    this.setReferences(javaObject.references);
+    this.setSynonyms(javaObject.synonyms);
+    this.setDescription(javaObject.description);
+    this.setBloodBrainBarrier(javaObject.bloodBrainBarrier);
+  }
+}
+
+Drug.prototype = Object.create(TargettingStructure.prototype);
+Drug.prototype.constructor = Drug;
+
+/**
+ *
+ * @param {string[]} brandNames
+ */
+Drug.prototype.setBrandNames = function (brandNames) {
+  this._brandNames = brandNames;
+};
+
+/**
+ *
+ * @returns {string[]}
+ */
+Drug.prototype.getBrandNames = function () {
+  return this._brandNames;
+};
+
+/**
+ *
+ * @param {Annotation[]}references
+ */
+Drug.prototype.setReferences = function (references) {
+  this._references = [];
+  for (var i = 0; i < references.length; i++) {
+    this._references.push(new Annotation(references[i]));
+  }
+};
+
+/**
+ *
+ * @returns {Annotation[]}
+ */
+Drug.prototype.getReferences = function () {
+  return this._references;
+};
+
+/**
+ *
+ * @param {string[]} synonyms
+ */
+Drug.prototype.setSynonyms = function (synonyms) {
+  this._synonyms = synonyms;
+};
+
+/**
+ *
+ * @returns {string[]}
+ */
+Drug.prototype.getSynonyms = function () {
+  return this._synonyms;
+};
+
+/**
+ *
+ * @param {string} description
+ */
+Drug.prototype.setDescription = function (description) {
+  this._description = description;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+Drug.prototype.getDescription = function () {
+  return this._description;
+};
+
+/**
+ *
+ * @param {boolean} bloodBrainBarrier
+ */
+Drug.prototype.setBloodBrainBarrier = function (bloodBrainBarrier) {
+  this._bloodBrainBarrier = bloodBrainBarrier;
+};
+
+/**
+ *
+ * @returns {boolean}
+ */
+Drug.prototype.getBloodBrainBarrier = function () {
+  return this._bloodBrainBarrier;
+};
+
+module.exports = Drug;
diff --git a/frontend-js/src/main/js/map/data/GeneVariant.js b/frontend-js/src/main/js/map/data/GeneVariant.js
index 50fa4462f2eecc232ad702e927cdd6dfbed6928b..166b1edb754f5c2b62cd0d5abc43f18ceb15de00 100644
--- a/frontend-js/src/main/js/map/data/GeneVariant.js
+++ b/frontend-js/src/main/js/map/data/GeneVariant.js
@@ -1,164 +1,164 @@
-"use strict";
-
-/**
- *
- * @param {Object} javaObject
- * @param {number} javaObject.position
- * @param {string} javaObject.originalDna
- * @param {string} javaObject.modifiedDna
- * @param {string} javaObject.referenceGenomeType
- * @param {string} javaObject.referenceGenomeVersion
- * @param {string} javaObject.contig
- * @param {null|number} [javaObject.allelFrequency]
- * @param {null|string} [javaObject.variantIdentifier]
- *
- * @constructor
- */
-function GeneVariant(javaObject) {
-  this.setPosition(javaObject.position);
-  this.setOriginalDna(javaObject.originalDna);
-  this.setModifiedDna(javaObject.modifiedDna);
-  this.setReferenceGenomeType(javaObject.referenceGenomeType);
-  this.setReferenceGenomeVersion(javaObject.referenceGenomeVersion);
-  this.setContig(javaObject.contig);
-  this.setAllelFrequency(javaObject.allelFrequency);
-  this.setVariantIdentifier(javaObject.variantIdentifier);
-}
-
-/**
- *
- * @param {number} position
- */
-GeneVariant.prototype.setPosition = function (position) {
-  this._position = position;
-};
-
-/**
- *
- * @returns {number}
- */
-GeneVariant.prototype.getPosition = function () {
-  return this._position;
-};
-
-/**
- *
- * @param {string} originalDna
- */
-GeneVariant.prototype.setOriginalDna = function (originalDna) {
-  this._original = originalDna;
-};
-
-/**
- *
- * @returns {string}
- */
-GeneVariant.prototype.getOriginalDna = function () {
-  return this._original;
-};
-
-/**
- *
- * @param {string} modifiedDna
- */
-GeneVariant.prototype.setModifiedDna = function (modifiedDna) {
-  this._modifiedDna = modifiedDna;
-};
-
-/**
- *
- * @returns {string}
- */
-GeneVariant.prototype.getModifiedDna = function () {
-  return this._modifiedDna;
-};
-
-/**
- *
- * @param {string} contig
- */
-GeneVariant.prototype.setContig = function (contig) {
-  this._contig = contig;
-};
-
-/**
- *
- * @returns {string}
- */
-GeneVariant.prototype.getContig = function () {
-  return this._contig;
-};
-
-/**
- *
- * @param {number} allelFrequency
- */
-GeneVariant.prototype.setAllelFrequency = function (allelFrequency) {
-  if (allelFrequency === null) {
-    this._allelFrequency = undefined;
-  } else {
-    this._allelFrequency = allelFrequency;
-  }
-};
-
-/**
- *
- * @returns {number}
- */
-GeneVariant.prototype.getAllelFrequency = function () {
-  return this._allelFrequency;
-};
-
-/**
- *
- * @param {string} variantIdentifier
- */
-GeneVariant.prototype.setVariantIdentifier = function (variantIdentifier) {
-  if (variantIdentifier === null) {
-    this._variantIdentifier = undefined;
-  } else {
-    this._variantIdentifier = variantIdentifier;
-  }
-};
-
-/**
- *
- * @returns {string}
- */
-GeneVariant.prototype.getVariantIdentifier = function () {
-  return this._variantIdentifier;
-};
-
-/**
- *
- * @param {string} referenceGenomeType
- */
-GeneVariant.prototype.setReferenceGenomeType = function (referenceGenomeType) {
-  this._referenceGenomeType = referenceGenomeType;
-};
-
-/**
- *
- * @returns {string}
- */
-GeneVariant.prototype.getReferenceGenomeType = function () {
-  return this._referenceGenomeType;
-};
-
-/**
- *
- * @param {string} referenceGenomeVersion
- */
-GeneVariant.prototype.setReferenceGenomeVersion = function (referenceGenomeVersion) {
-  this._referenceGenomeVersion = referenceGenomeVersion;
-};
-
-/**
- *
- * @returns {string}
- */
-GeneVariant.prototype.getReferenceGenomeVersion = function () {
-  return this._referenceGenomeVersion;
-};
-
-module.exports = GeneVariant;
+"use strict";
+
+/**
+ *
+ * @param {Object} javaObject
+ * @param {number} javaObject.position
+ * @param {string} javaObject.originalDna
+ * @param {string} javaObject.modifiedDna
+ * @param {string} javaObject.referenceGenomeType
+ * @param {string} javaObject.referenceGenomeVersion
+ * @param {string} javaObject.contig
+ * @param {null|number} [javaObject.allelFrequency]
+ * @param {null|string} [javaObject.variantIdentifier]
+ *
+ * @constructor
+ */
+function GeneVariant(javaObject) {
+  this.setPosition(javaObject.position);
+  this.setOriginalDna(javaObject.originalDna);
+  this.setModifiedDna(javaObject.modifiedDna);
+  this.setReferenceGenomeType(javaObject.referenceGenomeType);
+  this.setReferenceGenomeVersion(javaObject.referenceGenomeVersion);
+  this.setContig(javaObject.contig);
+  this.setAllelFrequency(javaObject.allelFrequency);
+  this.setVariantIdentifier(javaObject.variantIdentifier);
+}
+
+/**
+ *
+ * @param {number} position
+ */
+GeneVariant.prototype.setPosition = function (position) {
+  this._position = position;
+};
+
+/**
+ *
+ * @returns {number}
+ */
+GeneVariant.prototype.getPosition = function () {
+  return this._position;
+};
+
+/**
+ *
+ * @param {string} originalDna
+ */
+GeneVariant.prototype.setOriginalDna = function (originalDna) {
+  this._original = originalDna;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+GeneVariant.prototype.getOriginalDna = function () {
+  return this._original;
+};
+
+/**
+ *
+ * @param {string} modifiedDna
+ */
+GeneVariant.prototype.setModifiedDna = function (modifiedDna) {
+  this._modifiedDna = modifiedDna;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+GeneVariant.prototype.getModifiedDna = function () {
+  return this._modifiedDna;
+};
+
+/**
+ *
+ * @param {string} contig
+ */
+GeneVariant.prototype.setContig = function (contig) {
+  this._contig = contig;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+GeneVariant.prototype.getContig = function () {
+  return this._contig;
+};
+
+/**
+ *
+ * @param {number} allelFrequency
+ */
+GeneVariant.prototype.setAllelFrequency = function (allelFrequency) {
+  if (allelFrequency === null) {
+    this._allelFrequency = undefined;
+  } else {
+    this._allelFrequency = allelFrequency;
+  }
+};
+
+/**
+ *
+ * @returns {number}
+ */
+GeneVariant.prototype.getAllelFrequency = function () {
+  return this._allelFrequency;
+};
+
+/**
+ *
+ * @param {string} variantIdentifier
+ */
+GeneVariant.prototype.setVariantIdentifier = function (variantIdentifier) {
+  if (variantIdentifier === null) {
+    this._variantIdentifier = undefined;
+  } else {
+    this._variantIdentifier = variantIdentifier;
+  }
+};
+
+/**
+ *
+ * @returns {string}
+ */
+GeneVariant.prototype.getVariantIdentifier = function () {
+  return this._variantIdentifier;
+};
+
+/**
+ *
+ * @param {string} referenceGenomeType
+ */
+GeneVariant.prototype.setReferenceGenomeType = function (referenceGenomeType) {
+  this._referenceGenomeType = referenceGenomeType;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+GeneVariant.prototype.getReferenceGenomeType = function () {
+  return this._referenceGenomeType;
+};
+
+/**
+ *
+ * @param {string} referenceGenomeVersion
+ */
+GeneVariant.prototype.setReferenceGenomeVersion = function (referenceGenomeVersion) {
+  this._referenceGenomeVersion = referenceGenomeVersion;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+GeneVariant.prototype.getReferenceGenomeVersion = function () {
+  return this._referenceGenomeVersion;
+};
+
+module.exports = GeneVariant;
diff --git a/frontend-js/src/main/js/map/data/IdentifiedElement.js b/frontend-js/src/main/js/map/data/IdentifiedElement.js
index 59d26d826ed8f1c0d22ef80dbd2dba4459cdf471..855cdf88c3bf000faa5a37f4c6747939e682691a 100644
--- a/frontend-js/src/main/js/map/data/IdentifiedElement.js
+++ b/frontend-js/src/main/js/map/data/IdentifiedElement.js
@@ -1,250 +1,250 @@
-"use strict";
-
-var Alias = require('./Alias');
-var LayoutAlias = require('./LayoutAlias');
-var Reaction = require('./Reaction');
-var LayoutReaction = require('./LayoutReaction');
-var PointData = require('./PointData');
-var Point = require('../canvas/Point');
-
-var logger = require('../../logger');
-
-/**
- * @typedef {Object} IdentifiedElementInput
- * @property {string|number} [id]
- * @property {string|number} [objectId]
- * @property {number} modelId
- * @property {string} type
- * @property {string} [icon]
- */
-
-/**
- * This is object representing element tha should be visualized on the map. It's
- * very light and contains only the most important data. There are three types
- * of objects to visualize:
- * <ul>
- * <li>"ALIAS" - for {@link Alias} objects</li>
- * <li>"REACTION" - for {@link Reaction} objects</li>
- * <li>"POINT" - for any point on the map, the data connected to this kind of
- * objects are stored in {@link PointData}</li>
- * </ul>
- *
- * @param {BioEntity|LayoutAlias|LayoutReaction|PointData|IdentifiedElementInput} object
- * @constructor
- */
-function IdentifiedElement(object) {
-  this._visualizationdata = {};
-  if (object instanceof Alias) {
-    this.setId(object.getId());
-    this.setModelId(object.getModelId());
-    this.setType("ALIAS");
-  } else if (object instanceof LayoutAlias) {
-    this.setId(object.getId());
-    this.setModelId(object.getModelId());
-    this.setType("ALIAS");
-  } else if (object instanceof Reaction) {
-    this.setId(object.getId());
-    this.setModelId(object.getModelId());
-    this.setType("REACTION");
-  } else if (object instanceof LayoutReaction) {
-    this.setId(object.getId());
-    this.setModelId(object.getModelId());
-    this.setType("REACTION");
-  } else if (object instanceof PointData) {
-    this.setId(object.getId());
-    this.setModelId(object.getModelId());
-    this.setType("POINT");
-  } else {
-    // identifier of the object to visualize
-    if (object.objectId === undefined) {
-      this.setId(object.id);
-    } else {
-      this.setId(object.objectId);
-    }
-    // which marker should be used to show this object
-    this.setIcon(object.icon);
-    // on which model the element is located
-    this.setModelId(object.modelId);
-    // what kind of object we are talking about
-    this.setType(object.type);
-  }
-
-  if (this.getType() === "POINT") {
-    var tmp = this.getId();
-    if (tmp.indexOf("Point2D.Double") >= 0) {
-      tmp = tmp.replace("Point2D.Double", "");
-      tmp = JSON.parse(tmp);
-    } else {
-      tmp = tmp.replace("(", "");
-      tmp = tmp.replace(")", "");
-      tmp = tmp.split(",");
-    }
-    var x = parseFloat(tmp[0]).toFixed(2);
-    var y = parseFloat(tmp[1]).toFixed(2);
-    this._point = new Point(x, y);
-    this.setId("(" + x + "," + y + ")");
-  } else if (this.getType() !== "ALIAS" && this.getType() !== "REACTION") {
-    throw new Error("Unknown type of identified element: " + this.getType());
-  }
-
-  if (this.getId() === undefined) {
-    throw new Error("Id not defined for element: " + object);
-  }
-}
-
-/**
- * Returns point where it should be visualized when the type of object is
- * "POINT".
- *
- * @returns {Point|null} where it should be visualized when the
- *          type of object is "POINT".
- */
-IdentifiedElement.prototype.getPoint = function () {
-  if (this._point === undefined || this._point === null) {
-    logger.warn("No point associated with IdentifiedElement");
-    return null;
-  } else {
-    return this._point;
-  }
-};
-
-/**
- * Returns element identifier.
- *
- * @returns {string|number} element identifier
- */
-IdentifiedElement.prototype.getId = function () {
-  return this.id;
-};
-
-IdentifiedElement.prototype.setId = function (id) {
-  // some elements are identified by id that is not a number (like point on the
-  // map)
-  if (!isNaN(id)) {
-    id = parseInt(id);
-  }
-  this.id = id;
-};
-
-/**
- *
- * @param {number|string} modelId
- */
-IdentifiedElement.prototype.setModelId = function (modelId) {
-  if (modelId === undefined || modelId === null) {
-    throw new Error("ModelId is invalid");
-  }
-  this.modelId = parseInt(modelId);
-};
-
-/**
- * Returns model identifier where element is placed.
- *
- * @returns {number} model identifier
- */
-IdentifiedElement.prototype.getModelId = function () {
-  return this.modelId;
-};
-
-/**
- * Returns type of the element. For now only three types are allowed:
- * <ul>
- * <li>"ALIAS" - for {@link Alias} objects</li>
- * <li>"REACTION" - for {@link Reaction} objects</li>
- * <li>"POINT" - for any point on the map, the data connected to this kind of
- * objects are stored in {@link PointData}</li>
- * </ul>
- *
- * @returns {string} type of the element
- */
-IdentifiedElement.prototype.getType = function () {
-  return this.type;
-};
-
-IdentifiedElement.prototype.setType = function (type) {
-  if (type === undefined || type === null) {
-    throw new Error("Type not defined");
-  }
-
-  this.type = type.toUpperCase();
-};
-
-/**
- * Returns icon that should be used for visualization.
- *
- * @returns {string|undefined} icon that should be used for visualization
- */
-IdentifiedElement.prototype.getIcon = function () {
-  return this._visualizationdata._icon;
-};
-
-/**
- *
- * @param {string} icon
- */
-IdentifiedElement.prototype.setIcon = function (icon) {
-  this._visualizationdata._icon = icon;
-};
-
-/**
- * @returns {string|undefined}
- */
-IdentifiedElement.prototype.getColor = function () {
-  return this._visualizationdata._color;
-};
-
-IdentifiedElement.prototype.setColor = function (color) {
-  this._visualizationdata._color = color;
-};
-
-IdentifiedElement.prototype.getOpacity = function () {
-  return this._visualizationdata._opacity;
-};
-
-IdentifiedElement.prototype.setOpacity = function (opacity) {
-  this._visualizationdata._opacity = opacity;
-};
-
-IdentifiedElement.prototype.getLineWeight = function () {
-  return this._visualizationdata._lineWeight;
-};
-
-IdentifiedElement.prototype.setLineWeight = function (lineWeight) {
-  this._visualizationdata._lineWeight = lineWeight;
-};
-IdentifiedElement.prototype.getLineOpacity = function () {
-  return this._visualizationdata._lineOpacity;
-};
-
-IdentifiedElement.prototype.setLineOpacity = function (lineOpacity) {
-  this._visualizationdata._lineOpacity = lineOpacity;
-};
-IdentifiedElement.prototype.getLineColor = function () {
-  return this._visualizationdata._lineColor;
-};
-
-IdentifiedElement.prototype.setLineColor = function (lineColor) {
-  this._visualizationdata._lineColor = lineColor;
-};
-
-IdentifiedElement.prototype.equals = function (argument) {
-  if (argument instanceof IdentifiedElement) {
-    return (this.getType() === argument.getType() && //
-      this.getId() === argument.getId() && //
-      this.getModelId() === argument.getModelId());
-  } else {
-    return false;
-  }
-};
-
-/**
- *
- * @returns {string}
- */
-IdentifiedElement.prototype.toString = function () {
-  var self = this;
-  return "[" + IdentifiedElement.prototype.constructor.name + "] " + self.getType() + " " + self.getId() + " (model: "
-    + self.getModelId() + ")";
-};
-
-module.exports = IdentifiedElement;
+"use strict";
+
+var Alias = require('./Alias');
+var LayoutAlias = require('./LayoutAlias');
+var Reaction = require('./Reaction');
+var LayoutReaction = require('./LayoutReaction');
+var PointData = require('./PointData');
+var Point = require('../canvas/Point');
+
+var logger = require('../../logger');
+
+/**
+ * @typedef {Object} IdentifiedElementInput
+ * @property {string|number} [id]
+ * @property {string|number} [objectId]
+ * @property {number} modelId
+ * @property {string} type
+ * @property {string} [icon]
+ */
+
+/**
+ * This is object representing element tha should be visualized on the map. It's
+ * very light and contains only the most important data. There are three types
+ * of objects to visualize:
+ * <ul>
+ * <li>"ALIAS" - for {@link Alias} objects</li>
+ * <li>"REACTION" - for {@link Reaction} objects</li>
+ * <li>"POINT" - for any point on the map, the data connected to this kind of
+ * objects are stored in {@link PointData}</li>
+ * </ul>
+ *
+ * @param {BioEntity|LayoutAlias|LayoutReaction|PointData|IdentifiedElementInput} object
+ * @constructor
+ */
+function IdentifiedElement(object) {
+  this._visualizationdata = {};
+  if (object instanceof Alias) {
+    this.setId(object.getId());
+    this.setModelId(object.getModelId());
+    this.setType("ALIAS");
+  } else if (object instanceof LayoutAlias) {
+    this.setId(object.getId());
+    this.setModelId(object.getModelId());
+    this.setType("ALIAS");
+  } else if (object instanceof Reaction) {
+    this.setId(object.getId());
+    this.setModelId(object.getModelId());
+    this.setType("REACTION");
+  } else if (object instanceof LayoutReaction) {
+    this.setId(object.getId());
+    this.setModelId(object.getModelId());
+    this.setType("REACTION");
+  } else if (object instanceof PointData) {
+    this.setId(object.getId());
+    this.setModelId(object.getModelId());
+    this.setType("POINT");
+  } else {
+    // identifier of the object to visualize
+    if (object.objectId === undefined) {
+      this.setId(object.id);
+    } else {
+      this.setId(object.objectId);
+    }
+    // which marker should be used to show this object
+    this.setIcon(object.icon);
+    // on which model the element is located
+    this.setModelId(object.modelId);
+    // what kind of object we are talking about
+    this.setType(object.type);
+  }
+
+  if (this.getType() === "POINT") {
+    var tmp = this.getId();
+    if (tmp.indexOf("Point2D.Double") >= 0) {
+      tmp = tmp.replace("Point2D.Double", "");
+      tmp = JSON.parse(tmp);
+    } else {
+      tmp = tmp.replace("(", "");
+      tmp = tmp.replace(")", "");
+      tmp = tmp.split(",");
+    }
+    var x = parseFloat(tmp[0]).toFixed(2);
+    var y = parseFloat(tmp[1]).toFixed(2);
+    this._point = new Point(x, y);
+    this.setId("(" + x + "," + y + ")");
+  } else if (this.getType() !== "ALIAS" && this.getType() !== "REACTION") {
+    throw new Error("Unknown type of identified element: " + this.getType());
+  }
+
+  if (this.getId() === undefined) {
+    throw new Error("Id not defined for element: " + object);
+  }
+}
+
+/**
+ * Returns point where it should be visualized when the type of object is
+ * "POINT".
+ *
+ * @returns {Point|null} where it should be visualized when the
+ *          type of object is "POINT".
+ */
+IdentifiedElement.prototype.getPoint = function () {
+  if (this._point === undefined || this._point === null) {
+    logger.warn("No point associated with IdentifiedElement");
+    return null;
+  } else {
+    return this._point;
+  }
+};
+
+/**
+ * Returns element identifier.
+ *
+ * @returns {string|number} element identifier
+ */
+IdentifiedElement.prototype.getId = function () {
+  return this.id;
+};
+
+IdentifiedElement.prototype.setId = function (id) {
+  // some elements are identified by id that is not a number (like point on the
+  // map)
+  if (!isNaN(id)) {
+    id = parseInt(id);
+  }
+  this.id = id;
+};
+
+/**
+ *
+ * @param {number|string} modelId
+ */
+IdentifiedElement.prototype.setModelId = function (modelId) {
+  if (modelId === undefined || modelId === null) {
+    throw new Error("ModelId is invalid");
+  }
+  this.modelId = parseInt(modelId);
+};
+
+/**
+ * Returns model identifier where element is placed.
+ *
+ * @returns {number} model identifier
+ */
+IdentifiedElement.prototype.getModelId = function () {
+  return this.modelId;
+};
+
+/**
+ * Returns type of the element. For now only three types are allowed:
+ * <ul>
+ * <li>"ALIAS" - for {@link Alias} objects</li>
+ * <li>"REACTION" - for {@link Reaction} objects</li>
+ * <li>"POINT" - for any point on the map, the data connected to this kind of
+ * objects are stored in {@link PointData}</li>
+ * </ul>
+ *
+ * @returns {string} type of the element
+ */
+IdentifiedElement.prototype.getType = function () {
+  return this.type;
+};
+
+IdentifiedElement.prototype.setType = function (type) {
+  if (type === undefined || type === null) {
+    throw new Error("Type not defined");
+  }
+
+  this.type = type.toUpperCase();
+};
+
+/**
+ * Returns icon that should be used for visualization.
+ *
+ * @returns {string|undefined} icon that should be used for visualization
+ */
+IdentifiedElement.prototype.getIcon = function () {
+  return this._visualizationdata._icon;
+};
+
+/**
+ *
+ * @param {string} icon
+ */
+IdentifiedElement.prototype.setIcon = function (icon) {
+  this._visualizationdata._icon = icon;
+};
+
+/**
+ * @returns {string|undefined}
+ */
+IdentifiedElement.prototype.getColor = function () {
+  return this._visualizationdata._color;
+};
+
+IdentifiedElement.prototype.setColor = function (color) {
+  this._visualizationdata._color = color;
+};
+
+IdentifiedElement.prototype.getOpacity = function () {
+  return this._visualizationdata._opacity;
+};
+
+IdentifiedElement.prototype.setOpacity = function (opacity) {
+  this._visualizationdata._opacity = opacity;
+};
+
+IdentifiedElement.prototype.getLineWeight = function () {
+  return this._visualizationdata._lineWeight;
+};
+
+IdentifiedElement.prototype.setLineWeight = function (lineWeight) {
+  this._visualizationdata._lineWeight = lineWeight;
+};
+IdentifiedElement.prototype.getLineOpacity = function () {
+  return this._visualizationdata._lineOpacity;
+};
+
+IdentifiedElement.prototype.setLineOpacity = function (lineOpacity) {
+  this._visualizationdata._lineOpacity = lineOpacity;
+};
+IdentifiedElement.prototype.getLineColor = function () {
+  return this._visualizationdata._lineColor;
+};
+
+IdentifiedElement.prototype.setLineColor = function (lineColor) {
+  this._visualizationdata._lineColor = lineColor;
+};
+
+IdentifiedElement.prototype.equals = function (argument) {
+  if (argument instanceof IdentifiedElement) {
+    return (this.getType() === argument.getType() && //
+      this.getId() === argument.getId() && //
+      this.getModelId() === argument.getModelId());
+  } else {
+    return false;
+  }
+};
+
+/**
+ *
+ * @returns {string}
+ */
+IdentifiedElement.prototype.toString = function () {
+  var self = this;
+  return "[" + IdentifiedElement.prototype.constructor.name + "] " + self.getType() + " " + self.getId() + " (model: "
+    + self.getModelId() + ")";
+};
+
+module.exports = IdentifiedElement;
diff --git a/frontend-js/src/main/js/map/data/KineticLaw.js b/frontend-js/src/main/js/map/data/KineticLaw.js
index fb4ecc6deb8ed953caa823fada83fb9864b18e73..0fd2129d88a49b3ad49e28b4152573663580ec46 100644
--- a/frontend-js/src/main/js/map/data/KineticLaw.js
+++ b/frontend-js/src/main/js/map/data/KineticLaw.js
@@ -1,39 +1,39 @@
-"use strict";
-
-function KineticLaw(jsonObject) {
-  var self = this;
-  self.setParameterIds(jsonObject.parameterIds);
-  self.setFunctionIds(jsonObject.functionIds);
-  self.setDefinition(jsonObject.definition);
-  self.setMathMlPresentation(jsonObject.mathMlPresentation);
-}
-
-KineticLaw.prototype.setParameterIds = function (parameterIds) {
-  this._parameterIds = parameterIds;
-};
-KineticLaw.prototype.getParameterIds = function () {
-  return this._parameterIds;
-};
-
-KineticLaw.prototype.setFunctionIds = function (functionIds) {
-  this._functionIds = functionIds;
-};
-KineticLaw.prototype.getFunctionIds = function () {
-  return this._functionIds;
-};
-
-KineticLaw.prototype.setDefinition = function (definition) {
-  this._definition = definition;
-};
-KineticLaw.prototype.getDefinition = function () {
-  return this._definition;
-};
-
-KineticLaw.prototype.setMathMlPresentation = function (mathMlPresentation) {
-  this._mathMlPresentation = mathMlPresentation;
-};
-KineticLaw.prototype.getMathMlPresentation = function () {
-  return this._mathMlPresentation;
-};
-
-module.exports = KineticLaw;
+"use strict";
+
+function KineticLaw(jsonObject) {
+  var self = this;
+  self.setParameterIds(jsonObject.parameterIds);
+  self.setFunctionIds(jsonObject.functionIds);
+  self.setDefinition(jsonObject.definition);
+  self.setMathMlPresentation(jsonObject.mathMlPresentation);
+}
+
+KineticLaw.prototype.setParameterIds = function (parameterIds) {
+  this._parameterIds = parameterIds;
+};
+KineticLaw.prototype.getParameterIds = function () {
+  return this._parameterIds;
+};
+
+KineticLaw.prototype.setFunctionIds = function (functionIds) {
+  this._functionIds = functionIds;
+};
+KineticLaw.prototype.getFunctionIds = function () {
+  return this._functionIds;
+};
+
+KineticLaw.prototype.setDefinition = function (definition) {
+  this._definition = definition;
+};
+KineticLaw.prototype.getDefinition = function () {
+  return this._definition;
+};
+
+KineticLaw.prototype.setMathMlPresentation = function (mathMlPresentation) {
+  this._mathMlPresentation = mathMlPresentation;
+};
+KineticLaw.prototype.getMathMlPresentation = function () {
+  return this._mathMlPresentation;
+};
+
+module.exports = KineticLaw;
diff --git a/frontend-js/src/main/js/map/data/LayoutReaction.js b/frontend-js/src/main/js/map/data/LayoutReaction.js
index 4026262f1371b037036a02890a46d9f2e4d55802..4c880969b5597d31acbc5b8093ecc1aae54e3989 100644
--- a/frontend-js/src/main/js/map/data/LayoutReaction.js
+++ b/frontend-js/src/main/js/map/data/LayoutReaction.js
@@ -1,55 +1,55 @@
-"use strict";
-
-/**
- * Class representing reaction visualized in a overlay.
- * 
- * @param javaObject
- *          object de-serialized from ajax query to the server side
- */
-function LayoutReaction(javaObject) {
-  this.setId(javaObject.idObject);
-  this.setModelId(javaObject.modelId);
-  this.setWidth(javaObject.width);
-  this.setColor(javaObject.color);
-  this.setReverse(javaObject.reverse);
-}
-
-LayoutReaction.prototype.getId = function() {
-  return this.id;
-};
-
-LayoutReaction.prototype.setId = function(id) {
-  this.id = parseInt(id);
-};
-
-LayoutReaction.prototype.getModelId = function() {
-  return this._modelId;
-};
-
-LayoutReaction.prototype.setModelId = function(modelId) {
-  this._modelId = parseInt(modelId);
-};
-
-LayoutReaction.prototype.setWidth = function(width) {
-  this.width = width;
-};
-
-LayoutReaction.prototype.setColor = function(color) {
-  this.color = color;
-};
-
-LayoutReaction.prototype.setReverse= function(reverse) {
-  this.reverse = reverse;
-};
-
-LayoutReaction.prototype.getWidth = function() {
-  return this.width;
-};
-LayoutReaction.prototype.getColor = function() {
-  return this.color;
-};
-LayoutReaction.prototype.getReverse = function() {
-  return this.reverse;
-};
-
-module.exports = LayoutReaction;
+"use strict";
+
+/**
+ * Class representing reaction visualized in a overlay.
+ * 
+ * @param javaObject
+ *          object de-serialized from ajax query to the server side
+ */
+function LayoutReaction(javaObject) {
+  this.setId(javaObject.idObject);
+  this.setModelId(javaObject.modelId);
+  this.setWidth(javaObject.width);
+  this.setColor(javaObject.color);
+  this.setReverse(javaObject.reverse);
+}
+
+LayoutReaction.prototype.getId = function() {
+  return this.id;
+};
+
+LayoutReaction.prototype.setId = function(id) {
+  this.id = parseInt(id);
+};
+
+LayoutReaction.prototype.getModelId = function() {
+  return this._modelId;
+};
+
+LayoutReaction.prototype.setModelId = function(modelId) {
+  this._modelId = parseInt(modelId);
+};
+
+LayoutReaction.prototype.setWidth = function(width) {
+  this.width = width;
+};
+
+LayoutReaction.prototype.setColor = function(color) {
+  this.color = color;
+};
+
+LayoutReaction.prototype.setReverse= function(reverse) {
+  this.reverse = reverse;
+};
+
+LayoutReaction.prototype.getWidth = function() {
+  return this.width;
+};
+LayoutReaction.prototype.getColor = function() {
+  return this.color;
+};
+LayoutReaction.prototype.getReverse = function() {
+  return this.reverse;
+};
+
+module.exports = LayoutReaction;
diff --git a/frontend-js/src/main/js/map/data/Mesh.js b/frontend-js/src/main/js/map/data/Mesh.js
index 500ef3a9a107101e11642b1478ca03731a5652a7..433f5ca9924e89bd38fd7ac5486e332a8b5e4bac 100644
--- a/frontend-js/src/main/js/map/data/Mesh.js
+++ b/frontend-js/src/main/js/map/data/Mesh.js
@@ -1,36 +1,36 @@
-"use strict";
-
-function Mesh(jsonObject) {
-  var self = this;
-  self.setSynonyms(jsonObject.synonyms);
-  self.setName(jsonObject.name);
-  self.setId(jsonObject.id);
-  self.setDescription(jsonObject.description);
-}
-
-Mesh.prototype.setSynonyms = function (synonyms) {
-  this._synonyms = synonyms;
-};
-Mesh.prototype.getSynonyms = function () {
-  return this._synonyms;
-};
-Mesh.prototype.setName = function (name) {
-  this._name = name;
-};
-Mesh.prototype.getName = function () {
-  return this._name;
-};
-Mesh.prototype.setId = function (id) {
-  this._id = id;
-};
-Mesh.prototype.getId = function () {
-  return this._id;
-};
-Mesh.prototype.setDescription = function (description) {
-  this._description = description;
-};
-Mesh.prototype.getDescription = function () {
-  return this._description;
-};
-
-module.exports = Mesh;
+"use strict";
+
+function Mesh(jsonObject) {
+  var self = this;
+  self.setSynonyms(jsonObject.synonyms);
+  self.setName(jsonObject.name);
+  self.setId(jsonObject.id);
+  self.setDescription(jsonObject.description);
+}
+
+Mesh.prototype.setSynonyms = function (synonyms) {
+  this._synonyms = synonyms;
+};
+Mesh.prototype.getSynonyms = function () {
+  return this._synonyms;
+};
+Mesh.prototype.setName = function (name) {
+  this._name = name;
+};
+Mesh.prototype.getName = function () {
+  return this._name;
+};
+Mesh.prototype.setId = function (id) {
+  this._id = id;
+};
+Mesh.prototype.getId = function () {
+  return this._id;
+};
+Mesh.prototype.setDescription = function (description) {
+  this._description = description;
+};
+Mesh.prototype.getDescription = function () {
+  return this._description;
+};
+
+module.exports = Mesh;
diff --git a/frontend-js/src/main/js/map/data/MiRna.js b/frontend-js/src/main/js/map/data/MiRna.js
index ddc024e2d8bedef67c13a02a9f9f2ac3be488985..a5b79965334b131f4d55b41a2a6fe2757fb7a835 100644
--- a/frontend-js/src/main/js/map/data/MiRna.js
+++ b/frontend-js/src/main/js/map/data/MiRna.js
@@ -1,12 +1,12 @@
-"use strict";
-
-var TargettingStructure = require("./TargettingStructure");
-
-function MiRna(javaObject) {
-  TargettingStructure.call(this, javaObject);
-}
-
-MiRna.prototype = Object.create(TargettingStructure.prototype);
-MiRna.prototype.constructor = MiRna;
-
-module.exports = MiRna;
+"use strict";
+
+var TargettingStructure = require("./TargettingStructure");
+
+function MiRna(javaObject) {
+  TargettingStructure.call(this, javaObject);
+}
+
+MiRna.prototype = Object.create(TargettingStructure.prototype);
+MiRna.prototype.constructor = MiRna;
+
+module.exports = MiRna;
diff --git a/frontend-js/src/main/js/map/data/MiriamType.js b/frontend-js/src/main/js/map/data/MiriamType.js
index 57b7387244aaadd90aeef121fad18de1f763dd96..80772a63e06c33e7501686360b99ace8785d5cd5 100644
--- a/frontend-js/src/main/js/map/data/MiriamType.js
+++ b/frontend-js/src/main/js/map/data/MiriamType.js
@@ -1,60 +1,60 @@
-"use strict";
-
-var ObjectWithListeners = require('../../ObjectWithListeners');
-
-function MiriamType(data, name) {
-  // call super constructor
-  ObjectWithListeners.call(this);
-
-  var self = this;
-  self.setUris(data.uris);
-  self.setHomepage(data.homepage);
-  self.setName(name);
-  self.setCommonName(data.commonName);
-  self.setRegistryIdentifier(data.registryIdentifier);
-}
-
-MiriamType.prototype = Object.create(ObjectWithListeners.prototype);
-MiriamType.prototype.constructor = MiriamType;
-
-MiriamType.prototype.setUris = function(uris) {
-  this._uris = uris;
-};
-
-MiriamType.prototype.getUris = function() {
-  return this._uris;
-};
-
-MiriamType.prototype.setHomepage = function(homepage) {
-  this._homepage = homepage;
-};
-
-MiriamType.prototype.getHomepage = function() {
-  return this._homepage;
-};
-
-MiriamType.prototype.setName = function(name) {
-  this._name = name;
-};
-
-MiriamType.prototype.getName = function() {
-  return this._name;
-};
-
-MiriamType.prototype.setCommonName = function(commonName) {
-  this._commonName = commonName;
-};
-
-MiriamType.prototype.getCommonName = function() {
-  return this._commonName;
-};
-
-MiriamType.prototype.setRegistryIdentifier = function(registryIdentifier) {
-  this._registryIdentifier = registryIdentifier;
-};
-
-MiriamType.prototype.getRegistryIdentifier = function() {
-  return this._registryIdentifier;
-};
-
-module.exports = MiriamType;
+"use strict";
+
+var ObjectWithListeners = require('../../ObjectWithListeners');
+
+function MiriamType(data, name) {
+  // call super constructor
+  ObjectWithListeners.call(this);
+
+  var self = this;
+  self.setUris(data.uris);
+  self.setHomepage(data.homepage);
+  self.setName(name);
+  self.setCommonName(data.commonName);
+  self.setRegistryIdentifier(data.registryIdentifier);
+}
+
+MiriamType.prototype = Object.create(ObjectWithListeners.prototype);
+MiriamType.prototype.constructor = MiriamType;
+
+MiriamType.prototype.setUris = function(uris) {
+  this._uris = uris;
+};
+
+MiriamType.prototype.getUris = function() {
+  return this._uris;
+};
+
+MiriamType.prototype.setHomepage = function(homepage) {
+  this._homepage = homepage;
+};
+
+MiriamType.prototype.getHomepage = function() {
+  return this._homepage;
+};
+
+MiriamType.prototype.setName = function(name) {
+  this._name = name;
+};
+
+MiriamType.prototype.getName = function() {
+  return this._name;
+};
+
+MiriamType.prototype.setCommonName = function(commonName) {
+  this._commonName = commonName;
+};
+
+MiriamType.prototype.getCommonName = function() {
+  return this._commonName;
+};
+
+MiriamType.prototype.setRegistryIdentifier = function(registryIdentifier) {
+  this._registryIdentifier = registryIdentifier;
+};
+
+MiriamType.prototype.getRegistryIdentifier = function() {
+  return this._registryIdentifier;
+};
+
+module.exports = MiriamType;
diff --git a/frontend-js/src/main/js/map/data/ModificationStateType.js b/frontend-js/src/main/js/map/data/ModificationStateType.js
index 7f5612b996c30cd90adb6b1b5faed6a7f47631cc..3343d4de4264502072158c61ccda92fb6d2d293a 100644
--- a/frontend-js/src/main/js/map/data/ModificationStateType.js
+++ b/frontend-js/src/main/js/map/data/ModificationStateType.js
@@ -1,42 +1,42 @@
-"use strict";
-
-var ObjectWithListeners = require('../../ObjectWithListeners');
-
-function ModificationStateType(data, name) {
-  // call super constructor
-  ObjectWithListeners.call(this);
-
-  var self = this;
-  self.setAbbreviation(data.abbreviation);
-  self.setName(name);
-  self.setCommonName(data.commonName);
-}
-
-ModificationStateType.prototype = Object.create(ObjectWithListeners.prototype);
-ModificationStateType.prototype.constructor = ModificationStateType;
-
-ModificationStateType.prototype.setName = function(name) {
-  this._name = name;
-};
-
-ModificationStateType.prototype.getName = function() {
-  return this._name;
-};
-
-ModificationStateType.prototype.setAbbreviation= function(abbreviation) {
-  this._abbreviation = abbreviation;
-};
-
-ModificationStateType.prototype.getAbbreviation = function() {
-  return this._abbreviation;
-};
-
-ModificationStateType.prototype.setCommonName = function(commonName) {
-  this._commonName = commonName;
-};
-
-ModificationStateType.prototype.getCommonName = function() {
-  return this._commonName;
-};
-
-module.exports = ModificationStateType;
+"use strict";
+
+var ObjectWithListeners = require('../../ObjectWithListeners');
+
+function ModificationStateType(data, name) {
+  // call super constructor
+  ObjectWithListeners.call(this);
+
+  var self = this;
+  self.setAbbreviation(data.abbreviation);
+  self.setName(name);
+  self.setCommonName(data.commonName);
+}
+
+ModificationStateType.prototype = Object.create(ObjectWithListeners.prototype);
+ModificationStateType.prototype.constructor = ModificationStateType;
+
+ModificationStateType.prototype.setName = function(name) {
+  this._name = name;
+};
+
+ModificationStateType.prototype.getName = function() {
+  return this._name;
+};
+
+ModificationStateType.prototype.setAbbreviation= function(abbreviation) {
+  this._abbreviation = abbreviation;
+};
+
+ModificationStateType.prototype.getAbbreviation = function() {
+  return this._abbreviation;
+};
+
+ModificationStateType.prototype.setCommonName = function(commonName) {
+  this._commonName = commonName;
+};
+
+ModificationStateType.prototype.getCommonName = function() {
+  return this._commonName;
+};
+
+module.exports = ModificationStateType;
diff --git a/frontend-js/src/main/js/map/data/Modifier.js b/frontend-js/src/main/js/map/data/Modifier.js
index 9d488e0ee94e30955d8b4ba947f4bfa5800518b6..ea94bdd8b443c683131f82b324c250be34392cf0 100644
--- a/frontend-js/src/main/js/map/data/Modifier.js
+++ b/frontend-js/src/main/js/map/data/Modifier.js
@@ -1,22 +1,22 @@
-"use strict";
-
-
-function Modifier(javaObject) {
-  this.setAlias(javaObject.aliasId);
-  this.setStoichiometry(javaObject.stoichiometry);
-}
-
-Modifier.prototype.getAlias = function () {
-  return this._alias;
-};
-Modifier.prototype.setAlias = function (alias) {
-  this._alias = alias;
-};
-Modifier.prototype.getStoichiometry = function () {
-  return this._stoichiometry;
-};
-Modifier.prototype.setStoichiometry = function (stoichiometry) {
-  this._stoichiometry = stoichiometry;
-};
-
-module.exports = Modifier;
+"use strict";
+
+
+function Modifier(javaObject) {
+  this.setAlias(javaObject.aliasId);
+  this.setStoichiometry(javaObject.stoichiometry);
+}
+
+Modifier.prototype.getAlias = function () {
+  return this._alias;
+};
+Modifier.prototype.setAlias = function (alias) {
+  this._alias = alias;
+};
+Modifier.prototype.getStoichiometry = function () {
+  return this._stoichiometry;
+};
+Modifier.prototype.setStoichiometry = function (stoichiometry) {
+  this._stoichiometry = stoichiometry;
+};
+
+module.exports = Modifier;
diff --git a/frontend-js/src/main/js/map/data/PointData.js b/frontend-js/src/main/js/map/data/PointData.js
index c97186d002ff55a144528fc60bd471d11ded4e96..0d23a5dd3ca2493d15e120ca7691d9515a6ae6f3 100644
--- a/frontend-js/src/main/js/map/data/PointData.js
+++ b/frontend-js/src/main/js/map/data/PointData.js
@@ -1,56 +1,56 @@
-"use strict";
-
-var Point = require('../canvas/Point');
-
-/**
- * Object representing information for specific point on the map.
- */
-function PointData(javaObject, modelId) {
-  if (javaObject instanceof Point) {
-    this._point = javaObject;
-    this._modelId = modelId;
-  } else if (javaObject.constructor.name === "IdentifiedElement") {
-    this._point = javaObject.getPoint();
-    this._modelId = javaObject.getModelId();
-  } else {
-    var tmp = javaObject.idObject.replace("Point2D.Double", "");
-    tmp = JSON.parse(tmp);
-    var x = parseFloat(tmp[0]).toFixed(2);
-    var y = parseFloat(tmp[1]).toFixed(2);
-    this._point = new Point(x, y);
-    this._modelId = modelId;
-  }
-  this._id = "(" + parseFloat(this._point.x).toFixed(2) + "," + parseFloat(this._point.y).toFixed(2) + ")";
-}
-
-/**
- * Returns identifier of the object.
- * 
- * @returns {string} that is identifier of the object
- */
-PointData.prototype.getId = function() {
-  return this._id;
-};
-
-/**
- * Returns point to which this object corresponds.
- * 
- * @returns {Point} to which this object corresponds
- */
-PointData.prototype.getPoint = function() {
-  return this._point;
-};
-
-/**
- *
- * @returns {number}
- */
-PointData.prototype.getModelId = function() {
-  return this._modelId;
-};
-
-PointData.prototype.isComplete = function() {
-  return true;
-};
-
-module.exports = PointData;
+"use strict";
+
+var Point = require('../canvas/Point');
+
+/**
+ * Object representing information for specific point on the map.
+ */
+function PointData(javaObject, modelId) {
+  if (javaObject instanceof Point) {
+    this._point = javaObject;
+    this._modelId = modelId;
+  } else if (javaObject.constructor.name === "IdentifiedElement") {
+    this._point = javaObject.getPoint();
+    this._modelId = javaObject.getModelId();
+  } else {
+    var tmp = javaObject.idObject.replace("Point2D.Double", "");
+    tmp = JSON.parse(tmp);
+    var x = parseFloat(tmp[0]).toFixed(2);
+    var y = parseFloat(tmp[1]).toFixed(2);
+    this._point = new Point(x, y);
+    this._modelId = modelId;
+  }
+  this._id = "(" + parseFloat(this._point.x).toFixed(2) + "," + parseFloat(this._point.y).toFixed(2) + ")";
+}
+
+/**
+ * Returns identifier of the object.
+ * 
+ * @returns {string} that is identifier of the object
+ */
+PointData.prototype.getId = function() {
+  return this._id;
+};
+
+/**
+ * Returns point to which this object corresponds.
+ * 
+ * @returns {Point} to which this object corresponds
+ */
+PointData.prototype.getPoint = function() {
+  return this._point;
+};
+
+/**
+ *
+ * @returns {number}
+ */
+PointData.prototype.getModelId = function() {
+  return this._modelId;
+};
+
+PointData.prototype.isComplete = function() {
+  return true;
+};
+
+module.exports = PointData;
diff --git a/frontend-js/src/main/js/map/data/PrivilegeType.js b/frontend-js/src/main/js/map/data/PrivilegeType.js
index 45af426283985ab02e2165bc19cd799600a71254..be25207f9d7654aea14014486271468d3736bce7 100644
--- a/frontend-js/src/main/js/map/data/PrivilegeType.js
+++ b/frontend-js/src/main/js/map/data/PrivilegeType.js
@@ -1,54 +1,54 @@
-"use strict";
-
-var ObjectWithListeners = require('../../ObjectWithListeners');
-
-function PrivilegeType(data, name) {
-  // call super constructor
-  ObjectWithListeners.call(this);
-
-  var self = this;
-  self.setName(name);
-  self.setCommonName(data.commonName);
-  self.setObjectType(data.objectType);
-  self.setValueType(data.valueType);
-}
-
-PrivilegeType.prototype = Object.create(ObjectWithListeners.prototype);
-PrivilegeType.prototype.constructor = PrivilegeType;
-
-PrivilegeType.CONFIGURATION_MANAGE = 'CONFIGURATION_MANAGE';
-PrivilegeType.MANAGE_GENOMES = 'MANAGE_GENOMES';
-PrivilegeType.PROJECT_MANAGEMENT = 'PROJECT_MANAGEMENT';
-PrivilegeType.USER_MANAGEMENT = 'USER_MANAGEMENT';
-
-PrivilegeType.prototype.setObjectType = function (objectType) {
-  this._objectType = objectType;
-};
-
-PrivilegeType.prototype.getObjectType = function () {
-  return this._objectType;
-};
-PrivilegeType.prototype.setValueType = function (valueType) {
-  this._valueType = valueType;
-};
-
-PrivilegeType.prototype.getValueType = function () {
-  return this._valueType;
-};
-PrivilegeType.prototype.setCommonName = function (commonName) {
-  this._commonName = commonName;
-};
-
-PrivilegeType.prototype.getCommonName = function () {
-  return this._commonName;
-};
-
-PrivilegeType.prototype.setName = function (name) {
-  this._name = name;
-};
-
-PrivilegeType.prototype.getName = function () {
-  return this._name;
-};
-
-module.exports = PrivilegeType;
+"use strict";
+
+var ObjectWithListeners = require('../../ObjectWithListeners');
+
+function PrivilegeType(data, name) {
+  // call super constructor
+  ObjectWithListeners.call(this);
+
+  var self = this;
+  self.setName(name);
+  self.setCommonName(data.commonName);
+  self.setObjectType(data.objectType);
+  self.setValueType(data.valueType);
+}
+
+PrivilegeType.prototype = Object.create(ObjectWithListeners.prototype);
+PrivilegeType.prototype.constructor = PrivilegeType;
+
+PrivilegeType.CONFIGURATION_MANAGE = 'CONFIGURATION_MANAGE';
+PrivilegeType.MANAGE_GENOMES = 'MANAGE_GENOMES';
+PrivilegeType.PROJECT_MANAGEMENT = 'PROJECT_MANAGEMENT';
+PrivilegeType.USER_MANAGEMENT = 'USER_MANAGEMENT';
+
+PrivilegeType.prototype.setObjectType = function (objectType) {
+  this._objectType = objectType;
+};
+
+PrivilegeType.prototype.getObjectType = function () {
+  return this._objectType;
+};
+PrivilegeType.prototype.setValueType = function (valueType) {
+  this._valueType = valueType;
+};
+
+PrivilegeType.prototype.getValueType = function () {
+  return this._valueType;
+};
+PrivilegeType.prototype.setCommonName = function (commonName) {
+  this._commonName = commonName;
+};
+
+PrivilegeType.prototype.getCommonName = function () {
+  return this._commonName;
+};
+
+PrivilegeType.prototype.setName = function (name) {
+  this._name = name;
+};
+
+PrivilegeType.prototype.getName = function () {
+  return this._name;
+};
+
+module.exports = PrivilegeType;
diff --git a/frontend-js/src/main/js/map/data/Product.js b/frontend-js/src/main/js/map/data/Product.js
index ba1f61311296f2db7a700911d8c0cc8e247fbff2..d14459e57650a493485678fbc7efc59af204769d 100644
--- a/frontend-js/src/main/js/map/data/Product.js
+++ b/frontend-js/src/main/js/map/data/Product.js
@@ -1,23 +1,23 @@
-"use strict";
-
-
-function Product(javaObject) {
-  this.setAlias(javaObject.aliasId);
-  this.setStoichiometry(javaObject.stoichiometry);
-}
-
-Product.prototype.getAlias = function () {
-  return this._alias;
-};
-Product.prototype.setAlias = function (alias) {
-  this._alias = alias;
-};
-Product.prototype.getStoichiometry = function () {
-  return this._stoichiometry;
-};
-Product.prototype.setStoichiometry = function (stoichiometry) {
-  this._stoichiometry = stoichiometry;
-};
-
-
-module.exports = Product;
+"use strict";
+
+
+function Product(javaObject) {
+  this.setAlias(javaObject.aliasId);
+  this.setStoichiometry(javaObject.stoichiometry);
+}
+
+Product.prototype.getAlias = function () {
+  return this._alias;
+};
+Product.prototype.setAlias = function (alias) {
+  this._alias = alias;
+};
+Product.prototype.getStoichiometry = function () {
+  return this._stoichiometry;
+};
+Product.prototype.setStoichiometry = function (stoichiometry) {
+  this._stoichiometry = stoichiometry;
+};
+
+
+module.exports = Product;
diff --git a/frontend-js/src/main/js/map/data/Project.js b/frontend-js/src/main/js/map/data/Project.js
index e5053fbc932bb3d7674196add1a69008caece753..0f9114d09d04f2e00b528e66fea312b03ea25473 100644
--- a/frontend-js/src/main/js/map/data/Project.js
+++ b/frontend-js/src/main/js/map/data/Project.js
@@ -1,526 +1,526 @@
-"use strict";
-
-/* exported logger */
-
-var ObjectWithListeners = require('../../ObjectWithListeners');
-
-var Annotation = require("./Annotation");
-var DataOverlay = require("./DataOverlay");
-var Model = require('./MapModel');
-
-var Promise = require('bluebird');
-
-// noinspection JSUnusedLocalSymbols
-var logger = require('../../logger');
-
-/**
- *
- * @param {Project|string|Object} [data]
- * @constructor
- */
-function Project(data) {
-  // call super constructor
-  ObjectWithListeners.call(this);
-  this.registerListenerType("onreload");
-
-  this._dataOverlays = [];
-  this._models = [];
-  this._elementsPointingToSubmap = [];
-
-  if (data !== undefined) {
-    this.loadFromData(data);
-  }
-}
-
-// this class inherits from ObjectWithListeners class where generic methods for
-// listeners are set
-Project.prototype = Object.create(ObjectWithListeners.prototype);
-Project.prototype.constructor = Project;
-
-/**
- *
- * @param {Project|string} data
- * @private
- */
-Project.prototype.loadFromData = function (data) {
-  var self = this;
-  if (typeof data === "string") {
-    // replace is due to some strange problem with serialization
-    data = JSON.parse(data.replace(/\n/g, " "));
-  }
-  if (data instanceof Project) {
-    self._update(data);
-  } else {
-    self.setId(parseInt(data.idObject));
-    self.setProjectId(data.projectId);
-    self.setDirectory(data.directory);
-    self.setVersion(data.version);
-    self.setName(data.name);
-    self.setOverviewImages(data.overviewImageViews);
-    self.setTopOverviewImage(data.topOverviewImage);
-    self.setDisease(data.disease);
-    self.setOrganism(data.organism);
-    self.setStatus(data.status);
-    self.setNotifyEmail(data.notifyEmail);
-    self.setProgress(data.progress);
-    self.setHasWarnings(data.warnings);
-    self.setHasErrors(data.errors);
-    self.setMapCanvasType(data.mapCanvasType);
-  }
-};
-
-/**
- *
- * @param {Project} data
- * @returns {PromiseLike}
- */
-Project.prototype.update = function (data) {
-  this._update(data);
-  return this.callListeners("onreload");
-};
-
-/**
- *
- * @param {Project} data
- * @private
- */
-Project.prototype._update = function (data) {
-  var self = this;
-  self.setId(data.getId());
-  self.setProjectId(data.getProjectId());
-  self.setDirectory(data.getDirectory());
-  self.setVersion(data.getVersion());
-  self.setName(data.getName());
-  self.setOverviewImages(data.getOverviewImages());
-  self.setTopOverviewImage(data.getTopOverviewImage());
-  self.setDisease(data.getDisease());
-  self.setOrganism(data.getOrganism());
-  self.setStatus(data.getStatus());
-  self.setProgress(data.getProgress());
-  self.setNotifyEmail(data.getNotifyEmail());
-  self.setHasWarnings(data.hasWarnings());
-  self.setHasErrors(data.hasErrors());
-  self.setMapCanvasType(data.getMapCanvasType());
-
-  if (data.getModels() !== undefined) {
-    var models = data.getModels();
-    for (var i = 0; i < models.length; i++) {
-      self.addModel(new Model(models[i]));
-    }
-  }
-};
-
-/**
- *
- * @returns {number}
- */
-Project.prototype.getId = function () {
-  return this._id;
-};
-
-/**
- *
- * @param {number|string} id
- */
-Project.prototype.setId = function (id) {
-  this._id = parseInt(id);
-};
-
-/**
- *
- * @returns {boolean}
- */
-Project.prototype.hasErrors = function () {
-  return this._hasErrors === true;
-};
-
-/**
- *
- * @param {boolean} hasErrors
- */
-Project.prototype.setHasErrors = function (hasErrors) {
-  this._hasErrors = hasErrors;
-};
-
-/**
- *
- * @returns {boolean}
- */
-Project.prototype.hasWarnings = function () {
-  return this._hasWarnings === true;
-};
-
-/**
- *
- * @param {boolean} hasWarnings
- */
-Project.prototype.setHasWarnings = function (hasWarnings) {
-  this._hasWarnings = hasWarnings;
-};
-
-/**
- *
- * @returns {string}
- */
-Project.prototype.getProjectId = function () {
-  return this._projectId;
-};
-
-/**
- *
- * @param {string} projectId
- */
-Project.prototype.setProjectId = function (projectId) {
-  this._projectId = projectId;
-};
-
-/**
- *
- * @returns {string}
- */
-Project.prototype.getDirectory = function () {
-  return this._directory;
-};
-
-/**
- *
- * @param {string} directory
- */
-Project.prototype.setDirectory = function (directory) {
-  this._directory = directory;
-};
-
-/**
- *
- * @returns {string}
- */
-Project.prototype.getVersion = function () {
-  return this._version;
-};
-
-/**
- *
- * @param {string} version
- */
-Project.prototype.setVersion = function (version) {
-  this._version = version;
-};
-
-/**
- *
- * @returns {string}
- */
-Project.prototype.getName = function () {
-  return this._name;
-};
-
-/**
- *
- * @param {string} name
- */
-Project.prototype.setName = function (name) {
-  this._name = name;
-};
-
-/**
- *
- * @returns {MapModel[]}
- */
-Project.prototype.getModels = function () {
-  return this._models;
-};
-
-/**
- *
- * @param modelId
- * @returns {MapModel|null}
- */
-Project.prototype.getModelById = function (modelId) {
-  for (var i = 0; i < this._models.length; i++) {
-    if (this._models[i].getId() === modelId) {
-      return this._models[i];
-    }
-  }
-  return null;
-};
-
-/**
- *
- * @param {MapModel[]} models
- */
-Project.prototype.setModels = function (models) {
-  this._models = models;
-};
-
-/**
- *
- * @param {MapModel} model
- */
-Project.prototype.addModel = function (model) {
-  this._models.push(model);
-};
-
-Project.prototype.getOverviewImages = function () {
-  return this._overviewImages;
-};
-Project.prototype.setOverviewImages = function (overviewImages) {
-  this._overviewImages = overviewImages;
-};
-
-Project.prototype.getTopOverviewImage = function () {
-  return this._topOverviewImage;
-};
-Project.prototype.setTopOverviewImage = function (topOverviewImage) {
-  this._topOverviewImage = topOverviewImage;
-};
-
-/**
- *
- * @returns {Annotation}
- */
-Project.prototype.getDisease = function () {
-  return this._disease;
-};
-
-/**
- *
- * @param {Object} disease
- */
-Project.prototype.setDisease = function (disease) {
-  if (disease !== undefined && disease !== null) {
-    this._disease = new Annotation(disease);
-  } else {
-    this._disease = undefined;
-  }
-};
-
-/**
- *
- * @returns {Annotation}
- */
-Project.prototype.getOrganism = function () {
-  return this._organism;
-};
-
-/**
- *
- * @param {Object} organism
- */
-Project.prototype.setOrganism = function (organism) {
-  if (organism !== undefined && organism !== null) {
-    this._organism = new Annotation(organism);
-  } else {
-    this._organism = undefined;
-  }
-};
-
-/**
- *
- * @returns {string}
- */
-Project.prototype.getMapCanvasType = function () {
-  return this._mapCanvasType;
-};
-
-/**
- *
- * @param {string} mapCanvasType
- */
-Project.prototype.setMapCanvasType = function (mapCanvasType) {
-  this._mapCanvasType = mapCanvasType;
-};
-
-/**
- *
- * @returns {string}
- */
-Project.prototype.getStatus = function () {
-  return this._status;
-};
-
-/**
- *
- * @param {string} status
- */
-Project.prototype.setStatus = function (status) {
-  this._status = status;
-};
-
-/**
- *
- * @returns {number}
- */
-Project.prototype.getProgress = function () {
-  return this._progress;
-};
-
-/**
- *
- * @param {number} progress
- */
-Project.prototype.setProgress = function (progress) {
-  this._progress = progress;
-};
-
-/**
- *
- * @returns {string}
- */
-Project.prototype.getNotifyEmail = function () {
-  return this._notifyEmail;
-};
-
-/**
- *
- * @param {string} notifyEmail
- */
-Project.prototype.setNotifyEmail = function (notifyEmail) {
-  this._notifyEmail = notifyEmail;
-};
-
-/**
- *
- * @param {DataOverlay} overlay
- * @param {boolean} [updateWhenExists=false]
- */
-Project.prototype.addDataOverlay = function (overlay, updateWhenExists) {
-  var overlayToAdd = null;
-  if (overlay instanceof DataOverlay) {
-    overlayToAdd = overlay;
-  } else {
-    overlayToAdd = new DataOverlay(overlay);
-  }
-  var object = this._dataOverlays[overlayToAdd.getId()];
-  if (object === undefined) {
-    this._dataOverlays[overlayToAdd.getId()] = overlayToAdd;
-  } else {
-    if (updateWhenExists) {
-      object.update(overlay);
-    } else {
-      throw new Error("Overlay " + overlayToAdd.getId() + " already exists in a project " + this.getProjectId());
-    }
-  }
-};
-
-/**
- *
- * @param {DataOverlay} overlay
- */
-Project.prototype.addOrUpdateDataOverlay = function (overlay) {
-  this.addDataOverlay(overlay, true);
-};
-
-
-/**
- *
- * @param {DataOverlay[]} overlay
- */
-Project.prototype.addOrUpdateDataOverlays = function (overlay) {
-  this.addDataOverlays(overlay, true);
-};
-
-/**
- *
- * @param {DataOverlay[]} overlays
- * @param {boolean} updateWhenExists
- */
-Project.prototype.addDataOverlays = function (overlays, updateWhenExists) {
-  if (overlays === undefined) {
-    logger.warn("Overlays are undefined...");
-  } else {
-    for (var i = 0; i < overlays.length; i++) {
-      this.addDataOverlay(overlays[i], updateWhenExists);
-    }
-  }
-};
-
-/**
- *
- * @returns {DataOverlay[]}
- */
-Project.prototype.getDataOverlays = function () {
-  var result = [];
-  for (var id in this._dataOverlays) {
-    if (this._dataOverlays.hasOwnProperty(id)) {
-      result.push(this._dataOverlays[id]);
-    }
-  }
-  result.sort(function (dataOverlay1, dataOverlay2) {
-    if (dataOverlay1.getOrder() < dataOverlay2.getOrder())
-      return -1;
-    if (dataOverlay1.getOrder() > dataOverlay2.getOrder())
-      return 1;
-    return 0;
-  });
-  return result;
-};
-
-
-/**
- * Returns data overlay for a given overlay identifier.
- *
- * @param {number} overlayId
- *          overlay identifier
- * @returns {PromiseLike<DataOverlay>} for a given overlay identifier
- */
-Project.prototype.getDataOverlayById = function (overlayId) {
-  var self = this;
-  if (self._dataOverlays[overlayId] !== undefined) {
-    return Promise.resolve(self._dataOverlays[overlayId]);
-  } else {
-    return ServerConnector.getOverlayById(overlayId).then(function (overlay) {
-      self.addDataOverlay(overlay, false);
-      return self._dataOverlays[overlayId];
-    });
-  }
-};
-
-/**
- * Returns promise with list of elements pointing to the submap.
- *
- * @param {number} modelId id of the submap
- * @returns {Promise} for a given overlay identifier
- */
-Project.prototype.getElementsPointingToSubmap = function (modelId) {
-  var self = this;
-  if (self._elementsPointingToSubmap[modelId] !== undefined) {
-    return Promise.resolve(self._elementsPointingToSubmap[modelId]);
-  }
-  var promise = Promise.resolve();
-  if (self._submapConnections === undefined) {
-    promise = ServerConnector.getSubmapConnections().then(function (data) {
-      self._submapConnections = data;
-    });
-  }
-  return promise.then(function () {
-    self._elementsPointingToSubmap[modelId] = [];
-
-    var queue = [modelId];
-
-    while (queue.length > 0) {
-      var id = queue.shift();
-      for (var i = 0; i < self._submapConnections.length; i++) {
-        var connection = self._submapConnections[i];
-        if (connection.to === id) {
-          var elementToAdd = connection.from;
-          var alreadyAdded = false;
-          for (var j = 0; j < self._elementsPointingToSubmap[modelId].length; j++) {
-            var elementAlreadyAdded = self._elementsPointingToSubmap[modelId][j];
-            if (elementToAdd.getId() === elementAlreadyAdded.getId()) {
-              alreadyAdded = true;
-            }
-          }
-          if (!alreadyAdded) {
-            self._elementsPointingToSubmap[modelId].push(elementToAdd);
-            queue.push(elementToAdd.getModelId());
-          }
-        }
-      }
-    }
-
-    return self._elementsPointingToSubmap[modelId];
-  });
-};
-
-
-module.exports = Project;
+"use strict";
+
+/* exported logger */
+
+var ObjectWithListeners = require('../../ObjectWithListeners');
+
+var Annotation = require("./Annotation");
+var DataOverlay = require("./DataOverlay");
+var Model = require('./MapModel');
+
+var Promise = require('bluebird');
+
+// noinspection JSUnusedLocalSymbols
+var logger = require('../../logger');
+
+/**
+ *
+ * @param {Project|string|Object} [data]
+ * @constructor
+ */
+function Project(data) {
+  // call super constructor
+  ObjectWithListeners.call(this);
+  this.registerListenerType("onreload");
+
+  this._dataOverlays = [];
+  this._models = [];
+  this._elementsPointingToSubmap = [];
+
+  if (data !== undefined) {
+    this.loadFromData(data);
+  }
+}
+
+// this class inherits from ObjectWithListeners class where generic methods for
+// listeners are set
+Project.prototype = Object.create(ObjectWithListeners.prototype);
+Project.prototype.constructor = Project;
+
+/**
+ *
+ * @param {Project|string} data
+ * @private
+ */
+Project.prototype.loadFromData = function (data) {
+  var self = this;
+  if (typeof data === "string") {
+    // replace is due to some strange problem with serialization
+    data = JSON.parse(data.replace(/\n/g, " "));
+  }
+  if (data instanceof Project) {
+    self._update(data);
+  } else {
+    self.setId(parseInt(data.idObject));
+    self.setProjectId(data.projectId);
+    self.setDirectory(data.directory);
+    self.setVersion(data.version);
+    self.setName(data.name);
+    self.setOverviewImages(data.overviewImageViews);
+    self.setTopOverviewImage(data.topOverviewImage);
+    self.setDisease(data.disease);
+    self.setOrganism(data.organism);
+    self.setStatus(data.status);
+    self.setNotifyEmail(data.notifyEmail);
+    self.setProgress(data.progress);
+    self.setHasWarnings(data.warnings);
+    self.setHasErrors(data.errors);
+    self.setMapCanvasType(data.mapCanvasType);
+  }
+};
+
+/**
+ *
+ * @param {Project} data
+ * @returns {PromiseLike}
+ */
+Project.prototype.update = function (data) {
+  this._update(data);
+  return this.callListeners("onreload");
+};
+
+/**
+ *
+ * @param {Project} data
+ * @private
+ */
+Project.prototype._update = function (data) {
+  var self = this;
+  self.setId(data.getId());
+  self.setProjectId(data.getProjectId());
+  self.setDirectory(data.getDirectory());
+  self.setVersion(data.getVersion());
+  self.setName(data.getName());
+  self.setOverviewImages(data.getOverviewImages());
+  self.setTopOverviewImage(data.getTopOverviewImage());
+  self.setDisease(data.getDisease());
+  self.setOrganism(data.getOrganism());
+  self.setStatus(data.getStatus());
+  self.setProgress(data.getProgress());
+  self.setNotifyEmail(data.getNotifyEmail());
+  self.setHasWarnings(data.hasWarnings());
+  self.setHasErrors(data.hasErrors());
+  self.setMapCanvasType(data.getMapCanvasType());
+
+  if (data.getModels() !== undefined) {
+    var models = data.getModels();
+    for (var i = 0; i < models.length; i++) {
+      self.addModel(new Model(models[i]));
+    }
+  }
+};
+
+/**
+ *
+ * @returns {number}
+ */
+Project.prototype.getId = function () {
+  return this._id;
+};
+
+/**
+ *
+ * @param {number|string} id
+ */
+Project.prototype.setId = function (id) {
+  this._id = parseInt(id);
+};
+
+/**
+ *
+ * @returns {boolean}
+ */
+Project.prototype.hasErrors = function () {
+  return this._hasErrors === true;
+};
+
+/**
+ *
+ * @param {boolean} hasErrors
+ */
+Project.prototype.setHasErrors = function (hasErrors) {
+  this._hasErrors = hasErrors;
+};
+
+/**
+ *
+ * @returns {boolean}
+ */
+Project.prototype.hasWarnings = function () {
+  return this._hasWarnings === true;
+};
+
+/**
+ *
+ * @param {boolean} hasWarnings
+ */
+Project.prototype.setHasWarnings = function (hasWarnings) {
+  this._hasWarnings = hasWarnings;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+Project.prototype.getProjectId = function () {
+  return this._projectId;
+};
+
+/**
+ *
+ * @param {string} projectId
+ */
+Project.prototype.setProjectId = function (projectId) {
+  this._projectId = projectId;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+Project.prototype.getDirectory = function () {
+  return this._directory;
+};
+
+/**
+ *
+ * @param {string} directory
+ */
+Project.prototype.setDirectory = function (directory) {
+  this._directory = directory;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+Project.prototype.getVersion = function () {
+  return this._version;
+};
+
+/**
+ *
+ * @param {string} version
+ */
+Project.prototype.setVersion = function (version) {
+  this._version = version;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+Project.prototype.getName = function () {
+  return this._name;
+};
+
+/**
+ *
+ * @param {string} name
+ */
+Project.prototype.setName = function (name) {
+  this._name = name;
+};
+
+/**
+ *
+ * @returns {MapModel[]}
+ */
+Project.prototype.getModels = function () {
+  return this._models;
+};
+
+/**
+ *
+ * @param modelId
+ * @returns {MapModel|null}
+ */
+Project.prototype.getModelById = function (modelId) {
+  for (var i = 0; i < this._models.length; i++) {
+    if (this._models[i].getId() === modelId) {
+      return this._models[i];
+    }
+  }
+  return null;
+};
+
+/**
+ *
+ * @param {MapModel[]} models
+ */
+Project.prototype.setModels = function (models) {
+  this._models = models;
+};
+
+/**
+ *
+ * @param {MapModel} model
+ */
+Project.prototype.addModel = function (model) {
+  this._models.push(model);
+};
+
+Project.prototype.getOverviewImages = function () {
+  return this._overviewImages;
+};
+Project.prototype.setOverviewImages = function (overviewImages) {
+  this._overviewImages = overviewImages;
+};
+
+Project.prototype.getTopOverviewImage = function () {
+  return this._topOverviewImage;
+};
+Project.prototype.setTopOverviewImage = function (topOverviewImage) {
+  this._topOverviewImage = topOverviewImage;
+};
+
+/**
+ *
+ * @returns {Annotation}
+ */
+Project.prototype.getDisease = function () {
+  return this._disease;
+};
+
+/**
+ *
+ * @param {Object} disease
+ */
+Project.prototype.setDisease = function (disease) {
+  if (disease !== undefined && disease !== null) {
+    this._disease = new Annotation(disease);
+  } else {
+    this._disease = undefined;
+  }
+};
+
+/**
+ *
+ * @returns {Annotation}
+ */
+Project.prototype.getOrganism = function () {
+  return this._organism;
+};
+
+/**
+ *
+ * @param {Object} organism
+ */
+Project.prototype.setOrganism = function (organism) {
+  if (organism !== undefined && organism !== null) {
+    this._organism = new Annotation(organism);
+  } else {
+    this._organism = undefined;
+  }
+};
+
+/**
+ *
+ * @returns {string}
+ */
+Project.prototype.getMapCanvasType = function () {
+  return this._mapCanvasType;
+};
+
+/**
+ *
+ * @param {string} mapCanvasType
+ */
+Project.prototype.setMapCanvasType = function (mapCanvasType) {
+  this._mapCanvasType = mapCanvasType;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+Project.prototype.getStatus = function () {
+  return this._status;
+};
+
+/**
+ *
+ * @param {string} status
+ */
+Project.prototype.setStatus = function (status) {
+  this._status = status;
+};
+
+/**
+ *
+ * @returns {number}
+ */
+Project.prototype.getProgress = function () {
+  return this._progress;
+};
+
+/**
+ *
+ * @param {number} progress
+ */
+Project.prototype.setProgress = function (progress) {
+  this._progress = progress;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+Project.prototype.getNotifyEmail = function () {
+  return this._notifyEmail;
+};
+
+/**
+ *
+ * @param {string} notifyEmail
+ */
+Project.prototype.setNotifyEmail = function (notifyEmail) {
+  this._notifyEmail = notifyEmail;
+};
+
+/**
+ *
+ * @param {DataOverlay} overlay
+ * @param {boolean} [updateWhenExists=false]
+ */
+Project.prototype.addDataOverlay = function (overlay, updateWhenExists) {
+  var overlayToAdd = null;
+  if (overlay instanceof DataOverlay) {
+    overlayToAdd = overlay;
+  } else {
+    overlayToAdd = new DataOverlay(overlay);
+  }
+  var object = this._dataOverlays[overlayToAdd.getId()];
+  if (object === undefined) {
+    this._dataOverlays[overlayToAdd.getId()] = overlayToAdd;
+  } else {
+    if (updateWhenExists) {
+      object.update(overlay);
+    } else {
+      throw new Error("Overlay " + overlayToAdd.getId() + " already exists in a project " + this.getProjectId());
+    }
+  }
+};
+
+/**
+ *
+ * @param {DataOverlay} overlay
+ */
+Project.prototype.addOrUpdateDataOverlay = function (overlay) {
+  this.addDataOverlay(overlay, true);
+};
+
+
+/**
+ *
+ * @param {DataOverlay[]} overlay
+ */
+Project.prototype.addOrUpdateDataOverlays = function (overlay) {
+  this.addDataOverlays(overlay, true);
+};
+
+/**
+ *
+ * @param {DataOverlay[]} overlays
+ * @param {boolean} updateWhenExists
+ */
+Project.prototype.addDataOverlays = function (overlays, updateWhenExists) {
+  if (overlays === undefined) {
+    logger.warn("Overlays are undefined...");
+  } else {
+    for (var i = 0; i < overlays.length; i++) {
+      this.addDataOverlay(overlays[i], updateWhenExists);
+    }
+  }
+};
+
+/**
+ *
+ * @returns {DataOverlay[]}
+ */
+Project.prototype.getDataOverlays = function () {
+  var result = [];
+  for (var id in this._dataOverlays) {
+    if (this._dataOverlays.hasOwnProperty(id)) {
+      result.push(this._dataOverlays[id]);
+    }
+  }
+  result.sort(function (dataOverlay1, dataOverlay2) {
+    if (dataOverlay1.getOrder() < dataOverlay2.getOrder())
+      return -1;
+    if (dataOverlay1.getOrder() > dataOverlay2.getOrder())
+      return 1;
+    return 0;
+  });
+  return result;
+};
+
+
+/**
+ * Returns data overlay for a given overlay identifier.
+ *
+ * @param {number} overlayId
+ *          overlay identifier
+ * @returns {PromiseLike<DataOverlay>} for a given overlay identifier
+ */
+Project.prototype.getDataOverlayById = function (overlayId) {
+  var self = this;
+  if (self._dataOverlays[overlayId] !== undefined) {
+    return Promise.resolve(self._dataOverlays[overlayId]);
+  } else {
+    return ServerConnector.getOverlayById(overlayId).then(function (overlay) {
+      self.addDataOverlay(overlay, false);
+      return self._dataOverlays[overlayId];
+    });
+  }
+};
+
+/**
+ * Returns promise with list of elements pointing to the submap.
+ *
+ * @param {number} modelId id of the submap
+ * @returns {Promise} for a given overlay identifier
+ */
+Project.prototype.getElementsPointingToSubmap = function (modelId) {
+  var self = this;
+  if (self._elementsPointingToSubmap[modelId] !== undefined) {
+    return Promise.resolve(self._elementsPointingToSubmap[modelId]);
+  }
+  var promise = Promise.resolve();
+  if (self._submapConnections === undefined) {
+    promise = ServerConnector.getSubmapConnections().then(function (data) {
+      self._submapConnections = data;
+    });
+  }
+  return promise.then(function () {
+    self._elementsPointingToSubmap[modelId] = [];
+
+    var queue = [modelId];
+
+    while (queue.length > 0) {
+      var id = queue.shift();
+      for (var i = 0; i < self._submapConnections.length; i++) {
+        var connection = self._submapConnections[i];
+        if (connection.to === id) {
+          var elementToAdd = connection.from;
+          var alreadyAdded = false;
+          for (var j = 0; j < self._elementsPointingToSubmap[modelId].length; j++) {
+            var elementAlreadyAdded = self._elementsPointingToSubmap[modelId][j];
+            if (elementToAdd.getId() === elementAlreadyAdded.getId()) {
+              alreadyAdded = true;
+            }
+          }
+          if (!alreadyAdded) {
+            self._elementsPointingToSubmap[modelId].push(elementToAdd);
+            queue.push(elementToAdd.getModelId());
+          }
+        }
+      }
+    }
+
+    return self._elementsPointingToSubmap[modelId];
+  });
+};
+
+
+module.exports = Project;
diff --git a/frontend-js/src/main/js/map/data/ProjectStatistics.js b/frontend-js/src/main/js/map/data/ProjectStatistics.js
index 0e5cd484641a1a04e88b51e38391628854617a04..5230dbdad6e498ecec6d2b459e7777d169bdf255 100644
--- a/frontend-js/src/main/js/map/data/ProjectStatistics.js
+++ b/frontend-js/src/main/js/map/data/ProjectStatistics.js
@@ -1,63 +1,63 @@
-"use strict";
-
-/* exported logger */
-
-var ObjectWithListeners = require('../../ObjectWithListeners');
-
-var logger = require('../../logger');
-
-function ProjectStatistics(data, configuration) {
-  // call super constructor
-  ObjectWithListeners.call(this);
-
-  this.setReactionAnnotations(data.reactionAnnotations, configuration);
-  this.setElementAnnotations(data.elementAnnotations, configuration);
-  this.setPublicationCount(data.publications, configuration);
-}
-
-ProjectStatistics.prototype = Object.create(ObjectWithListeners.prototype);
-ProjectStatistics.prototype.constructor = ProjectStatistics;
-
-ProjectStatistics.prototype.setReactionAnnotations = function(reactionAnnotations, configuration) {
-  var self = this;
-  self._reactionAnnotations = [];
-  for ( var key in reactionAnnotations) {
-    if (reactionAnnotations.hasOwnProperty(key)) {
-      var miriamType = configuration.getMiriamTypeByName(key);
-      self._reactionAnnotations.push({
-        miriamType : miriamType,
-        count : reactionAnnotations[key]
-      });
-    }
-  }
-};
-
-ProjectStatistics.prototype.setElementAnnotations = function(elementAnnotations, configuration) {
-  var self = this;
-  self._elementAnnotations = [];
-  for ( var key in elementAnnotations) {
-    if (elementAnnotations.hasOwnProperty(key)) {
-      var miriamType = configuration.getMiriamTypeByName(key);
-      self._elementAnnotations.push({
-        miriamType : miriamType,
-        count : elementAnnotations[key]
-      });
-    }
-  }
-};
-
-ProjectStatistics.prototype.getElementAnnotations = function() {
-  return this._elementAnnotations;
-};
-ProjectStatistics.prototype.getReactionAnnotations = function() {
-  return this._reactionAnnotations;
-};
-
-ProjectStatistics.prototype.setPublicationCount = function(count) {
-  this._publicationsCount = count;
-};
-ProjectStatistics.prototype.getPublicationCount = function() {
-  return this._publicationsCount;
-};
-
-module.exports = ProjectStatistics;
+"use strict";
+
+/* exported logger */
+
+var ObjectWithListeners = require('../../ObjectWithListeners');
+
+var logger = require('../../logger');
+
+function ProjectStatistics(data, configuration) {
+  // call super constructor
+  ObjectWithListeners.call(this);
+
+  this.setReactionAnnotations(data.reactionAnnotations, configuration);
+  this.setElementAnnotations(data.elementAnnotations, configuration);
+  this.setPublicationCount(data.publications, configuration);
+}
+
+ProjectStatistics.prototype = Object.create(ObjectWithListeners.prototype);
+ProjectStatistics.prototype.constructor = ProjectStatistics;
+
+ProjectStatistics.prototype.setReactionAnnotations = function(reactionAnnotations, configuration) {
+  var self = this;
+  self._reactionAnnotations = [];
+  for ( var key in reactionAnnotations) {
+    if (reactionAnnotations.hasOwnProperty(key)) {
+      var miriamType = configuration.getMiriamTypeByName(key);
+      self._reactionAnnotations.push({
+        miriamType : miriamType,
+        count : reactionAnnotations[key]
+      });
+    }
+  }
+};
+
+ProjectStatistics.prototype.setElementAnnotations = function(elementAnnotations, configuration) {
+  var self = this;
+  self._elementAnnotations = [];
+  for ( var key in elementAnnotations) {
+    if (elementAnnotations.hasOwnProperty(key)) {
+      var miriamType = configuration.getMiriamTypeByName(key);
+      self._elementAnnotations.push({
+        miriamType : miriamType,
+        count : elementAnnotations[key]
+      });
+    }
+  }
+};
+
+ProjectStatistics.prototype.getElementAnnotations = function() {
+  return this._elementAnnotations;
+};
+ProjectStatistics.prototype.getReactionAnnotations = function() {
+  return this._reactionAnnotations;
+};
+
+ProjectStatistics.prototype.setPublicationCount = function(count) {
+  this._publicationsCount = count;
+};
+ProjectStatistics.prototype.getPublicationCount = function() {
+  return this._publicationsCount;
+};
+
+module.exports = ProjectStatistics;
diff --git a/frontend-js/src/main/js/map/data/Reactant.js b/frontend-js/src/main/js/map/data/Reactant.js
index 8643fc280213b264e5d6342d6999c468cde02a7f..d6f65d317556d6534e84f9740efb3b25041aa762 100644
--- a/frontend-js/src/main/js/map/data/Reactant.js
+++ b/frontend-js/src/main/js/map/data/Reactant.js
@@ -1,30 +1,30 @@
-"use strict";
-
-var Alias = require("./Alias");
-
-
-function Reactant(javaObject) {
-  this.setAlias(javaObject.aliasId);
-  this.setStoichiometry(javaObject.stoichiometry);
-}
-
-Reactant.prototype.getAlias = function () {
-  return this._alias;
-};
-
-Reactant.prototype.setAlias = function (alias) {
-  this._alias = alias;
-};
-
-Reactant.prototype.isComplete = function (alias) {
-  return this.getAlias() instanceof Alias;
-};
-Reactant.prototype.getStoichiometry = function () {
-  return this._stoichiometry;
-};
-Reactant.prototype.setStoichiometry = function (stoichiometry) {
-  this._stoichiometry = stoichiometry;
-};
-
-
-module.exports = Reactant;
+"use strict";
+
+var Alias = require("./Alias");
+
+
+function Reactant(javaObject) {
+  this.setAlias(javaObject.aliasId);
+  this.setStoichiometry(javaObject.stoichiometry);
+}
+
+Reactant.prototype.getAlias = function () {
+  return this._alias;
+};
+
+Reactant.prototype.setAlias = function (alias) {
+  this._alias = alias;
+};
+
+Reactant.prototype.isComplete = function (alias) {
+  return this.getAlias() instanceof Alias;
+};
+Reactant.prototype.getStoichiometry = function () {
+  return this._stoichiometry;
+};
+Reactant.prototype.setStoichiometry = function (stoichiometry) {
+  this._stoichiometry = stoichiometry;
+};
+
+
+module.exports = Reactant;
diff --git a/frontend-js/src/main/js/map/data/Reaction.js b/frontend-js/src/main/js/map/data/Reaction.js
index 8a0499c487eda93207e340385d29b1367444edb3..9e9efffa7dc1f8163e6d9c27f6298c1d2a16fe62 100644
--- a/frontend-js/src/main/js/map/data/Reaction.js
+++ b/frontend-js/src/main/js/map/data/Reaction.js
@@ -1,257 +1,257 @@
-"use strict";
-
-/* exported logger */
-
-var BioEntity = require("./BioEntity");
-var KineticLaw = require("./KineticLaw");
-var Point = require("../canvas/Point");
-
-var Modifier = require('./Modifier');
-var Product = require('./Product');
-var Reactant = require('./Reactant');
-
-var logger = require('../../logger');
-
-/**
- * Class representing reaction data.
- *
- * @param javaObject
- *          object de-serialized from ajax query to the server side
- */
-function Reaction(javaObject) {
-  BioEntity.call(this, javaObject);
-  this.startLines = [];
-  this.endLines = [];
-  this.midLines = [];
-  if (javaObject instanceof Reaction) {
-    this.setId(javaObject.getId());
-    this.setCenter(javaObject.getCenter());
-    this.setModelId(javaObject.getModelId());
-
-    this.startLines.push.apply(this.startLines, javaObject.getStartLines());
-    this.endLines.push.apply(this.endLines, javaObject.getEndLines());
-    this.midLines.push.apply(this.midLines, javaObject.getMidLines());
-
-  } else {
-    if (javaObject.idObject !== undefined) {
-      this.setId(javaObject.idObject);
-    } else {
-      this.setId(javaObject.id);
-    }
-    for (var i = 0; i < javaObject.lines.length; i++) {
-      var line = javaObject.lines[i];
-      if (line.type === "START") {
-        this.startLines.push(line);
-      } else if (line.type === "END") {
-        this.endLines.push(line);
-      } else if (line.type === "MIDDLE") {
-        this.midLines.push(line);
-      } else {
-        throw new Error("Unknown line type: " + line.type);
-      }
-    }
-    this.setCenter(javaObject.centerPoint);
-    this.setModelId(javaObject.modelId);
-    this.setIsComplete(false);
-    this.update(javaObject);
-  }
-}
-
-Reaction.prototype = Object.create(BioEntity.prototype);
-Reaction.prototype.constructor = Reaction;
-
-/**
- *
- * @returns {Point}
- */
-Reaction.prototype.getCenter = function () {
-  return this._center;
-};
-
-/**
- *
- * @returns {Object[]}
- */
-Reaction.prototype.getLines = function () {
-  var result = [];
-  result = result.concat(this.startLines);
-  result = result.concat(this.endLines);
-  result = result.concat(this.midLines);
-  return result;
-};
-
-Reaction.prototype.getMidLines = function () {
-  return this.midLines;
-};
-Reaction.prototype.getStartLines = function () {
-  return this.startLines;
-};
-Reaction.prototype.getEndLines = function () {
-  return this.endLines;
-};
-
-Reaction.prototype.setCenter = function (center) {
-  if (center === null || center === undefined) {
-    throw new Error("Setting undefined center: " + center);
-  }
-  this._center = new Point(center);
-};
-
-Reaction.prototype.update = function (javaObject) {
-  if (javaObject.reactionId === undefined) {
-    return;
-  }
-  this.setReactionId(javaObject.reactionId);
-  this.setSymbol(javaObject.symbol);
-  this.setAbbreviation(javaObject.abbreviation);
-  this.setFormula(javaObject.formula);
-  this.setMechanicalConfidenceScore(javaObject.mechanicalConfidenceScore);
-  this.setLowerBound(javaObject.lowerBound);
-  this.setUpperBound(javaObject.upperBound);
-  this.setGeneProteinReaction(javaObject.geneProteinReaction);
-  this.setSubsystem(javaObject.subsystem);
-  this.setSynonyms(javaObject.synonyms);
-  this.setDescription(javaObject.notes);
-  this.setOther(javaObject.other);
-  this.setReferences(javaObject.references);
-  this.setType(javaObject.type);
-
-  var reactants = [];
-  var products = [];
-  var modifiers = [];
-  var i;
-  if (javaObject.reactants !== undefined) {
-    for (i = 0; i < javaObject.reactants.length; i++) {
-      reactants.push(new Reactant(javaObject.reactants[i]));
-    }
-  }
-  if (javaObject.products !== undefined) {
-    for (i = 0; i < javaObject.products.length; i++) {
-      products.push(new Product(javaObject.products[i]));
-    }
-  }
-  if (javaObject.modifiers !== "" && javaObject.modifiers !== undefined) {
-    for (i = 0; i < javaObject.modifiers.length; i++) {
-      modifiers.push(new Modifier(javaObject.modifiers[i]));
-    }
-  }
-  this.setReactants(reactants);
-  this.setProducts(products);
-  this.setModifiers(modifiers);
-
-  if (javaObject.kineticLaw !== undefined && javaObject.kineticLaw !== null) {
-    this.setKineticLaw(new KineticLaw(javaObject.kineticLaw));
-  }
-
-  this.setHierarchyVisibilityLevel(javaObject.hierarchyVisibilityLevel);
-  this.setIsComplete(true);
-};
-
-Reaction.prototype.isComplete = function () {
-  var self = this;
-  var result = self._complete;
-  if (result) {
-    var reactants = self.getReactants();
-    if (reactants.length === 0) {
-      result = false;
-    } else {
-      result = reactants[0].isComplete();
-    }
-  }
-  return result;
-};
-
-Reaction.prototype.getReactionId = function () {
-  return this._reactionId;
-};
-
-Reaction.prototype.setReactionId = function (reactionId) {
-  this._reactionId = reactionId;
-};
-
-Reaction.prototype.getMechanicalConfidenceScore = function () {
-  return this._mechanicalConfidenceScore;
-};
-
-Reaction.prototype.setMechanicalConfidenceScore = function (mechanicalConfidenceScore) {
-  this._mechanicalConfidenceScore = mechanicalConfidenceScore;
-};
-
-Reaction.prototype.getLowerBound = function () {
-  return this._lowerBound;
-};
-
-Reaction.prototype.setLowerBound = function (lowerBound) {
-  this._lowerBound = lowerBound;
-};
-
-Reaction.prototype.getUpperBound = function () {
-  return this._upperBound;
-};
-
-Reaction.prototype.setUpperBound = function (upperBound) {
-  this._upperBound = upperBound;
-};
-
-Reaction.prototype.setGeneProteinReaction = function (geneProteinReaction) {
-  this._geneProteinReaction = geneProteinReaction;
-};
-
-Reaction.prototype.getGeneProteinReaction = function () {
-  return this._geneProteinReaction;
-};
-
-Reaction.prototype.setSubsystem = function (subsystem) {
-  this._subsystem = subsystem;
-};
-
-Reaction.prototype.getSubsystem = function () {
-  return this._subsystem;
-};
-
-Reaction.prototype.getReactants = function () {
-  return this._reactants;
-};
-
-Reaction.prototype.setReactants = function (reactants) {
-  this._reactants = reactants;
-};
-
-Reaction.prototype.setProducts = function (products) {
-  this._products = products;
-};
-
-Reaction.prototype.getProducts = function () {
-  return this._products;
-};
-
-Reaction.prototype.getElements = function () {
-  var result = [], i;
-  for (i = 0; i < this.getReactants().length; i++) {
-    result.push(this.getReactants()[i].getAlias());
-  }
-  for (i = 0; i < this.getProducts().length; i++) {
-    result.push(this.getProducts()[i].getAlias());
-  }
-  for (i = 0; i < this.getModifiers().length; i++) {
-    result.push(this.getModifiers()[i].getAlias());
-  }
-  return result;
-};
-
-Reaction.prototype.setModifiers = function (modifiers) {
-  this._modifiers = modifiers;
-};
-
-Reaction.prototype.getModifiers = function () {
-  return this._modifiers;
-};
-
-Reaction.prototype.setKineticLaw = function (kineticLaw) {
-  this._kineticLaw = kineticLaw;
-};
-Reaction.prototype.getKineticLaw = function () {
-  return this._kineticLaw;
-};
-
-module.exports = Reaction;
+"use strict";
+
+/* exported logger */
+
+var BioEntity = require("./BioEntity");
+var KineticLaw = require("./KineticLaw");
+var Point = require("../canvas/Point");
+
+var Modifier = require('./Modifier');
+var Product = require('./Product');
+var Reactant = require('./Reactant');
+
+var logger = require('../../logger');
+
+/**
+ * Class representing reaction data.
+ *
+ * @param javaObject
+ *          object de-serialized from ajax query to the server side
+ */
+function Reaction(javaObject) {
+  BioEntity.call(this, javaObject);
+  this.startLines = [];
+  this.endLines = [];
+  this.midLines = [];
+  if (javaObject instanceof Reaction) {
+    this.setId(javaObject.getId());
+    this.setCenter(javaObject.getCenter());
+    this.setModelId(javaObject.getModelId());
+
+    this.startLines.push.apply(this.startLines, javaObject.getStartLines());
+    this.endLines.push.apply(this.endLines, javaObject.getEndLines());
+    this.midLines.push.apply(this.midLines, javaObject.getMidLines());
+
+  } else {
+    if (javaObject.idObject !== undefined) {
+      this.setId(javaObject.idObject);
+    } else {
+      this.setId(javaObject.id);
+    }
+    for (var i = 0; i < javaObject.lines.length; i++) {
+      var line = javaObject.lines[i];
+      if (line.type === "START") {
+        this.startLines.push(line);
+      } else if (line.type === "END") {
+        this.endLines.push(line);
+      } else if (line.type === "MIDDLE") {
+        this.midLines.push(line);
+      } else {
+        throw new Error("Unknown line type: " + line.type);
+      }
+    }
+    this.setCenter(javaObject.centerPoint);
+    this.setModelId(javaObject.modelId);
+    this.setIsComplete(false);
+    this.update(javaObject);
+  }
+}
+
+Reaction.prototype = Object.create(BioEntity.prototype);
+Reaction.prototype.constructor = Reaction;
+
+/**
+ *
+ * @returns {Point}
+ */
+Reaction.prototype.getCenter = function () {
+  return this._center;
+};
+
+/**
+ *
+ * @returns {Object[]}
+ */
+Reaction.prototype.getLines = function () {
+  var result = [];
+  result = result.concat(this.startLines);
+  result = result.concat(this.endLines);
+  result = result.concat(this.midLines);
+  return result;
+};
+
+Reaction.prototype.getMidLines = function () {
+  return this.midLines;
+};
+Reaction.prototype.getStartLines = function () {
+  return this.startLines;
+};
+Reaction.prototype.getEndLines = function () {
+  return this.endLines;
+};
+
+Reaction.prototype.setCenter = function (center) {
+  if (center === null || center === undefined) {
+    throw new Error("Setting undefined center: " + center);
+  }
+  this._center = new Point(center);
+};
+
+Reaction.prototype.update = function (javaObject) {
+  if (javaObject.reactionId === undefined) {
+    return;
+  }
+  this.setReactionId(javaObject.reactionId);
+  this.setSymbol(javaObject.symbol);
+  this.setAbbreviation(javaObject.abbreviation);
+  this.setFormula(javaObject.formula);
+  this.setMechanicalConfidenceScore(javaObject.mechanicalConfidenceScore);
+  this.setLowerBound(javaObject.lowerBound);
+  this.setUpperBound(javaObject.upperBound);
+  this.setGeneProteinReaction(javaObject.geneProteinReaction);
+  this.setSubsystem(javaObject.subsystem);
+  this.setSynonyms(javaObject.synonyms);
+  this.setDescription(javaObject.notes);
+  this.setOther(javaObject.other);
+  this.setReferences(javaObject.references);
+  this.setType(javaObject.type);
+
+  var reactants = [];
+  var products = [];
+  var modifiers = [];
+  var i;
+  if (javaObject.reactants !== undefined) {
+    for (i = 0; i < javaObject.reactants.length; i++) {
+      reactants.push(new Reactant(javaObject.reactants[i]));
+    }
+  }
+  if (javaObject.products !== undefined) {
+    for (i = 0; i < javaObject.products.length; i++) {
+      products.push(new Product(javaObject.products[i]));
+    }
+  }
+  if (javaObject.modifiers !== "" && javaObject.modifiers !== undefined) {
+    for (i = 0; i < javaObject.modifiers.length; i++) {
+      modifiers.push(new Modifier(javaObject.modifiers[i]));
+    }
+  }
+  this.setReactants(reactants);
+  this.setProducts(products);
+  this.setModifiers(modifiers);
+
+  if (javaObject.kineticLaw !== undefined && javaObject.kineticLaw !== null) {
+    this.setKineticLaw(new KineticLaw(javaObject.kineticLaw));
+  }
+
+  this.setHierarchyVisibilityLevel(javaObject.hierarchyVisibilityLevel);
+  this.setIsComplete(true);
+};
+
+Reaction.prototype.isComplete = function () {
+  var self = this;
+  var result = self._complete;
+  if (result) {
+    var reactants = self.getReactants();
+    if (reactants.length === 0) {
+      result = false;
+    } else {
+      result = reactants[0].isComplete();
+    }
+  }
+  return result;
+};
+
+Reaction.prototype.getReactionId = function () {
+  return this._reactionId;
+};
+
+Reaction.prototype.setReactionId = function (reactionId) {
+  this._reactionId = reactionId;
+};
+
+Reaction.prototype.getMechanicalConfidenceScore = function () {
+  return this._mechanicalConfidenceScore;
+};
+
+Reaction.prototype.setMechanicalConfidenceScore = function (mechanicalConfidenceScore) {
+  this._mechanicalConfidenceScore = mechanicalConfidenceScore;
+};
+
+Reaction.prototype.getLowerBound = function () {
+  return this._lowerBound;
+};
+
+Reaction.prototype.setLowerBound = function (lowerBound) {
+  this._lowerBound = lowerBound;
+};
+
+Reaction.prototype.getUpperBound = function () {
+  return this._upperBound;
+};
+
+Reaction.prototype.setUpperBound = function (upperBound) {
+  this._upperBound = upperBound;
+};
+
+Reaction.prototype.setGeneProteinReaction = function (geneProteinReaction) {
+  this._geneProteinReaction = geneProteinReaction;
+};
+
+Reaction.prototype.getGeneProteinReaction = function () {
+  return this._geneProteinReaction;
+};
+
+Reaction.prototype.setSubsystem = function (subsystem) {
+  this._subsystem = subsystem;
+};
+
+Reaction.prototype.getSubsystem = function () {
+  return this._subsystem;
+};
+
+Reaction.prototype.getReactants = function () {
+  return this._reactants;
+};
+
+Reaction.prototype.setReactants = function (reactants) {
+  this._reactants = reactants;
+};
+
+Reaction.prototype.setProducts = function (products) {
+  this._products = products;
+};
+
+Reaction.prototype.getProducts = function () {
+  return this._products;
+};
+
+Reaction.prototype.getElements = function () {
+  var result = [], i;
+  for (i = 0; i < this.getReactants().length; i++) {
+    result.push(this.getReactants()[i].getAlias());
+  }
+  for (i = 0; i < this.getProducts().length; i++) {
+    result.push(this.getProducts()[i].getAlias());
+  }
+  for (i = 0; i < this.getModifiers().length; i++) {
+    result.push(this.getModifiers()[i].getAlias());
+  }
+  return result;
+};
+
+Reaction.prototype.setModifiers = function (modifiers) {
+  this._modifiers = modifiers;
+};
+
+Reaction.prototype.getModifiers = function () {
+  return this._modifiers;
+};
+
+Reaction.prototype.setKineticLaw = function (kineticLaw) {
+  this._kineticLaw = kineticLaw;
+};
+Reaction.prototype.getKineticLaw = function () {
+  return this._kineticLaw;
+};
+
+module.exports = Reaction;
diff --git a/frontend-js/src/main/js/map/data/ReferenceGenome.js b/frontend-js/src/main/js/map/data/ReferenceGenome.js
index 8ed9b5445016bb0b1a922580129e125079e4c7be..cc90df69f73c79e6cc97d1c31d5a0b7ef91ea6a9 100644
--- a/frontend-js/src/main/js/map/data/ReferenceGenome.js
+++ b/frontend-js/src/main/js/map/data/ReferenceGenome.js
@@ -1,193 +1,193 @@
-"use strict";
-
-var Annotation = require('./Annotation');
-var ReferenceGenomeGeneMapping = require('./ReferenceGenomeGeneMapping');
-
-function ReferenceGenome(javaObject) {
-  if (javaObject !== undefined && javaObject !== null) {
-    this.setId(javaObject.idObject);
-    this.setType(javaObject.type);
-    this.setVersion(javaObject.version);
-    this.setLocalUrl(javaObject.localUrl);
-    this.setSourceUrl(javaObject.sourceUrl);
-    if (javaObject.localUrl !== undefined) {
-      this.setUrl(javaObject.localUrl);
-    } else {
-      this.setUrl(javaObject.sourceUrl);
-    }
-    this.setOrganism(new Annotation(javaObject.organism));
-    this.setDownloadProgress(javaObject.downloadProgress);
-    this._geneMapping = [];
-    if (javaObject.geneMapping !== undefined) {
-      for (var i = 0; i < javaObject.geneMapping.length; i++) {
-        this._geneMapping.push(new ReferenceGenomeGeneMapping(javaObject.geneMapping[i]));
-      }
-    }
-  } else {
-    this._geneMapping = [];
-  }
-}
-
-/**
- *
- * @param {string} type
- */
-ReferenceGenome.prototype.setType = function (type) {
-  this._type = type;
-};
-
-/**
- *
- * @returns {string}
- */
-ReferenceGenome.prototype.getType = function () {
-  return this._type;
-};
-
-/**
- *
- * @param {number} id
- */
-ReferenceGenome.prototype.setId = function (id) {
-  this._id = id;
-};
-
-/**
- *
- * @returns {number}
- */
-ReferenceGenome.prototype.getId = function () {
-  return this._id;
-};
-
-/**
- *
- * @returns {number}
- */
-ReferenceGenome.prototype.getDownloadProgress = function () {
-  return this._downloadProgress;
-};
-
-/**
- *
- * @param {number} downloadProgress
- */
-ReferenceGenome.prototype.setDownloadProgress = function (downloadProgress) {
-  this._downloadProgress = downloadProgress;
-};
-
-
-/**
- *
- * @returns {string}
- */
-ReferenceGenome.prototype.getDownloadProgressStatus = function () {
-  if (this.getDownloadProgress() === 100) {
-    if (this.getLocalUrl() !== undefined) {
-      return "READY";
-    } else {
-      return "ERROR";
-    }
-  } else {
-    if (this.getDownloadProgress() === undefined) {
-      return "N/A";
-    } else {
-      return this.getDownloadProgress().toString();
-    }
-  }
-};
-
-
-/**
- *
- * @param {Annotation} organism
- */
-ReferenceGenome.prototype.setOrganism = function (organism) {
-  this._organism = organism;
-};
-
-/**
- *
- * @returns {Annotation}
- */
-ReferenceGenome.prototype.getOrganism = function () {
-  return this._organism;
-};
-
-/**
- *
- * @param {string} url
- */
-ReferenceGenome.prototype.setUrl = function (url) {
-  this._url = url;
-};
-
-/**
- *
- * @returns {string}
- */
-ReferenceGenome.prototype.getUrl = function () {
-  return this._url;
-};
-
-/**
- *
- * @returns {string}
- */
-ReferenceGenome.prototype.getSourceUrl = function () {
-  return this._sourceUrl;
-};
-
-/**
- *
- * @param {string} sourceUrl
- */
-ReferenceGenome.prototype.setSourceUrl = function (sourceUrl) {
-  this._sourceUrl = sourceUrl;
-};
-
-/**
- *
- * @returns {string}
- */
-ReferenceGenome.prototype.getLocalUrl = function () {
-  return this._localUrl;
-};
-
-/**
- *
- * @param {string} localUrl
- */
-ReferenceGenome.prototype.setLocalUrl = function (localUrl) {
-  if (localUrl === null) {
-    this._localUrl = undefined;
-  } else {
-    this._localUrl = localUrl;
-  }
-};
-
-/**
- *
- * @param {string} version
- */
-ReferenceGenome.prototype.setVersion = function (version) {
-  this._version = version;
-};
-
-/**
- *
- * @returns {string}
- */
-ReferenceGenome.prototype.getVersion = function () {
-  return this._version;
-};
-
-/**
- *
- * @returns {ReferenceGenomeGeneMapping[]}
- */
-ReferenceGenome.prototype.getGeneMappings = function () {
-  return this._geneMapping;
-};
-
-module.exports = ReferenceGenome;
+"use strict";
+
+var Annotation = require('./Annotation');
+var ReferenceGenomeGeneMapping = require('./ReferenceGenomeGeneMapping');
+
+function ReferenceGenome(javaObject) {
+  if (javaObject !== undefined && javaObject !== null) {
+    this.setId(javaObject.idObject);
+    this.setType(javaObject.type);
+    this.setVersion(javaObject.version);
+    this.setLocalUrl(javaObject.localUrl);
+    this.setSourceUrl(javaObject.sourceUrl);
+    if (javaObject.localUrl !== undefined) {
+      this.setUrl(javaObject.localUrl);
+    } else {
+      this.setUrl(javaObject.sourceUrl);
+    }
+    this.setOrganism(new Annotation(javaObject.organism));
+    this.setDownloadProgress(javaObject.downloadProgress);
+    this._geneMapping = [];
+    if (javaObject.geneMapping !== undefined) {
+      for (var i = 0; i < javaObject.geneMapping.length; i++) {
+        this._geneMapping.push(new ReferenceGenomeGeneMapping(javaObject.geneMapping[i]));
+      }
+    }
+  } else {
+    this._geneMapping = [];
+  }
+}
+
+/**
+ *
+ * @param {string} type
+ */
+ReferenceGenome.prototype.setType = function (type) {
+  this._type = type;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+ReferenceGenome.prototype.getType = function () {
+  return this._type;
+};
+
+/**
+ *
+ * @param {number} id
+ */
+ReferenceGenome.prototype.setId = function (id) {
+  this._id = id;
+};
+
+/**
+ *
+ * @returns {number}
+ */
+ReferenceGenome.prototype.getId = function () {
+  return this._id;
+};
+
+/**
+ *
+ * @returns {number}
+ */
+ReferenceGenome.prototype.getDownloadProgress = function () {
+  return this._downloadProgress;
+};
+
+/**
+ *
+ * @param {number} downloadProgress
+ */
+ReferenceGenome.prototype.setDownloadProgress = function (downloadProgress) {
+  this._downloadProgress = downloadProgress;
+};
+
+
+/**
+ *
+ * @returns {string}
+ */
+ReferenceGenome.prototype.getDownloadProgressStatus = function () {
+  if (this.getDownloadProgress() === 100) {
+    if (this.getLocalUrl() !== undefined) {
+      return "READY";
+    } else {
+      return "ERROR";
+    }
+  } else {
+    if (this.getDownloadProgress() === undefined) {
+      return "N/A";
+    } else {
+      return this.getDownloadProgress().toString();
+    }
+  }
+};
+
+
+/**
+ *
+ * @param {Annotation} organism
+ */
+ReferenceGenome.prototype.setOrganism = function (organism) {
+  this._organism = organism;
+};
+
+/**
+ *
+ * @returns {Annotation}
+ */
+ReferenceGenome.prototype.getOrganism = function () {
+  return this._organism;
+};
+
+/**
+ *
+ * @param {string} url
+ */
+ReferenceGenome.prototype.setUrl = function (url) {
+  this._url = url;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+ReferenceGenome.prototype.getUrl = function () {
+  return this._url;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+ReferenceGenome.prototype.getSourceUrl = function () {
+  return this._sourceUrl;
+};
+
+/**
+ *
+ * @param {string} sourceUrl
+ */
+ReferenceGenome.prototype.setSourceUrl = function (sourceUrl) {
+  this._sourceUrl = sourceUrl;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+ReferenceGenome.prototype.getLocalUrl = function () {
+  return this._localUrl;
+};
+
+/**
+ *
+ * @param {string} localUrl
+ */
+ReferenceGenome.prototype.setLocalUrl = function (localUrl) {
+  if (localUrl === null) {
+    this._localUrl = undefined;
+  } else {
+    this._localUrl = localUrl;
+  }
+};
+
+/**
+ *
+ * @param {string} version
+ */
+ReferenceGenome.prototype.setVersion = function (version) {
+  this._version = version;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+ReferenceGenome.prototype.getVersion = function () {
+  return this._version;
+};
+
+/**
+ *
+ * @returns {ReferenceGenomeGeneMapping[]}
+ */
+ReferenceGenome.prototype.getGeneMappings = function () {
+  return this._geneMapping;
+};
+
+module.exports = ReferenceGenome;
diff --git a/frontend-js/src/main/js/map/data/ReferenceGenomeGeneMapping.js b/frontend-js/src/main/js/map/data/ReferenceGenomeGeneMapping.js
index b28f702bb5667b2d93d8672502bb26faa1b602a8..d8e955bf20522b4192b69389e800bc9a697e9025 100644
--- a/frontend-js/src/main/js/map/data/ReferenceGenomeGeneMapping.js
+++ b/frontend-js/src/main/js/map/data/ReferenceGenomeGeneMapping.js
@@ -1,112 +1,112 @@
-"use strict";
-
-function ReferenceGenomeGeneMapping(javaObject) {
-  this.setName(javaObject.name);
-  if (javaObject.localUrl !== undefined) {
-    this.setUrl(javaObject.localUrl);
-  } else {
-    this.setUrl(javaObject.sourceUrl);
-  }
-  this.setLocalUrl(javaObject.localUrl);
-  this.setSourceUrl(javaObject.sourceUrl);
-  this.setProgress(javaObject.downloadProgress);
-  this.setId(javaObject.idObject);
-}
-
-/**
- *
- * @param {string} name
- */
-ReferenceGenomeGeneMapping.prototype.setName = function (name) {
-  this._name = name;
-};
-
-/**
- *
- * @returns {string}
- */
-ReferenceGenomeGeneMapping.prototype.getName = function () {
-  return this._name;
-};
-
-/**
- *
- * @param {string} url
- */
-ReferenceGenomeGeneMapping.prototype.setUrl = function (url) {
-  this._url = url;
-};
-
-/**
- *
- * @returns {string}
- */
-ReferenceGenomeGeneMapping.prototype.getUrl = function () {
-  return this._url;
-};
-
-/**
- *
- * @param {string} url
- */
-ReferenceGenomeGeneMapping.prototype.setLocalUrl = function (url) {
-  this._localUrl = url;
-};
-
-/**
- *
- * @returns {string}
- */
-ReferenceGenomeGeneMapping.prototype.getLocalUrl = function () {
-  return this._localUrl;
-};
-
-/**
- *
- * @returns {string}
- */
-ReferenceGenomeGeneMapping.prototype.getSourceUrl = function () {
-  return this._sourceUrl;
-};
-
-/**
- *
- * @param {string} url
- */
-ReferenceGenomeGeneMapping.prototype.setSourceUrl = function (url) {
-  this._sourceUrl = url;
-};
-
-/**
- *
- * @param {number} progress
- */
-ReferenceGenomeGeneMapping.prototype.setProgress = function (progress) {
-  this._progress = progress;
-};
-
-/**
- *
- * @returns {number}
- */
-ReferenceGenomeGeneMapping.prototype.getProgress = function () {
-  return this._progress;
-};
-
-/**
- *
- * @param {number} id
- */
-ReferenceGenomeGeneMapping.prototype.setId = function (id) {
-  this._id = id;
-};
-
-/**
- *
- * @returns {number}
- */
-ReferenceGenomeGeneMapping.prototype.getId = function () {
-  return this._id;
-};
-
-module.exports = ReferenceGenomeGeneMapping;
+"use strict";
+
+function ReferenceGenomeGeneMapping(javaObject) {
+  this.setName(javaObject.name);
+  if (javaObject.localUrl !== undefined) {
+    this.setUrl(javaObject.localUrl);
+  } else {
+    this.setUrl(javaObject.sourceUrl);
+  }
+  this.setLocalUrl(javaObject.localUrl);
+  this.setSourceUrl(javaObject.sourceUrl);
+  this.setProgress(javaObject.downloadProgress);
+  this.setId(javaObject.idObject);
+}
+
+/**
+ *
+ * @param {string} name
+ */
+ReferenceGenomeGeneMapping.prototype.setName = function (name) {
+  this._name = name;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+ReferenceGenomeGeneMapping.prototype.getName = function () {
+  return this._name;
+};
+
+/**
+ *
+ * @param {string} url
+ */
+ReferenceGenomeGeneMapping.prototype.setUrl = function (url) {
+  this._url = url;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+ReferenceGenomeGeneMapping.prototype.getUrl = function () {
+  return this._url;
+};
+
+/**
+ *
+ * @param {string} url
+ */
+ReferenceGenomeGeneMapping.prototype.setLocalUrl = function (url) {
+  this._localUrl = url;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+ReferenceGenomeGeneMapping.prototype.getLocalUrl = function () {
+  return this._localUrl;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+ReferenceGenomeGeneMapping.prototype.getSourceUrl = function () {
+  return this._sourceUrl;
+};
+
+/**
+ *
+ * @param {string} url
+ */
+ReferenceGenomeGeneMapping.prototype.setSourceUrl = function (url) {
+  this._sourceUrl = url;
+};
+
+/**
+ *
+ * @param {number} progress
+ */
+ReferenceGenomeGeneMapping.prototype.setProgress = function (progress) {
+  this._progress = progress;
+};
+
+/**
+ *
+ * @returns {number}
+ */
+ReferenceGenomeGeneMapping.prototype.getProgress = function () {
+  return this._progress;
+};
+
+/**
+ *
+ * @param {number} id
+ */
+ReferenceGenomeGeneMapping.prototype.setId = function (id) {
+  this._id = id;
+};
+
+/**
+ *
+ * @returns {number}
+ */
+ReferenceGenomeGeneMapping.prototype.getId = function () {
+  return this._id;
+};
+
+module.exports = ReferenceGenomeGeneMapping;
diff --git a/frontend-js/src/main/js/map/data/SbmlFunction.js b/frontend-js/src/main/js/map/data/SbmlFunction.js
index c6d52947cda17dce905e60047e9779c0a7a4f2d1..077b8a23770a11f9db4374fa9bd13c3fc227b40a 100644
--- a/frontend-js/src/main/js/map/data/SbmlFunction.js
+++ b/frontend-js/src/main/js/map/data/SbmlFunction.js
@@ -1,55 +1,55 @@
-"use strict";
-
-function SbmlFunction(jsonObject) {
-  var self = this;
-  self.setFunctionId(jsonObject.functionId);
-  self.setName(jsonObject.name);
-  self.setId(jsonObject.id);
-  self.setArguments(jsonObject["arguments"]);
-  self.setDefinition(jsonObject.definition);
-  self.setMathMlPresentation(jsonObject.mathMlPresentation);
-}
-
-SbmlFunction.prototype.setFunctionId = function (functionId) {
-  this._functionId = functionId;
-};
-SbmlFunction.prototype.getFunctionId = function () {
-  return this._functionId;
-};
-
-SbmlFunction.prototype.setDefinition = function (definition) {
-  this._definition = definition;
-};
-SbmlFunction.prototype.getDefinition = function () {
-  return this._definition;
-};
-
-SbmlFunction.prototype.setMathMlPresentation = function (mathMlPresentation) {
-  this._mathMlPresentation = mathMlPresentation;
-};
-SbmlFunction.prototype.getMathMlPresentation = function () {
-  return this._mathMlPresentation;
-};
-
-SbmlFunction.prototype.setName = function (name) {
-  this._name = name;
-};
-SbmlFunction.prototype.getName = function () {
-  return this._name;
-};
-SbmlFunction.prototype.setArguments = function (args) {
-  this._arguments = args;
-};
-SbmlFunction.prototype.getArguments = function () {
-  return this._arguments;
-};
-
-SbmlFunction.prototype.setId = function (id) {
-  this._id = id;
-};
-SbmlFunction.prototype.getId = function () {
-  return this._id;
-};
-
-
-module.exports = SbmlFunction;
+"use strict";
+
+function SbmlFunction(jsonObject) {
+  var self = this;
+  self.setFunctionId(jsonObject.functionId);
+  self.setName(jsonObject.name);
+  self.setId(jsonObject.id);
+  self.setArguments(jsonObject["arguments"]);
+  self.setDefinition(jsonObject.definition);
+  self.setMathMlPresentation(jsonObject.mathMlPresentation);
+}
+
+SbmlFunction.prototype.setFunctionId = function (functionId) {
+  this._functionId = functionId;
+};
+SbmlFunction.prototype.getFunctionId = function () {
+  return this._functionId;
+};
+
+SbmlFunction.prototype.setDefinition = function (definition) {
+  this._definition = definition;
+};
+SbmlFunction.prototype.getDefinition = function () {
+  return this._definition;
+};
+
+SbmlFunction.prototype.setMathMlPresentation = function (mathMlPresentation) {
+  this._mathMlPresentation = mathMlPresentation;
+};
+SbmlFunction.prototype.getMathMlPresentation = function () {
+  return this._mathMlPresentation;
+};
+
+SbmlFunction.prototype.setName = function (name) {
+  this._name = name;
+};
+SbmlFunction.prototype.getName = function () {
+  return this._name;
+};
+SbmlFunction.prototype.setArguments = function (args) {
+  this._arguments = args;
+};
+SbmlFunction.prototype.getArguments = function () {
+  return this._arguments;
+};
+
+SbmlFunction.prototype.setId = function (id) {
+  this._id = id;
+};
+SbmlFunction.prototype.getId = function () {
+  return this._id;
+};
+
+
+module.exports = SbmlFunction;
diff --git a/frontend-js/src/main/js/map/data/SbmlParameter.js b/frontend-js/src/main/js/map/data/SbmlParameter.js
index 86c52d8b1b00e328939a4410c0c9898015c4fe6e..3bf2430104b657afefc8ced3696407e48ff97884 100644
--- a/frontend-js/src/main/js/map/data/SbmlParameter.js
+++ b/frontend-js/src/main/js/map/data/SbmlParameter.js
@@ -1,56 +1,56 @@
-"use strict";
-
-function SbmlParameter(jsonObject) {
-  var self = this;
-  self.setParameterId(jsonObject.parameterId);
-  self.setValue(jsonObject.value);
-  self.setGlobal(jsonObject.global);
-  self.setName(jsonObject.name);
-  self.setId(jsonObject.id);
-  self.setUnitsId(jsonObject.unitsId);
-}
-
-SbmlParameter.prototype.setParameterId = function (parameterId) {
-  this._parameterId = parameterId;
-};
-SbmlParameter.prototype.getParameterId = function () {
-  return this._parameterId;
-};
-
-SbmlParameter.prototype.setUnitsId = function (unitsId) {
-  this._unitsId = unitsId;
-};
-SbmlParameter.prototype.getUnitsId = function () {
-  return this._unitsId;
-};
-
-SbmlParameter.prototype.setValue = function (value) {
-  this._value = value;
-};
-SbmlParameter.prototype.getValue = function () {
-  return this._value;
-};
-
-SbmlParameter.prototype.setGlobal = function (global) {
-  this._global = global;
-};
-SbmlParameter.prototype.getGlobal = function () {
-  return this._global;
-};
-
-SbmlParameter.prototype.setName = function (name) {
-  this._name = name;
-};
-SbmlParameter.prototype.getName = function () {
-  return this._name;
-};
-
-SbmlParameter.prototype.setId = function (id) {
-  this._id = id;
-};
-SbmlParameter.prototype.getId = function () {
-  return this._id;
-};
-
-
-module.exports = SbmlParameter;
+"use strict";
+
+function SbmlParameter(jsonObject) {
+  var self = this;
+  self.setParameterId(jsonObject.parameterId);
+  self.setValue(jsonObject.value);
+  self.setGlobal(jsonObject.global);
+  self.setName(jsonObject.name);
+  self.setId(jsonObject.id);
+  self.setUnitsId(jsonObject.unitsId);
+}
+
+SbmlParameter.prototype.setParameterId = function (parameterId) {
+  this._parameterId = parameterId;
+};
+SbmlParameter.prototype.getParameterId = function () {
+  return this._parameterId;
+};
+
+SbmlParameter.prototype.setUnitsId = function (unitsId) {
+  this._unitsId = unitsId;
+};
+SbmlParameter.prototype.getUnitsId = function () {
+  return this._unitsId;
+};
+
+SbmlParameter.prototype.setValue = function (value) {
+  this._value = value;
+};
+SbmlParameter.prototype.getValue = function () {
+  return this._value;
+};
+
+SbmlParameter.prototype.setGlobal = function (global) {
+  this._global = global;
+};
+SbmlParameter.prototype.getGlobal = function () {
+  return this._global;
+};
+
+SbmlParameter.prototype.setName = function (name) {
+  this._name = name;
+};
+SbmlParameter.prototype.getName = function () {
+  return this._name;
+};
+
+SbmlParameter.prototype.setId = function (id) {
+  this._id = id;
+};
+SbmlParameter.prototype.getId = function () {
+  return this._id;
+};
+
+
+module.exports = SbmlParameter;
diff --git a/frontend-js/src/main/js/map/data/SearchBioEntityGroup.js b/frontend-js/src/main/js/map/data/SearchBioEntityGroup.js
index 16e07a3fe3d759e763ed2b449944a8e7fd57e0ac..a7ce5c1c9c20fc33853d414bcc19a0a77f1ee6c1 100644
--- a/frontend-js/src/main/js/map/data/SearchBioEntityGroup.js
+++ b/frontend-js/src/main/js/map/data/SearchBioEntityGroup.js
@@ -1,227 +1,227 @@
-"use strict";
-
-var Alias = require("./Alias");
-var BioEntity = require("./BioEntity");
-var Reaction = require("./Reaction");
-
-// noinspection JSUnusedLocalSymbols
-var logger = require('../../logger');
-
-/**
- * Class representing merged search bioEntities.
- *
- * @param bioEntity
- *          initial bioEntity from which group is created
- */
-function SearchBioEntityGroup(bioEntity) {
-  if (!(bioEntity instanceof BioEntity)) {
-    throw new Error("Invalid argument");
-  }
-  this._bioEntites = [bioEntity];
-}
-
-SearchBioEntityGroup.prototype.bioEntityMatch = function (newBioEntity) {
-  var result = true;
-  var self = this;
-
-  for (var i = 0; i < self._bioEntites.length; i++) {
-    var bioEntity = self._bioEntites[i];
-    if (self.bioEntityComparator(bioEntity, newBioEntity) !== 0) {
-      result = false;
-    }
-  }
-  return result;
-};
-
-SearchBioEntityGroup.prototype.addBioEntity = function (newBioEntity) {
-  this._bioEntites.push(newBioEntity);
-};
-
-SearchBioEntityGroup.prototype.getBioEntities = function () {
-  return this._bioEntites;
-};
-
-SearchBioEntityGroup.prototype.bioEntityComparator = function (bioEntity1, bioEntity2) {
-  if (bioEntity1 instanceof Alias && bioEntity2 instanceof Alias) {
-    if (bioEntity1.getName() !== bioEntity2.getName()) {
-      return -1;
-    }
-    if (bioEntity1.getModelId() !== bioEntity2.getModelId()) {
-      return -2;
-    }
-    if (bioEntity1.getCompartmentId() !== bioEntity2.getCompartmentId()) {
-      return -3;
-    }
-    if (bioEntity1.getType() !== bioEntity2.getType()) {
-      return -4;
-    }
-    if (bioEntity1.getOther("structuralState") !== bioEntity2.getOther("structuralState")) {
-      return -5;
-    }
-
-    var computeSerializedModifications = function (modifications) {
-      if (modifications === undefined) {
-        return [];
-      }
-      var result = [];
-      for (var i = 0; i < modifications.length; i++) {
-        var modification = modifications[i];
-        result.push(modification.name + "_" + modification.state);
-      }
-      result.sort();
-      return result;
-    };
-    var serializedModifications1 = computeSerializedModifications(bioEntity1.getOther("modifications"));
-    var serializedModifications2 = computeSerializedModifications(bioEntity2.getOther("modifications"));
-    if (serializedModifications1.length !== serializedModifications2.length) {
-      return -6;
-    }
-    for (var i = 0; i < serializedModifications1.length; i++) {
-      if (serializedModifications1[i] !== serializedModifications2[i]) {
-        return -7;
-      }
-    }
-    return 0;
-  }
-  if (bioEntity1 instanceof Reaction && bioEntity2 instanceof Reaction) {
-    if (bioEntity1.getId() !== bioEntity2.getId()) {
-      return -8;
-    }
-    return 0;
-  }
-  return -9;
-};
-
-SearchBioEntityGroup.prototype.setIcon = function (icon) {
-  this._icon = icon;
-};
-
-SearchBioEntityGroup.prototype.getIcon = function () {
-  return this._icon;
-};
-
-//aggregated data
-SearchBioEntityGroup.prototype.getType = function () {
-  return this._bioEntites[0].getType();
-};
-
-SearchBioEntityGroup.prototype.getName = function () {
-  return this._bioEntites[0].getName();
-};
-
-SearchBioEntityGroup.prototype.getModelId = function () {
-  return this._bioEntites[0].getModelId();
-};
-
-SearchBioEntityGroup.prototype.getCompartmentId = function () {
-  return this._bioEntites[0].getCompartmentId();
-};
-
-SearchBioEntityGroup.prototype.getReactants = function () {
-  return this._bioEntites[0].getReactants();
-};
-SearchBioEntityGroup.prototype.getProducts = function () {
-  return this._bioEntites[0].getProducts();
-};
-SearchBioEntityGroup.prototype.getModifiers = function () {
-  return this._bioEntites[0].getModifiers();
-};
-
-SearchBioEntityGroup.prototype.getFullName = function () {
-  return this.getMergedParameterByFunction("getFullName");
-};
-
-SearchBioEntityGroup.prototype.getReactionId = function () {
-  return this.getMergedParameterByFunction("getReactionId");
-};
-SearchBioEntityGroup.prototype.getLinkedSubmodelId = function () {
-  return this.getMergedParameterByFunction("getLinkedSubmodelId");
-};
-SearchBioEntityGroup.prototype.getSymbol = function () {
-  return this.getMergedParameterByFunction("getSymbol");
-};
-SearchBioEntityGroup.prototype.getAbbreviation = function () {
-  return this.getMergedParameterByFunction("getAbbreviation");
-};
-SearchBioEntityGroup.prototype.getFormula = function () {
-  return this.getMergedParameterByFunction("getFormula");
-};
-SearchBioEntityGroup.prototype.getMechanicalConfidenceScore = function () {
-  return this.getMergedParameterByFunction("getMechanicalConfidenceScore");
-};
-SearchBioEntityGroup.prototype.getLowerBound = function () {
-  return this.getMergedParameterByFunction("getLowerBound");
-};
-SearchBioEntityGroup.prototype.getUpperBound = function () {
-  return this.getMergedParameterByFunction("getUpperBound");
-};
-SearchBioEntityGroup.prototype.getGeneProteinReaction = function () {
-  return this.getMergedParameterByFunction("getGeneProteinReaction");
-};
-SearchBioEntityGroup.prototype.getSubsystem = function () {
-  return this.getMergedParameterByFunction("getSubsystem");
-};
-SearchBioEntityGroup.prototype.getDescription = function () {
-  return this.getMergedParameterByFunction("getDescription");
-};
-SearchBioEntityGroup.prototype.getCharge = function () {
-  return this.getMergedParameterByFunction("getCharge");
-};
-SearchBioEntityGroup.prototype.getSynonyms = function () {
-  return this.getIntersectionListByFunction("getSynonyms");
-};
-SearchBioEntityGroup.prototype.getFormerSymbols = function () {
-  return this.getIntersectionListByFunction("getFormerSymbols");
-};
-
-SearchBioEntityGroup.prototype.getReferences = function () {
-  return this.getIntersectionListByFunction("getReferences");
-};
-
-SearchBioEntityGroup.prototype.getOther = function (param) {
-  if (param === "modifications") {
-    return this.getIntersectionListByFunction(function (alias) {
-      return alias.getOther(param)
-    });
-  } else {
-    throw new Error("Don't now how to handle: " + param);
-  }
-};
-
-SearchBioEntityGroup.prototype.getMergedParameterByFunction = function (functionName) {
-  var bioEntities = this.getBioEntities();
-  var result = bioEntities[0][functionName]();
-  for (var i = 1; i < bioEntities.length; i++) {
-    var newEntry = bioEntities[i][functionName]();
-    if (newEntry !== result) {
-      result = "Value different among merged elements";
-    }
-  }
-  return result;
-};
-
-SearchBioEntityGroup.prototype.getIntersectionListByFunction = function (functionName) {
-  var bioEntities = this.getBioEntities();
-  var result;
-  if (typeof functionName === "function") {
-    result = functionName(bioEntities[0]);
-  } else {
-    result = bioEntities[0][functionName]();
-  }
-  for (var i = 1; i < bioEntities.length; i++) {
-    var newList;
-    if (typeof functionName === "function") {
-      newList = functionName(bioEntities[i]);
-    } else {
-      newList = bioEntities[0][functionName]();
-    }
-    //intersection of two arrays
-    result = result.filter(function (n) {
-      return newList.indexOf(n) !== -1;
-    });
-  }
-  return result;
-};
-
-
-module.exports = SearchBioEntityGroup;
+"use strict";
+
+var Alias = require("./Alias");
+var BioEntity = require("./BioEntity");
+var Reaction = require("./Reaction");
+
+// noinspection JSUnusedLocalSymbols
+var logger = require('../../logger');
+
+/**
+ * Class representing merged search bioEntities.
+ *
+ * @param bioEntity
+ *          initial bioEntity from which group is created
+ */
+function SearchBioEntityGroup(bioEntity) {
+  if (!(bioEntity instanceof BioEntity)) {
+    throw new Error("Invalid argument");
+  }
+  this._bioEntites = [bioEntity];
+}
+
+SearchBioEntityGroup.prototype.bioEntityMatch = function (newBioEntity) {
+  var result = true;
+  var self = this;
+
+  for (var i = 0; i < self._bioEntites.length; i++) {
+    var bioEntity = self._bioEntites[i];
+    if (self.bioEntityComparator(bioEntity, newBioEntity) !== 0) {
+      result = false;
+    }
+  }
+  return result;
+};
+
+SearchBioEntityGroup.prototype.addBioEntity = function (newBioEntity) {
+  this._bioEntites.push(newBioEntity);
+};
+
+SearchBioEntityGroup.prototype.getBioEntities = function () {
+  return this._bioEntites;
+};
+
+SearchBioEntityGroup.prototype.bioEntityComparator = function (bioEntity1, bioEntity2) {
+  if (bioEntity1 instanceof Alias && bioEntity2 instanceof Alias) {
+    if (bioEntity1.getName() !== bioEntity2.getName()) {
+      return -1;
+    }
+    if (bioEntity1.getModelId() !== bioEntity2.getModelId()) {
+      return -2;
+    }
+    if (bioEntity1.getCompartmentId() !== bioEntity2.getCompartmentId()) {
+      return -3;
+    }
+    if (bioEntity1.getType() !== bioEntity2.getType()) {
+      return -4;
+    }
+    if (bioEntity1.getOther("structuralState") !== bioEntity2.getOther("structuralState")) {
+      return -5;
+    }
+
+    var computeSerializedModifications = function (modifications) {
+      if (modifications === undefined) {
+        return [];
+      }
+      var result = [];
+      for (var i = 0; i < modifications.length; i++) {
+        var modification = modifications[i];
+        result.push(modification.name + "_" + modification.state);
+      }
+      result.sort();
+      return result;
+    };
+    var serializedModifications1 = computeSerializedModifications(bioEntity1.getOther("modifications"));
+    var serializedModifications2 = computeSerializedModifications(bioEntity2.getOther("modifications"));
+    if (serializedModifications1.length !== serializedModifications2.length) {
+      return -6;
+    }
+    for (var i = 0; i < serializedModifications1.length; i++) {
+      if (serializedModifications1[i] !== serializedModifications2[i]) {
+        return -7;
+      }
+    }
+    return 0;
+  }
+  if (bioEntity1 instanceof Reaction && bioEntity2 instanceof Reaction) {
+    if (bioEntity1.getId() !== bioEntity2.getId()) {
+      return -8;
+    }
+    return 0;
+  }
+  return -9;
+};
+
+SearchBioEntityGroup.prototype.setIcon = function (icon) {
+  this._icon = icon;
+};
+
+SearchBioEntityGroup.prototype.getIcon = function () {
+  return this._icon;
+};
+
+//aggregated data
+SearchBioEntityGroup.prototype.getType = function () {
+  return this._bioEntites[0].getType();
+};
+
+SearchBioEntityGroup.prototype.getName = function () {
+  return this._bioEntites[0].getName();
+};
+
+SearchBioEntityGroup.prototype.getModelId = function () {
+  return this._bioEntites[0].getModelId();
+};
+
+SearchBioEntityGroup.prototype.getCompartmentId = function () {
+  return this._bioEntites[0].getCompartmentId();
+};
+
+SearchBioEntityGroup.prototype.getReactants = function () {
+  return this._bioEntites[0].getReactants();
+};
+SearchBioEntityGroup.prototype.getProducts = function () {
+  return this._bioEntites[0].getProducts();
+};
+SearchBioEntityGroup.prototype.getModifiers = function () {
+  return this._bioEntites[0].getModifiers();
+};
+
+SearchBioEntityGroup.prototype.getFullName = function () {
+  return this.getMergedParameterByFunction("getFullName");
+};
+
+SearchBioEntityGroup.prototype.getReactionId = function () {
+  return this.getMergedParameterByFunction("getReactionId");
+};
+SearchBioEntityGroup.prototype.getLinkedSubmodelId = function () {
+  return this.getMergedParameterByFunction("getLinkedSubmodelId");
+};
+SearchBioEntityGroup.prototype.getSymbol = function () {
+  return this.getMergedParameterByFunction("getSymbol");
+};
+SearchBioEntityGroup.prototype.getAbbreviation = function () {
+  return this.getMergedParameterByFunction("getAbbreviation");
+};
+SearchBioEntityGroup.prototype.getFormula = function () {
+  return this.getMergedParameterByFunction("getFormula");
+};
+SearchBioEntityGroup.prototype.getMechanicalConfidenceScore = function () {
+  return this.getMergedParameterByFunction("getMechanicalConfidenceScore");
+};
+SearchBioEntityGroup.prototype.getLowerBound = function () {
+  return this.getMergedParameterByFunction("getLowerBound");
+};
+SearchBioEntityGroup.prototype.getUpperBound = function () {
+  return this.getMergedParameterByFunction("getUpperBound");
+};
+SearchBioEntityGroup.prototype.getGeneProteinReaction = function () {
+  return this.getMergedParameterByFunction("getGeneProteinReaction");
+};
+SearchBioEntityGroup.prototype.getSubsystem = function () {
+  return this.getMergedParameterByFunction("getSubsystem");
+};
+SearchBioEntityGroup.prototype.getDescription = function () {
+  return this.getMergedParameterByFunction("getDescription");
+};
+SearchBioEntityGroup.prototype.getCharge = function () {
+  return this.getMergedParameterByFunction("getCharge");
+};
+SearchBioEntityGroup.prototype.getSynonyms = function () {
+  return this.getIntersectionListByFunction("getSynonyms");
+};
+SearchBioEntityGroup.prototype.getFormerSymbols = function () {
+  return this.getIntersectionListByFunction("getFormerSymbols");
+};
+
+SearchBioEntityGroup.prototype.getReferences = function () {
+  return this.getIntersectionListByFunction("getReferences");
+};
+
+SearchBioEntityGroup.prototype.getOther = function (param) {
+  if (param === "modifications") {
+    return this.getIntersectionListByFunction(function (alias) {
+      return alias.getOther(param)
+    });
+  } else {
+    throw new Error("Don't now how to handle: " + param);
+  }
+};
+
+SearchBioEntityGroup.prototype.getMergedParameterByFunction = function (functionName) {
+  var bioEntities = this.getBioEntities();
+  var result = bioEntities[0][functionName]();
+  for (var i = 1; i < bioEntities.length; i++) {
+    var newEntry = bioEntities[i][functionName]();
+    if (newEntry !== result) {
+      result = "Value different among merged elements";
+    }
+  }
+  return result;
+};
+
+SearchBioEntityGroup.prototype.getIntersectionListByFunction = function (functionName) {
+  var bioEntities = this.getBioEntities();
+  var result;
+  if (typeof functionName === "function") {
+    result = functionName(bioEntities[0]);
+  } else {
+    result = bioEntities[0][functionName]();
+  }
+  for (var i = 1; i < bioEntities.length; i++) {
+    var newList;
+    if (typeof functionName === "function") {
+      newList = functionName(bioEntities[i]);
+    } else {
+      newList = bioEntities[0][functionName]();
+    }
+    //intersection of two arrays
+    result = result.filter(function (n) {
+      return newList.indexOf(n) !== -1;
+    });
+  }
+  return result;
+};
+
+
+module.exports = SearchBioEntityGroup;
diff --git a/frontend-js/src/main/js/map/data/Target.js b/frontend-js/src/main/js/map/data/Target.js
index d35c1731eb30095f3743171b7732f7e2a15c0cd0..08e5f713038ef7d5ae87b38b6a6a60db770a830b 100644
--- a/frontend-js/src/main/js/map/data/Target.js
+++ b/frontend-js/src/main/js/map/data/Target.js
@@ -1,67 +1,67 @@
-"use strict";
-
-/* exported logger */
-
-var Annotation = require("./Annotation");
-var IdentifiedElement = require('./IdentifiedElement');
-
-var logger = require('../../logger');
-
-function Target(javaObject) {
-  this.setName(javaObject.name);
-  this.setTargetElements(javaObject.targetElements);
-  this.setTargetParticipants(javaObject.targetParticipants);
-  this.setReferences(javaObject.references);
-}
-
-Target.prototype.setTargetElements = function(targetElements) {
-  this._targetElements = [];
-  for (var i = 0; i < targetElements.length; i++) {
-    this._targetElements.push(new IdentifiedElement(targetElements[i]));
-  }
-  this.setIsVisible(this._targetElements.length > 0);
-};
-
-Target.prototype.getTargetElements = function() {
-  return this._targetElements;
-};
-
-Target.prototype.setTargetParticipants = function(targetParticipants) {
-  this._targetParticipants = [];
-  for (var i = 0; i < targetParticipants.length; i++) {
-    this._targetParticipants.push(new Annotation(targetParticipants[i]));
-  }
-};
-
-Target.prototype.getTargetParticipants = function() {
-  return this._targetParticipants;
-};
-
-Target.prototype.setName = function(name) {
-  this._name = name;
-};
-
-Target.prototype.getName = function() {
-  return this._name;
-};
-
-Target.prototype.setIsVisible = function(visible) {
-  this._isVisible = visible;
-};
-
-Target.prototype.isVisible = function() {
-  return this._isVisible;
-};
-
-Target.prototype.setReferences = function(references) {
-  this._references = [];
-  for (var i = 0; i < references.length; i++) {
-    this._references.push(new Annotation(references[i]));
-  }
-};
-
-Target.prototype.getReferences = function() {
-  return this._references;
-};
-
-module.exports = Target;
+"use strict";
+
+/* exported logger */
+
+var Annotation = require("./Annotation");
+var IdentifiedElement = require('./IdentifiedElement');
+
+var logger = require('../../logger');
+
+function Target(javaObject) {
+  this.setName(javaObject.name);
+  this.setTargetElements(javaObject.targetElements);
+  this.setTargetParticipants(javaObject.targetParticipants);
+  this.setReferences(javaObject.references);
+}
+
+Target.prototype.setTargetElements = function(targetElements) {
+  this._targetElements = [];
+  for (var i = 0; i < targetElements.length; i++) {
+    this._targetElements.push(new IdentifiedElement(targetElements[i]));
+  }
+  this.setIsVisible(this._targetElements.length > 0);
+};
+
+Target.prototype.getTargetElements = function() {
+  return this._targetElements;
+};
+
+Target.prototype.setTargetParticipants = function(targetParticipants) {
+  this._targetParticipants = [];
+  for (var i = 0; i < targetParticipants.length; i++) {
+    this._targetParticipants.push(new Annotation(targetParticipants[i]));
+  }
+};
+
+Target.prototype.getTargetParticipants = function() {
+  return this._targetParticipants;
+};
+
+Target.prototype.setName = function(name) {
+  this._name = name;
+};
+
+Target.prototype.getName = function() {
+  return this._name;
+};
+
+Target.prototype.setIsVisible = function(visible) {
+  this._isVisible = visible;
+};
+
+Target.prototype.isVisible = function() {
+  return this._isVisible;
+};
+
+Target.prototype.setReferences = function(references) {
+  this._references = [];
+  for (var i = 0; i < references.length; i++) {
+    this._references.push(new Annotation(references[i]));
+  }
+};
+
+Target.prototype.getReferences = function() {
+  return this._references;
+};
+
+module.exports = Target;
diff --git a/frontend-js/src/main/js/map/data/TargettingStructure.js b/frontend-js/src/main/js/map/data/TargettingStructure.js
index d36d2288d4c41380c3655c36b395bd252b356434..b35a23713cf33b03fc45246791a2184710ecbeaa 100644
--- a/frontend-js/src/main/js/map/data/TargettingStructure.js
+++ b/frontend-js/src/main/js/map/data/TargettingStructure.js
@@ -1,60 +1,60 @@
-"use strict";
-
-/* exported logger */
-
-var Target = require("./Target");
-
-var logger = require('../../logger');
-
-function TargettingStructure(javaObject) {
-  if (javaObject !== undefined) {
-    this.setName(javaObject.name);
-    this.setId(javaObject.id);
-    this.setTargets(javaObject.targets);
-  }
-}
-
-TargettingStructure.prototype.setName = function(name) {
-  this._name = name;
-};
-
-TargettingStructure.prototype.getName = function() {
-  return this._name;
-};
-
-TargettingStructure.prototype.setId = function(id) {
-  this._id = id;
-};
-
-TargettingStructure.prototype.getId = function() {
-  return this._id;
-};
-
-TargettingStructure.prototype.setTargets = function(targets) {
-  this._targets = [];
-  for (var i = 0; i < targets.length; i++) {
-    this._targets.push(new Target(targets[i]));
-  }
-};
-
-TargettingStructure.prototype.getTargets = function() {
-  return this._targets;
-};
-
-TargettingStructure.prototype.getTargetsForIdentifiedElement = function(targetIdentifiedElement) {
-  var result = [];
-  this.getTargets().forEach(function(target) {
-    var targetOk = false;
-    target.getTargetElements().forEach(function(identifiedElement){
-      if (targetIdentifiedElement.equals(identifiedElement)) {
-        targetOk = true;
-      }
-    });
-    if (targetOk) {
-      result.push(target);
-    }
-  });
-  return result;
-};
-
-module.exports = TargettingStructure;
+"use strict";
+
+/* exported logger */
+
+var Target = require("./Target");
+
+var logger = require('../../logger');
+
+function TargettingStructure(javaObject) {
+  if (javaObject !== undefined) {
+    this.setName(javaObject.name);
+    this.setId(javaObject.id);
+    this.setTargets(javaObject.targets);
+  }
+}
+
+TargettingStructure.prototype.setName = function(name) {
+  this._name = name;
+};
+
+TargettingStructure.prototype.getName = function() {
+  return this._name;
+};
+
+TargettingStructure.prototype.setId = function(id) {
+  this._id = id;
+};
+
+TargettingStructure.prototype.getId = function() {
+  return this._id;
+};
+
+TargettingStructure.prototype.setTargets = function(targets) {
+  this._targets = [];
+  for (var i = 0; i < targets.length; i++) {
+    this._targets.push(new Target(targets[i]));
+  }
+};
+
+TargettingStructure.prototype.getTargets = function() {
+  return this._targets;
+};
+
+TargettingStructure.prototype.getTargetsForIdentifiedElement = function(targetIdentifiedElement) {
+  var result = [];
+  this.getTargets().forEach(function(target) {
+    var targetOk = false;
+    target.getTargetElements().forEach(function(identifiedElement){
+      if (targetIdentifiedElement.equals(identifiedElement)) {
+        targetOk = true;
+      }
+    });
+    if (targetOk) {
+      result.push(target);
+    }
+  });
+  return result;
+};
+
+module.exports = TargettingStructure;
diff --git a/frontend-js/src/main/js/map/data/User.js b/frontend-js/src/main/js/map/data/User.js
index 8c129f086c3f34238fc1b46169f8458b21b4398d..d0befc57c8f7cb0305724f860df026726b8d9d68 100644
--- a/frontend-js/src/main/js/map/data/User.js
+++ b/frontend-js/src/main/js/map/data/User.js
@@ -1,403 +1,403 @@
-"use strict";
-
-/* exported logger */
-
-// noinspection JSUnusedLocalSymbols
-var logger = require('../../logger');
-
-var UserPreferences = require('./UserPreferences');
-var ObjectWithListeners = require('../../ObjectWithListeners');
-
-/**
- *
- * @param javaObject
- * @constructor
- */
-function User(javaObject) {
-  // call super constructor
-  ObjectWithListeners.call(this);
-
-  this.registerListenerType("onreload");
-
-  this.setLogin(javaObject.login);
-  this.setName(javaObject.name);
-  this.setSurname(javaObject.surname);
-  this.setEmail(javaObject.email);
-  this.setRemoved(javaObject.removed);
-  this.setPrivileges(javaObject.privileges);
-  this.setPreferences(javaObject.preferences);
-  this.setMinColor(javaObject.minColor);
-  this.setMaxColor(javaObject.maxColor);
-  this.setNeutralColor(javaObject.neutralColor);
-  this.setSimpleColor(javaObject.simpleColor);
-  this.setTermsOfUseConsent(javaObject.termsOfUseConsent);
-  this.setLdapAccountAvailable(javaObject.ldapAccountAvailable);
-  this.setConnectedToLdap(javaObject.connectedToLdap);
-}
-
-// this class inherits from ObjectWithListeners class where generic methods for
-// listeners are set
-User.prototype = Object.create(ObjectWithListeners.prototype);
-User.prototype.constructor = User;
-
-/**
- *
- * @param {string} login
- */
-User.prototype.setLogin = function (login) {
-  this._login = login;
-};
-
-/**
- *
- * @returns {string}
- */
-User.prototype.getLogin = function () {
-  return this._login;
-};
-
-/**
- *
- * @param {string} name
- */
-User.prototype.setName = function (name) {
-  this._name = name;
-};
-
-/**
- *
- * @returns {string}
- */
-User.prototype.getName = function () {
-  return this._name;
-};
-
-/**
- *
- * @param {string} surname
- */
-User.prototype.setSurname = function (surname) {
-  this._surname = surname;
-};
-
-/**
- *
- * @returns {string}
- */
-User.prototype.getSurname = function () {
-  return this._surname;
-};
-
-/**
- *
- * @param {string} email
- */
-User.prototype.setEmail = function (email) {
-  this._email = email;
-};
-
-/**
- *
- * @returns {string}
- */
-User.prototype.getEmail = function () {
-  return this._email;
-};
-
-/**
- *
- * @param {boolean} removed
- */
-User.prototype.setRemoved = function (removed) {
-  this._removed = removed;
-};
-
-/**
- *
- * @returns {boolean}
- */
-User.prototype.getRemoved = function () {
-  return this._removed;
-};
-
-/**
- *
- * @param {string} minColor
- */
-User.prototype.setMinColor = function (minColor) {
-  this._minColor = minColor;
-};
-
-/**
- *
- * @returns {string}
- */
-User.prototype.getMinColor = function () {
-  return this._minColor;
-};
-
-/**
- *
- * @param {string} simpleColor
- */
-User.prototype.setSimpleColor = function (simpleColor) {
-  this._simpleColor = simpleColor;
-};
-
-/**
- *
- * @returns {string}
- */
-User.prototype.getSimpleColor = function () {
-  return this._simpleColor;
-};
-
-/**
- *
- * @param {string} neutralColor
- */
-User.prototype.setNeutralColor = function (neutralColor) {
-  this._neutralColor = neutralColor;
-};
-
-/**
- *
- * @returns {string}
- */
-User.prototype.getNeutralColor = function () {
-  return this._neutralColor;
-};
-
-/**
- *
- * @param {string} maxColor
- */
-User.prototype.setMaxColor = function (maxColor) {
-  this._maxColor = maxColor;
-};
-
-/**
- *
- * @returns {string}
- */
-User.prototype.getMaxColor = function () {
-  return this._maxColor;
-};
-
-/**
- *
- * @param {string} password
- */
-User.prototype.setPassword = function (password) {
-  this._password = password;
-};
-
-/**
- *
- * @returns {string}
- */
-User.prototype.getPassword = function () {
-  return this._password;
-};
-
-/**
- *
- * @param {Object[]} privileges
- */
-User.prototype.setPrivileges = function (privileges) {
-  this._privileges = privileges;
-  if (this._privileges === undefined) {
-    this._privileges = [];
-  }
-};
-
-/**
- *
- * @returns {Array}
- */
-User.prototype.getPrivileges = function () {
-  return this._privileges;
-};
-
-/**
- *
- * @param {UserPreferences|Object} preferences
- */
-User.prototype.setPreferences = function (preferences) {
-  if (!(preferences instanceof UserPreferences)) {
-    preferences = new UserPreferences(preferences);
-  }
-  this._preferences = preferences;
-};
-
-/**
- *
- * @returns {UserPreferences}
- */
-User.prototype.getPreferences = function () {
-  return this._preferences;
-};
-
-/**
- *
- * @param {PrivilegeType} type
- * @param {number} [objectId]
- * @returns {boolean}
- */
-User.prototype.hasPrivilege = function (type, objectId) {
-  return this.getPrivilegeValue(type, objectId) > 0;
-};
-
-/**
- *
- * @param {Object} params
- * @param {number} params.objectId
- * @param {PrivilegeType} params.type
- * @param {number} [params.value=1]
- */
-User.prototype.setPrivilege = function (params) {
-  var objectId = params.objectId;
-  var type = params.type;
-  var value = params.value;
-  if (value === undefined) {
-    value = 1;
-  } else if (value === true) {
-    value = 1;
-  } else if (value === false) {
-    value = 0;
-  }
-  for (var i = 0; i < this._privileges.length; i++) {
-    var privilege = this._privileges[i];
-    if (privilege.type === type.getName()) {
-      if (objectId === privilege.objectId) {
-        privilege.value = value;
-        return;
-      }
-    }
-  }
-  this._privileges.push({
-    type: type.getName(),
-    value: value,
-    objectId: objectId
-  });
-};
-
-/**
- *
- * @param {PrivilegeType} type
- * @param {number} [objectId]
- *
- * @returns {number}
- */
-User.prototype.getPrivilegeValue = function (type, objectId) {
-  for (var i = 0; i < this._privileges.length; i++) {
-    var privilege = this._privileges[i];
-    if (privilege.type === type.getName()) {
-      if (objectId === privilege.objectId) {
-        return privilege.value;
-      }
-    }
-  }
-  return 0;
-};
-
-/**
- *
- * @param {Configuration} configuration
- *
- * @returns {Object}
- */
-User.prototype.privilegesToExport = function (configuration) {
-  var self = this;
-  var result = {};
-  var validTypes = {};
-  var i;
-  for (i = 0; i < configuration.getPrivilegeTypes().length; i++) {
-    validTypes[configuration.getPrivilegeTypes()[i].getName()] = true;
-  }
-  for (i = 0; i < self.getPrivileges().length; i++) {
-    var privilege = self.getPrivileges()[i];
-    if (validTypes[privilege.type]) {
-      if (result[privilege.type] === undefined) {
-        result[privilege.type] = {};
-      }
-      if (privilege.objectId !== undefined) {
-        result[privilege.type][privilege.objectId] = privilege.value;
-      } else {
-        result[privilege.type] = privilege.value;
-      }
-    }
-  }
-  return result;
-};
-
-/**
- *
- * @param {User} user
- * @returns {PromiseLike}
- */
-User.prototype.update = function (user) {
-  var self = this;
-  self.setLogin(user.getLogin());
-  self.setName(user.getName());
-  self.setSurname(user.getSurname());
-  self.setEmail(user.getEmail());
-  self.setRemoved(user.getRemoved());
-  self.setPrivileges(user.getPrivileges());
-  self.getPreferences().update(user.getPreferences());
-  self.setMinColor(user.getMinColor());
-  self.setMaxColor(user.getMaxColor());
-  self.setSimpleColor(user.getSimpleColor());
-
-  return self.callListeners("onreload");
-};
-
-/**
- *
- * @param {boolean} termsOfUseConsent
- */
-User.prototype.setTermsOfUseConsent = function (termsOfUseConsent) {
-  this._termsOfUseConsent = termsOfUseConsent;
-};
-
-/**
- *
- * @returns {boolean}
- */
-User.prototype.isTermsOfUseConsent = function () {
-  return this._termsOfUseConsent;
-};
-
-/**
- *
- * @param {boolean} ldapAccountAvailable
- */
-User.prototype.setLdapAccountAvailable = function (ldapAccountAvailable) {
-  this._ldapAccountAvailable = ldapAccountAvailable;
-};
-
-/**
- *
- * @returns {boolean}
- */
-User.prototype.isLdapAccountAvailable = function () {
-  return this._ldapAccountAvailable;
-};
-
-/**
- *
- * @param {boolean} connectedToLdap
- */
-User.prototype.setConnectedToLdap = function (connectedToLdap) {
-  this._connectedToLdap = connectedToLdap;
-};
-
-/**
- *
- * @returns {boolean}
- */
-User.prototype.isConnectedToLdap = function () {
-  return this._connectedToLdap;
-};
-
-module.exports = User;
+"use strict";
+
+/* exported logger */
+
+// noinspection JSUnusedLocalSymbols
+var logger = require('../../logger');
+
+var UserPreferences = require('./UserPreferences');
+var ObjectWithListeners = require('../../ObjectWithListeners');
+
+/**
+ *
+ * @param javaObject
+ * @constructor
+ */
+function User(javaObject) {
+  // call super constructor
+  ObjectWithListeners.call(this);
+
+  this.registerListenerType("onreload");
+
+  this.setLogin(javaObject.login);
+  this.setName(javaObject.name);
+  this.setSurname(javaObject.surname);
+  this.setEmail(javaObject.email);
+  this.setRemoved(javaObject.removed);
+  this.setPrivileges(javaObject.privileges);
+  this.setPreferences(javaObject.preferences);
+  this.setMinColor(javaObject.minColor);
+  this.setMaxColor(javaObject.maxColor);
+  this.setNeutralColor(javaObject.neutralColor);
+  this.setSimpleColor(javaObject.simpleColor);
+  this.setTermsOfUseConsent(javaObject.termsOfUseConsent);
+  this.setLdapAccountAvailable(javaObject.ldapAccountAvailable);
+  this.setConnectedToLdap(javaObject.connectedToLdap);
+}
+
+// this class inherits from ObjectWithListeners class where generic methods for
+// listeners are set
+User.prototype = Object.create(ObjectWithListeners.prototype);
+User.prototype.constructor = User;
+
+/**
+ *
+ * @param {string} login
+ */
+User.prototype.setLogin = function (login) {
+  this._login = login;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+User.prototype.getLogin = function () {
+  return this._login;
+};
+
+/**
+ *
+ * @param {string} name
+ */
+User.prototype.setName = function (name) {
+  this._name = name;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+User.prototype.getName = function () {
+  return this._name;
+};
+
+/**
+ *
+ * @param {string} surname
+ */
+User.prototype.setSurname = function (surname) {
+  this._surname = surname;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+User.prototype.getSurname = function () {
+  return this._surname;
+};
+
+/**
+ *
+ * @param {string} email
+ */
+User.prototype.setEmail = function (email) {
+  this._email = email;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+User.prototype.getEmail = function () {
+  return this._email;
+};
+
+/**
+ *
+ * @param {boolean} removed
+ */
+User.prototype.setRemoved = function (removed) {
+  this._removed = removed;
+};
+
+/**
+ *
+ * @returns {boolean}
+ */
+User.prototype.getRemoved = function () {
+  return this._removed;
+};
+
+/**
+ *
+ * @param {string} minColor
+ */
+User.prototype.setMinColor = function (minColor) {
+  this._minColor = minColor;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+User.prototype.getMinColor = function () {
+  return this._minColor;
+};
+
+/**
+ *
+ * @param {string} simpleColor
+ */
+User.prototype.setSimpleColor = function (simpleColor) {
+  this._simpleColor = simpleColor;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+User.prototype.getSimpleColor = function () {
+  return this._simpleColor;
+};
+
+/**
+ *
+ * @param {string} neutralColor
+ */
+User.prototype.setNeutralColor = function (neutralColor) {
+  this._neutralColor = neutralColor;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+User.prototype.getNeutralColor = function () {
+  return this._neutralColor;
+};
+
+/**
+ *
+ * @param {string} maxColor
+ */
+User.prototype.setMaxColor = function (maxColor) {
+  this._maxColor = maxColor;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+User.prototype.getMaxColor = function () {
+  return this._maxColor;
+};
+
+/**
+ *
+ * @param {string} password
+ */
+User.prototype.setPassword = function (password) {
+  this._password = password;
+};
+
+/**
+ *
+ * @returns {string}
+ */
+User.prototype.getPassword = function () {
+  return this._password;
+};
+
+/**
+ *
+ * @param {Object[]} privileges
+ */
+User.prototype.setPrivileges = function (privileges) {
+  this._privileges = privileges;
+  if (this._privileges === undefined) {
+    this._privileges = [];
+  }
+};
+
+/**
+ *
+ * @returns {Array}
+ */
+User.prototype.getPrivileges = function () {
+  return this._privileges;
+};
+
+/**
+ *
+ * @param {UserPreferences|Object} preferences
+ */
+User.prototype.setPreferences = function (preferences) {
+  if (!(preferences instanceof UserPreferences)) {
+    preferences = new UserPreferences(preferences);
+  }
+  this._preferences = preferences;
+};
+
+/**
+ *
+ * @returns {UserPreferences}
+ */
+User.prototype.getPreferences = function () {
+  return this._preferences;
+};
+
+/**
+ *
+ * @param {PrivilegeType} type
+ * @param {number} [objectId]
+ * @returns {boolean}
+ */
+User.prototype.hasPrivilege = function (type, objectId) {
+  return this.getPrivilegeValue(type, objectId) > 0;
+};
+
+/**
+ *
+ * @param {Object} params
+ * @param {number} params.objectId
+ * @param {PrivilegeType} params.type
+ * @param {number} [params.value=1]
+ */
+User.prototype.setPrivilege = function (params) {
+  var objectId = params.objectId;
+  var type = params.type;
+  var value = params.value;
+  if (value === undefined) {
+    value = 1;
+  } else if (value === true) {
+    value = 1;
+  } else if (value === false) {
+    value = 0;
+  }
+  for (var i = 0; i < this._privileges.length; i++) {
+    var privilege = this._privileges[i];
+    if (privilege.type === type.getName()) {
+      if (objectId === privilege.objectId) {
+        privilege.value = value;
+        return;
+      }
+    }
+  }
+  this._privileges.push({
+    type: type.getName(),
+    value: value,
+    objectId: objectId
+  });
+};
+
+/**
+ *
+ * @param {PrivilegeType} type
+ * @param {number} [objectId]
+ *
+ * @returns {number}
+ */
+User.prototype.getPrivilegeValue = function (type, objectId) {
+  for (var i = 0; i < this._privileges.length; i++) {
+    var privilege = this._privileges[i];
+    if (privilege.type === type.getName()) {
+      if (objectId === privilege.objectId) {
+        return privilege.value;
+      }
+    }
+  }
+  return 0;
+};
+
+/**
+ *
+ * @param {Configuration} configuration
+ *
+ * @returns {Object}
+ */
+User.prototype.privilegesToExport = function (configuration) {
+  var self = this;
+  var result = {};
+  var validTypes = {};
+  var i;
+  for (i = 0; i < configuration.getPrivilegeTypes().length; i++) {
+    validTypes[configuration.getPrivilegeTypes()[i].getName()] = true;
+  }
+  for (i = 0; i < self.getPrivileges().length; i++) {
+    var privilege = self.getPrivileges()[i];
+    if (validTypes[privilege.type]) {
+      if (result[privilege.type] === undefined) {
+        result[privilege.type] = {};
+      }
+      if (privilege.objectId !== undefined) {
+        result[privilege.type][privilege.objectId] = privilege.value;
+      } else {
+        result[privilege.type] = privilege.value;
+      }
+    }
+  }
+  return result;
+};
+
+/**
+ *
+ * @param {User} user
+ * @returns {PromiseLike}
+ */
+User.prototype.update = function (user) {
+  var self = this;
+  self.setLogin(user.getLogin());
+  self.setName(user.getName());
+  self.setSurname(user.getSurname());
+  self.setEmail(user.getEmail());
+  self.setRemoved(user.getRemoved());
+  self.setPrivileges(user.getPrivileges());
+  self.getPreferences().update(user.getPreferences());
+  self.setMinColor(user.getMinColor());
+  self.setMaxColor(user.getMaxColor());
+  self.setSimpleColor(user.getSimpleColor());
+
+  return self.callListeners("onreload");
+};
+
+/**
+ *
+ * @param {boolean} termsOfUseConsent
+ */
+User.prototype.setTermsOfUseConsent = function (termsOfUseConsent) {
+  this._termsOfUseConsent = termsOfUseConsent;
+};
+
+/**
+ *
+ * @returns {boolean}
+ */
+User.prototype.isTermsOfUseConsent = function () {
+  return this._termsOfUseConsent;
+};
+
+/**
+ *
+ * @param {boolean} ldapAccountAvailable
+ */
+User.prototype.setLdapAccountAvailable = function (ldapAccountAvailable) {
+  this._ldapAccountAvailable = ldapAccountAvailable;
+};
+
+/**
+ *
+ * @returns {boolean}
+ */
+User.prototype.isLdapAccountAvailable = function () {
+  return this._ldapAccountAvailable;
+};
+
+/**
+ *
+ * @param {boolean} connectedToLdap
+ */
+User.prototype.setConnectedToLdap = function (connectedToLdap) {
+  this._connectedToLdap = connectedToLdap;
+};
+
+/**
+ *
+ * @returns {boolean}
+ */
+User.prototype.isConnectedToLdap = function () {
+  return this._connectedToLdap;
+};
+
+module.exports = User;
diff --git a/frontend-js/src/main/js/map/data/UserPreferences.js b/frontend-js/src/main/js/map/data/UserPreferences.js
index a42b804aad16f17f893c01fd6412c0018018d192..6d2fa23a5c1f19fe09420238018e00dd625a14b9 100644
--- a/frontend-js/src/main/js/map/data/UserPreferences.js
+++ b/frontend-js/src/main/js/map/data/UserPreferences.js
@@ -1,176 +1,176 @@
-"use strict";
-
-/* exported logger */
-
-// noinspection JSUnusedLocalSymbols
-var logger = require('../../logger');
-
-function UserPreferences(javaObject) {
-  if (javaObject !== undefined) {
-    this.setProjectUpload(javaObject["project-upload"]);
-    this.setElementAnnotators(javaObject["element-annotators"]);
-    this.setElementRequiredAnnotations(javaObject["element-required-annotations"]);
-    this.setElementValidAnnotations(javaObject["element-valid-annotations"]);
-    this.setAnnotatorsParameters(javaObject["annotators-parameters"]);
-    this.setGuiPreferences(javaObject["gui-preferences"]);
-  } else {
-    this._projectUpload = {};
-    this._elementAnnotators = {};
-    this._elementRequiredAnnotations = {};
-    this._elementValidAnnotations = {};
-    this._annotatorsParameters = {};
-    this._guiPreferences = {};
-  }
-}
-
-UserPreferences.prototype.update = function (userPreferences) {
-  var updateDict = function (originalDict, newDict) {
-    for (var key in newDict) {
-      if (newDict.hasOwnProperty(key)) {
-        originalDict[key] = newDict[key];
-      }
-    }
-  };
-
-  updateDict(this._projectUpload, userPreferences.getProjectUpload());
-  updateDict(this._elementAnnotators, userPreferences.getElementAnnotators);
-  updateDict(this._elementValidAnnotations, userPreferences._elementValidAnnotations);
-  updateDict(this._elementRequiredAnnotations, userPreferences._elementRequiredAnnotations);
-  updateDict(this._annotatorsParameters, userPreferences.getAnnotatorsParameters());
-  updateDict(this._guiPreferences, userPreferences.getGuiPreferences());
-};
-
-UserPreferences.prototype.setProjectUpload = function (projectUpload) {
-  this._projectUpload = {
-    autoResize: projectUpload["auto-resize"],
-    validateMiriam: projectUpload["validate-miriam"],
-    annotateModel: projectUpload["annotate-model"],
-    cacheData: projectUpload["cache-data"],
-    semanticZooming: projectUpload["semantic-zooming"],
-    sbgn: projectUpload["sbgn"]
-  };
-};
-UserPreferences.prototype.getAnnotatorsParameters = function () {
-  return this._annotatorsParameters;
-};
-UserPreferences.prototype.setAnnotatorsParameters = function (annotatorsParameters) {
-  this._annotatorsParameters = annotatorsParameters;
-};
-UserPreferences.prototype.getGuiPreferences = function () {
-  return this._guiPreferences;
-};
-UserPreferences.prototype.setGuiPreference = function (key, value) {
-  this._guiPreferences[key] = value;
-};
-UserPreferences.prototype.getGuiPreference = function (key, defaultValue) {
-  var result = this._guiPreferences[key];
-  if (result === undefined) {
-    result = defaultValue;
-  }
-  return result;
-};
-UserPreferences.prototype.setGuiPreferences = function (guiPreferences) {
-  this._guiPreferences = guiPreferences;
-};
-UserPreferences.prototype.getProjectUpload = function () {
-  return this._projectUpload;
-};
-UserPreferences.prototype.setElementAnnotators = function (elementAnnotators) {
-  this._elementAnnotators = elementAnnotators;
-};
-
-/**
- *
- * @param {string} className
- * @returns {string[]}
- */
-UserPreferences.prototype.getElementAnnotators = function (className) {
-  var result = this._elementAnnotators[className];
-  if (result === undefined) {
-    this._elementAnnotators[className] = [];
-    result = this._elementAnnotators[className];
-  }
-  return result;
-};
-
-/**
- *
- * @param {Object<string, Object>} elementRequiredAnnotations
- */
-UserPreferences.prototype.setElementRequiredAnnotations = function (elementRequiredAnnotations) {
-  this._elementRequiredAnnotations = {};
-  for (var key in elementRequiredAnnotations) {
-    if (elementRequiredAnnotations.hasOwnProperty(key)) {
-      var data = elementRequiredAnnotations[key];
-      this._elementRequiredAnnotations[key] = {
-        requiredAtLeastOnce: data["require-at-least-one"],
-        list: data["annotation-list"]
-      };
-    }
-  }
-};
-
-/**
- *
- * @param {string} className
- * @returns {{list:string[], requiredAtLeastOnce:boolean}}
- */
-UserPreferences.prototype.getElementRequiredAnnotations = function (className) {
-  var result = this._elementRequiredAnnotations[className];
-  if (result === undefined) {
-    result = {list: [], requiredAtLeastOnce: false};
-  }
-  return result;
-};
-
-/**
- *
- * @param {Object<string,string[]>}elementValidAnnotations
- */
-UserPreferences.prototype.setElementValidAnnotations = function (elementValidAnnotations) {
-  this._elementValidAnnotations = elementValidAnnotations;
-};
-
-/**
- *
- * @param {string} className
- * @returns {string[]}
- */
-UserPreferences.prototype.getElementValidAnnotations = function (className) {
-  var result = this._elementValidAnnotations[className];
-  if (result === undefined) {
-    result = [];
-  }
-  return result;
-};
-
-UserPreferences.prototype.toExport = function () {
-  var requiredAnnotations = {};
-  for (var key in this._elementRequiredAnnotations) {
-    if (this._elementRequiredAnnotations.hasOwnProperty(key)) {
-      var data = this._elementRequiredAnnotations[key];
-      requiredAnnotations[key] = {
-        "require-at-least-one": data.requiredAtLeastOnce,
-        "annotation-list": data.list
-      };
-    }
-  }
-
-  return {
-    "project-upload": {
-      "auto-resize": this._projectUpload.autoResize,
-      "validate-miriam": this._projectUpload.validateMiriam,
-      "annotate-model": this._projectUpload.annotateModel,
-      "cache-data": this._projectUpload.cacheData,
-      "sbgn": this._projectUpload.sbgn,
-      "semantic-zooming": this._projectUpload.semanticZooming
-    },
-    "element-annotators": this._elementAnnotators,
-    "element-valid-annotations": this._elementValidAnnotations,
-    "element-required-annotations": requiredAnnotations,
-    "annotators-parameters": this.getAnnotatorsParameters(),
-    "gui-preferences": this.getGuiPreferences()
-  };
-};
-
-module.exports = UserPreferences;
+"use strict";
+
+/* exported logger */
+
+// noinspection JSUnusedLocalSymbols
+var logger = require('../../logger');
+
+function UserPreferences(javaObject) {
+  if (javaObject !== undefined) {
+    this.setProjectUpload(javaObject["project-upload"]);
+    this.setElementAnnotators(javaObject["element-annotators"]);
+    this.setElementRequiredAnnotations(javaObject["element-required-annotations"]);
+    this.setElementValidAnnotations(javaObject["element-valid-annotations"]);
+    this.setAnnotatorsParameters(javaObject["annotators-parameters"]);
+    this.setGuiPreferences(javaObject["gui-preferences"]);
+  } else {
+    this._projectUpload = {};
+    this._elementAnnotators = {};
+    this._elementRequiredAnnotations = {};
+    this._elementValidAnnotations = {};
+    this._annotatorsParameters = {};
+    this._guiPreferences = {};
+  }
+}
+
+UserPreferences.prototype.update = function (userPreferences) {
+  var updateDict = function (originalDict, newDict) {
+    for (var key in newDict) {
+      if (newDict.hasOwnProperty(key)) {
+        originalDict[key] = newDict[key];
+      }
+    }
+  };
+
+  updateDict(this._projectUpload, userPreferences.getProjectUpload());
+  updateDict(this._elementAnnotators, userPreferences.getElementAnnotators);
+  updateDict(this._elementValidAnnotations, userPreferences._elementValidAnnotations);
+  updateDict(this._elementRequiredAnnotations, userPreferences._elementRequiredAnnotations);
+  updateDict(this._annotatorsParameters, userPreferences.getAnnotatorsParameters());
+  updateDict(this._guiPreferences, userPreferences.getGuiPreferences());
+};
+
+UserPreferences.prototype.setProjectUpload = function (projectUpload) {
+  this._projectUpload = {
+    autoResize: projectUpload["auto-resize"],
+    validateMiriam: projectUpload["validate-miriam"],
+    annotateModel: projectUpload["annotate-model"],
+    cacheData: projectUpload["cache-data"],
+    semanticZooming: projectUpload["semantic-zooming"],
+    sbgn: projectUpload["sbgn"]
+  };
+};
+UserPreferences.prototype.getAnnotatorsParameters = function () {
+  return this._annotatorsParameters;
+};
+UserPreferences.prototype.setAnnotatorsParameters = function (annotatorsParameters) {
+  this._annotatorsParameters = annotatorsParameters;
+};
+UserPreferences.prototype.getGuiPreferences = function () {
+  return this._guiPreferences;
+};
+UserPreferences.prototype.setGuiPreference = function (key, value) {
+  this._guiPreferences[key] = value;
+};
+UserPreferences.prototype.getGuiPreference = function (key, defaultValue) {
+  var result = this._guiPreferences[key];
+  if (result === undefined) {
+    result = defaultValue;
+  }
+  return result;
+};
+UserPreferences.prototype.setGuiPreferences = function (guiPreferences) {
+  this._guiPreferences = guiPreferences;
+};
+UserPreferences.prototype.getProjectUpload = function () {
+  return this._projectUpload;
+};
+UserPreferences.prototype.setElementAnnotators = function (elementAnnotators) {
+  this._elementAnnotators = elementAnnotators;
+};
+
+/**
+ *
+ * @param {string} className
+ * @returns {string[]}
+ */
+UserPreferences.prototype.getElementAnnotators = function (className) {
+  var result = this._elementAnnotators[className];
+  if (result === undefined) {
+    this._elementAnnotators[className] = [];
+    result = this._elementAnnotators[className];
+  }
+  return result;
+};
+
+/**
+ *
+ * @param {Object<string, Object>} elementRequiredAnnotations
+ */
+UserPreferences.prototype.setElementRequiredAnnotations = function (elementRequiredAnnotations) {
+  this._elementRequiredAnnotations = {};
+  for (var key in elementRequiredAnnotations) {
+    if (elementRequiredAnnotations.hasOwnProperty(key)) {
+      var data = elementRequiredAnnotations[key];
+      this._elementRequiredAnnotations[key] = {
+        requiredAtLeastOnce: data["require-at-least-one"],
+        list: data["annotation-list"]
+      };
+    }
+  }
+};
+
+/**
+ *
+ * @param {string} className
+ * @returns {{list:string[], requiredAtLeastOnce:boolean}}
+ */
+UserPreferences.prototype.getElementRequiredAnnotations = function (className) {
+  var result = this._elementRequiredAnnotations[className];
+  if (result === undefined) {
+    result = {list: [], requiredAtLeastOnce: false};
+  }
+  return result;
+};
+
+/**
+ *
+ * @param {Object<string,string[]>}elementValidAnnotations
+ */
+UserPreferences.prototype.setElementValidAnnotations = function (elementValidAnnotations) {
+  this._elementValidAnnotations = elementValidAnnotations;
+};
+
+/**
+ *
+ * @param {string} className
+ * @returns {string[]}
+ */
+UserPreferences.prototype.getElementValidAnnotations = function (className) {
+  var result = this._elementValidAnnotations[className];
+  if (result === undefined) {
+    result = [];
+  }
+  return result;
+};
+
+UserPreferences.prototype.toExport = function () {
+  var requiredAnnotations = {};
+  for (var key in this._elementRequiredAnnotations) {
+    if (this._elementRequiredAnnotations.hasOwnProperty(key)) {
+      var data = this._elementRequiredAnnotations[key];
+      requiredAnnotations[key] = {
+        "require-at-least-one": data.requiredAtLeastOnce,
+        "annotation-list": data.list
+      };
+    }
+  }
+
+  return {
+    "project-upload": {
+      "auto-resize": this._projectUpload.autoResize,
+      "validate-miriam": this._projectUpload.validateMiriam,
+      "annotate-model": this._projectUpload.annotateModel,
+      "cache-data": this._projectUpload.cacheData,
+      "sbgn": this._projectUpload.sbgn,
+      "semantic-zooming": this._projectUpload.semanticZooming
+    },
+    "element-annotators": this._elementAnnotators,
+    "element-valid-annotations": this._elementValidAnnotations,
+    "element-required-annotations": requiredAnnotations,
+    "annotators-parameters": this.getAnnotatorsParameters(),
+    "gui-preferences": this.getGuiPreferences()
+  };
+};
+
+module.exports = UserPreferences;
diff --git a/frontend-js/src/main/js/map/marker/AbstractMarker.js b/frontend-js/src/main/js/map/marker/AbstractMarker.js
index 2ea04f698cdc2578d292e6f48f78675a42c2e2f1..5fa0da4a9e490f1844ca2d0537ac8b92fd237219 100644
--- a/frontend-js/src/main/js/map/marker/AbstractMarker.js
+++ b/frontend-js/src/main/js/map/marker/AbstractMarker.js
@@ -1,334 +1,334 @@
-"use strict";
-
-var GuiConnector = require('../../GuiConnector');
-
-var logger = require('../../logger');
-var Promise = require("bluebird");
-
-var ObjectWithListeners = require('../../ObjectWithListeners');
-
-/**
- * Class representing Marker (called sometimes bubble) that we visualize on the
- * map.
- *
- * @param {IdentifiedElement} params.element
- * @param {AbstractCustomMap} params.map
- * @param {function|function[]} [params.onClick]
- * @constructor
- */
-function AbstractMarker(params) {
-  var self = this;
-  // call super constructor
-  ObjectWithListeners.call(this);
-
-  self._icons = [];
-  if (params.element.getIcon()) {
-    self._icons.push(params.element.getIcon());
-  }
-  self.setIdentifiedElement(params.element);
-  self.setCustomMap(params.map);
-
-  self.registerListenerType("onClick");
-  if (params.onClick !== undefined) {
-    if (typeof params.onClick !== "function") {
-      for (var i = 0; i < params.onClick.length; i++) {
-        self.addListener("onClick", params.onClick[i]);
-      }
-    } else {
-      self.addListener("onClick", params.onClick);
-    }
-  }
-
-}
-
-AbstractMarker.prototype = Object.create(ObjectWithListeners.prototype);
-AbstractMarker.prototype.constructor = AbstractMarker;
-
-/**
- * Returns identifier of this object.
- *
- * @returns {number|string} identifier of this object
- */
-AbstractMarker.prototype.getId = function () {
-  return this.getIdentifiedElement().getId();
-};
-
-/**
- * Returns icon of the marker.
- *
- * @returns {string|undefined} identifying icon of the marker
- */
-AbstractMarker.prototype.getIcon = function () {
-  var icons = this._icons;
-  if (icons.length === 0) {
-    return undefined;
-  } else if (icons.length === 1) {
-    return icons[0];
-  } else {
-    var result = icons[0];
-    //if we have many identical icons then return this specific icon
-    for (var i = 1; i < icons.length; i++) {
-      if (icons[i] !== result) {
-        return "marker/multi.png";
-
-      }
-    }
-    return result;
-  }
-};
-
-/**
- *
- * @returns {Promise}
- * @private
- */
-AbstractMarker.prototype._updateIcon = function () {
-  var self = this;
-  var marker = self.getMarker();
-  if (marker !== undefined) {
-    if (self.getIcon() === undefined) {
-      return self.hide();
-    } else {
-      marker.setIcon(GuiConnector.getImgPrefix() + self.getIcon());
-      if (!marker.isShown()) {
-        return self.show();
-      }
-    }
-  }
-  return Promise.resolve();
-};
-
-/**
- *
- * @param {string|null|undefined} icon
- * @returns {Promise}
- */
-AbstractMarker.prototype.setIcon = function (icon) {
-  var self = this;
-  if (icon === null || icon === undefined) {
-    self._icons = [];
-  } else {
-    self._icons = [icon];
-  }
-  return self._updateIcon();
-};
-
-/**
- *
- * @param {string[]} icons
- * @returns {Promise}
- */
-AbstractMarker.prototype.setIcons = function (icons) {
-  var self = this;
-  self._icons = icons;
-  return self._updateIcon();
-};
-
-/**
- *
- * @param {string} icon
- * @returns {Promise}
- */
-AbstractMarker.prototype.addIcon = function (icon) {
-  var self = this;
-  self._icons.push(icon);
-  return self._updateIcon();
-};
-
-/**
- *
- * @param {string[]} icons
- * @returns {Promise}
- */
-AbstractMarker.prototype.addIcons = function (icons) {
-  var self = this;
-  for (var i = 0; i < icons.length; i++) {
-    self._icons.push(icons[i]);
-  }
-  return self._updateIcon();
-};
-
-/**
- *
- * @param {string[]} icons
- * @returns {Promise}
- */
-AbstractMarker.prototype.removeIcons = function (icons) {
-  var self = this;
-  var promises = [];
-  for (var i = 0; i < icons.length; i++) {
-    promises.push(self.removeIcon(icons[i], true));
-  }
-  return Promise.all(promises).then(function () {
-    return self._updateIcon();
-  });
-};
-
-/**
- *
- * @param {string} icon
- * @param {boolean} [preventMarkerUpdate]
- * @returns {Promise}
- */
-AbstractMarker.prototype.removeIcon = function (icon, preventMarkerUpdate) {
-  var self = this;
-  var index = self._icons.indexOf(icon);
-
-  if (index > -1) {
-    self._icons.splice(index, 1);
-    if (!preventMarkerUpdate) {
-      return self._updateIcon();
-    }
-  } else {
-    logger.warn("Unknown icon for marker: " + icon);
-  }
-  return Promise.resolve();
-};
-
-/**
- * Shows marker on the map.
- *
- * @returns {Promise}
- */
-AbstractMarker.prototype.show = function () {
-  var self = this;
-  if (this.getMarker() === undefined) {
-    return this.init().then(function () {
-      return self.getMarker().show();
-    });
-  } else {
-    return this.getMarker().show();
-  }
-};
-
-/**
- *
- * @returns {Promise}
- */
-AbstractMarker.prototype.hide = function () {
-  var self = this;
-  if (this.getMarker() === undefined) {
-    return this.init().then(function () {
-      return self.getMarker().hide();
-    });
-  } else {
-    return Promise.resolve(this.getMarker().hide());
-  }
-};
-
-/**
- *
- * @returns {boolean}
- */
-AbstractMarker.prototype.isShown = function () {
-  if (this.getMarker() === undefined) {
-    return false;
-  }
-  return this.getMarker().isShown();
-};
-
-/**
- * Returns {@link AbstractCustomMap} where marker is located.
- *
- * @returns {AbstractCustomMap} where marker is located
- */
-AbstractMarker.prototype.getCustomMap = function () {
-  return this._map;
-};
-
-/**
- *
- * @param {AbstractCustomMap} map
- */
-AbstractMarker.prototype.setCustomMap = function (map) {
-  this._map = map;
-};
-
-/**
- * Returns {Bounds} of the marker (it's a single point).
- *
- * @returns {Bounds|null} bounds of the marker (it's a single point)
- */
-AbstractMarker.prototype.getBounds = function () {
-  var marker = this.getMarker();
-  if (marker === undefined || marker === null) {
-    logger.warn("Marker not initialized");
-    return null;
-  }
-
-  return marker.getBounds();
-};
-
-/**
- * Initializes {@link Marker} object connected to this object.
- *
- * @returns {Promise}
- * @protected
- */
-AbstractMarker.prototype._init = function () {
-  var self = this;
-  var point = this.getCoordinates();
-
-  this._marker = this.getCustomMap().getMapCanvas().createMarker({
-    position: point,
-    icon: GuiConnector.getImgPrefix() + self.getIcon(),
-    id: self.getId()
-  });
-
-  this._marker.addListener('click', function () {
-    return self.onClickHandler().then(null, GuiConnector.alert);
-  });
-  return Promise.resolve();
-};
-
-/**
- *
- * @returns {Promise|PromiseLike}
- */
-AbstractMarker.prototype.onClickHandler = function () {
-  return this.callListeners("onClick");
-};
-
-/**
- * Returns {google.maps.Marker} connected to this object.
- *
- * @returns {Marker} connected to this object
- */
-AbstractMarker.prototype.getMarker = function () {
-  return this._marker;
-};
-
-/**
- * Abstract function returning string marker type.
- *
- * @returns {string} marker type
- */
-AbstractMarker.prototype.getType = function () {
-  return this.getIdentifiedElement().getType();
-};
-
-/**
- *
- * @returns {number}
- */
-AbstractMarker.prototype.getModelId = function () {
-  return this.getIdentifiedElement().getModelId();
-};
-
-/**
- *
- * @returns {IdentifiedElement}
- */
-AbstractMarker.prototype.getIdentifiedElement = function () {
-  return this._identifiedElement;
-};
-
-/**
- *
- * @param {IdentifiedElement} identifiedElement
- */
-AbstractMarker.prototype.setIdentifiedElement = function (identifiedElement) {
-  this._identifiedElement = identifiedElement;
-};
-
-module.exports = AbstractMarker;
+"use strict";
+
+var GuiConnector = require('../../GuiConnector');
+
+var logger = require('../../logger');
+var Promise = require("bluebird");
+
+var ObjectWithListeners = require('../../ObjectWithListeners');
+
+/**
+ * Class representing Marker (called sometimes bubble) that we visualize on the
+ * map.
+ *
+ * @param {IdentifiedElement} params.element
+ * @param {AbstractCustomMap} params.map
+ * @param {function|function[]} [params.onClick]
+ * @constructor
+ */
+function AbstractMarker(params) {
+  var self = this;
+  // call super constructor
+  ObjectWithListeners.call(this);
+
+  self._icons = [];
+  if (params.element.getIcon()) {
+    self._icons.push(params.element.getIcon());
+  }
+  self.setIdentifiedElement(params.element);
+  self.setCustomMap(params.map);
+
+  self.registerListenerType("onClick");
+  if (params.onClick !== undefined) {
+    if (typeof params.onClick !== "function") {
+      for (var i = 0; i < params.onClick.length; i++) {
+        self.addListener("onClick", params.onClick[i]);
+      }
+    } else {
+      self.addListener("onClick", params.onClick);
+    }
+  }
+
+}
+
+AbstractMarker.prototype = Object.create(ObjectWithListeners.prototype);
+AbstractMarker.prototype.constructor = AbstractMarker;
+
+/**
+ * Returns identifier of this object.
+ *
+ * @returns {number|string} identifier of this object
+ */
+AbstractMarker.prototype.getId = function () {
+  return this.getIdentifiedElement().getId();
+};
+
+/**
+ * Returns icon of the marker.
+ *
+ * @returns {string|undefined} identifying icon of the marker
+ */
+AbstractMarker.prototype.getIcon = function () {
+  var icons = this._icons;
+  if (icons.length === 0) {
+    return undefined;
+  } else if (icons.length === 1) {
+    return icons[0];
+  } else {
+    var result = icons[0];
+    //if we have many identical icons then return this specific icon
+    for (var i = 1; i < icons.length; i++) {
+      if (icons[i] !== result) {
+        return "marker/multi.png";
+
+      }
+    }
+    return result;
+  }
+};
+
+/**
+ *
+ * @returns {Promise}
+ * @private
+ */
+AbstractMarker.prototype._updateIcon = function () {
+  var self = this;
+  var marker = self.getMarker();
+  if (marker !== undefined) {
+    if (self.getIcon() === undefined) {
+      return self.hide();
+    } else {
+      marker.setIcon(GuiConnector.getImgPrefix() + self.getIcon());
+      if (!marker.isShown()) {
+        return self.show();
+      }
+    }
+  }
+  return Promise.resolve();
+};
+
+/**
+ *
+ * @param {string|null|undefined} icon
+ * @returns {Promise}
+ */
+AbstractMarker.prototype.setIcon = function (icon) {
+  var self = this;
+  if (icon === null || icon === undefined) {
+    self._icons = [];
+  } else {
+    self._icons = [icon];
+  }
+  return self._updateIcon();
+};
+
+/**
+ *
+ * @param {string[]} icons
+ * @returns {Promise}
+ */
+AbstractMarker.prototype.setIcons = function (icons) {
+  var self = this;
+  self._icons = icons;
+  return self._updateIcon();
+};
+
+/**
+ *
+ * @param {string} icon
+ * @returns {Promise}
+ */
+AbstractMarker.prototype.addIcon = function (icon) {
+  var self = this;
+  self._icons.push(icon);
+  return self._updateIcon();
+};
+
+/**
+ *
+ * @param {string[]} icons
+ * @returns {Promise}
+ */
+AbstractMarker.prototype.addIcons = function (icons) {
+  var self = this;
+  for (var i = 0; i < icons.length; i++) {
+    self._icons.push(icons[i]);
+  }
+  return self._updateIcon();
+};
+
+/**
+ *
+ * @param {string[]} icons
+ * @returns {Promise}
+ */
+AbstractMarker.prototype.removeIcons = function (icons) {
+  var self = this;
+  var promises = [];
+  for (var i = 0; i < icons.length; i++) {
+    promises.push(self.removeIcon(icons[i], true));
+  }
+  return Promise.all(promises).then(function () {
+    return self._updateIcon();
+  });
+};
+
+/**
+ *
+ * @param {string} icon
+ * @param {boolean} [preventMarkerUpdate]
+ * @returns {Promise}
+ */
+AbstractMarker.prototype.removeIcon = function (icon, preventMarkerUpdate) {
+  var self = this;
+  var index = self._icons.indexOf(icon);
+
+  if (index > -1) {
+    self._icons.splice(index, 1);
+    if (!preventMarkerUpdate) {
+      return self._updateIcon();
+    }
+  } else {
+    logger.warn("Unknown icon for marker: " + icon);
+  }
+  return Promise.resolve();
+};
+
+/**
+ * Shows marker on the map.
+ *
+ * @returns {Promise}
+ */
+AbstractMarker.prototype.show = function () {
+  var self = this;
+  if (this.getMarker() === undefined) {
+    return this.init().then(function () {
+      return self.getMarker().show();
+    });
+  } else {
+    return this.getMarker().show();
+  }
+};
+
+/**
+ *
+ * @returns {Promise}
+ */
+AbstractMarker.prototype.hide = function () {
+  var self = this;
+  if (this.getMarker() === undefined) {
+    return this.init().then(function () {
+      return self.getMarker().hide();
+    });
+  } else {
+    return Promise.resolve(this.getMarker().hide());
+  }
+};
+
+/**
+ *
+ * @returns {boolean}
+ */
+AbstractMarker.prototype.isShown = function () {
+  if (this.getMarker() === undefined) {
+    return false;
+  }
+  return this.getMarker().isShown();
+};
+
+/**
+ * Returns {@link AbstractCustomMap} where marker is located.
+ *
+ * @returns {AbstractCustomMap} where marker is located
+ */
+AbstractMarker.prototype.getCustomMap = function () {
+  return this._map;
+};
+
+/**
+ *
+ * @param {AbstractCustomMap} map
+ */
+AbstractMarker.prototype.setCustomMap = function (map) {
+  this._map = map;
+};
+
+/**
+ * Returns {Bounds} of the marker (it's a single point).
+ *
+ * @returns {Bounds|null} bounds of the marker (it's a single point)
+ */
+AbstractMarker.prototype.getBounds = function () {
+  var marker = this.getMarker();
+  if (marker === undefined || marker === null) {
+    logger.warn("Marker not initialized");
+    return null;
+  }
+
+  return marker.getBounds();
+};
+
+/**
+ * Initializes {@link Marker} object connected to this object.
+ *
+ * @returns {Promise}
+ * @protected
+ */
+AbstractMarker.prototype._init = function () {
+  var self = this;
+  var point = this.getCoordinates();
+
+  this._marker = this.getCustomMap().getMapCanvas().createMarker({
+    position: point,
+    icon: GuiConnector.getImgPrefix() + self.getIcon(),
+    id: self.getId()
+  });
+
+  this._marker.addListener('click', function () {
+    return self.onClickHandler().then(null, GuiConnector.alert);
+  });
+  return Promise.resolve();
+};
+
+/**
+ *
+ * @returns {Promise|PromiseLike}
+ */
+AbstractMarker.prototype.onClickHandler = function () {
+  return this.callListeners("onClick");
+};
+
+/**
+ * Returns {google.maps.Marker} connected to this object.
+ *
+ * @returns {Marker} connected to this object
+ */
+AbstractMarker.prototype.getMarker = function () {
+  return this._marker;
+};
+
+/**
+ * Abstract function returning string marker type.
+ *
+ * @returns {string} marker type
+ */
+AbstractMarker.prototype.getType = function () {
+  return this.getIdentifiedElement().getType();
+};
+
+/**
+ *
+ * @returns {number}
+ */
+AbstractMarker.prototype.getModelId = function () {
+  return this.getIdentifiedElement().getModelId();
+};
+
+/**
+ *
+ * @returns {IdentifiedElement}
+ */
+AbstractMarker.prototype.getIdentifiedElement = function () {
+  return this._identifiedElement;
+};
+
+/**
+ *
+ * @param {IdentifiedElement} identifiedElement
+ */
+AbstractMarker.prototype.setIdentifiedElement = function (identifiedElement) {
+  this._identifiedElement = identifiedElement;
+};
+
+module.exports = AbstractMarker;
diff --git a/frontend-js/src/main/js/map/marker/AliasMarker.js b/frontend-js/src/main/js/map/marker/AliasMarker.js
index 7186290000c78c821ad50fef9ae0d7634033505e..9418c84a7840a0d02d6767257726660b08f12336 100644
--- a/frontend-js/src/main/js/map/marker/AliasMarker.js
+++ b/frontend-js/src/main/js/map/marker/AliasMarker.js
@@ -1,66 +1,66 @@
-"use strict";
-
-var AbstractMarker = require('./AbstractMarker');
-var Point = require('../canvas/Point');
-
-// noinspection JSUnusedLocalSymbols
-var logger = require('../../logger');
-
-/**
- * This class describes Google maps marker (connected to {@link Alias}) that is
- * visualized on the map.
- *
- * @param {IdentifiedElement} params.element
- * @param {AbstractCustomMap} params.map
- * @param {function|function[]} [params.onClick]
- * @constructor
- * @extends AbstractMarker
- */
-function AliasMarker(params) {
-  AbstractMarker.call(this, params);
-}
-
-AliasMarker.prototype = Object.create(AbstractMarker.prototype);
-AliasMarker.prototype.constructor = AliasMarker;
-
-/**
- * Returns {@link Alias} data for this marker.
- *
- * @returns {Alias} data for this marker
- */
-AliasMarker.prototype.getAliasData = function () {
-  return this._aliasData;
-};
-
-/**
- * Sets {@link Alias} data for this marker.
- *
- * @param {Alias} data
- *           data for this marker
- */
-AliasMarker.prototype.setAliasData = function (data) {
-  this._aliasData = data;
-};
-
-/**
- * Returns coordinates where marker is pointing.
- *
- * @returns {Point} - coordinates where marker is pointing
- */
-AliasMarker.prototype.getCoordinates = function () {
-  var alias = this.getAliasData();
-  return new Point(alias.getX() + alias.getWidth() / 2, alias.getY() + alias.getHeight() / 2);
-};
-
-AliasMarker.prototype.init = function () {
-  var self = this;
-  var model = self.getCustomMap().getModel();
-  return model.getByIdentifiedElement(self.getIdentifiedElement()).then(function (aliasData) {
-    self.setAliasData(aliasData);
-    return self._init();
-  }).then(function () {
-    return self.show();
-  });
-};
-
-module.exports = AliasMarker;
+"use strict";
+
+var AbstractMarker = require('./AbstractMarker');
+var Point = require('../canvas/Point');
+
+// noinspection JSUnusedLocalSymbols
+var logger = require('../../logger');
+
+/**
+ * This class describes Google maps marker (connected to {@link Alias}) that is
+ * visualized on the map.
+ *
+ * @param {IdentifiedElement} params.element
+ * @param {AbstractCustomMap} params.map
+ * @param {function|function[]} [params.onClick]
+ * @constructor
+ * @extends AbstractMarker
+ */
+function AliasMarker(params) {
+  AbstractMarker.call(this, params);
+}
+
+AliasMarker.prototype = Object.create(AbstractMarker.prototype);
+AliasMarker.prototype.constructor = AliasMarker;
+
+/**
+ * Returns {@link Alias} data for this marker.
+ *
+ * @returns {Alias} data for this marker
+ */
+AliasMarker.prototype.getAliasData = function () {
+  return this._aliasData;
+};
+
+/**
+ * Sets {@link Alias} data for this marker.
+ *
+ * @param {Alias} data
+ *           data for this marker
+ */
+AliasMarker.prototype.setAliasData = function (data) {
+  this._aliasData = data;
+};
+
+/**
+ * Returns coordinates where marker is pointing.
+ *
+ * @returns {Point} - coordinates where marker is pointing
+ */
+AliasMarker.prototype.getCoordinates = function () {
+  var alias = this.getAliasData();
+  return new Point(alias.getX() + alias.getWidth() / 2, alias.getY() + alias.getHeight() / 2);
+};
+
+AliasMarker.prototype.init = function () {
+  var self = this;
+  var model = self.getCustomMap().getModel();
+  return model.getByIdentifiedElement(self.getIdentifiedElement()).then(function (aliasData) {
+    self.setAliasData(aliasData);
+    return self._init();
+  }).then(function () {
+    return self.show();
+  });
+};
+
+module.exports = AliasMarker;
diff --git a/frontend-js/src/main/js/map/marker/MarkerSurfaceCollection.js b/frontend-js/src/main/js/map/marker/MarkerSurfaceCollection.js
index 5ecac222035e50ca0a651b3284e545ba702535c1..7189f9a8c4da11ea3054d5df2b7f855a314df489 100644
--- a/frontend-js/src/main/js/map/marker/MarkerSurfaceCollection.js
+++ b/frontend-js/src/main/js/map/marker/MarkerSurfaceCollection.js
@@ -1,562 +1,562 @@
-"use strict";
-
-var AliasMarker = require('./AliasMarker');
-var IdentifiedElement = require('../data/IdentifiedElement');
-var PointMarker = require('./PointMarker');
-var ReactionMarker = require('./ReactionMarker');
-
-var AbstractSurfaceElement = require('../surface/AbstractSurfaceElement');
-var AliasSurface = require('../surface/AliasSurface');
-var ReactionSurface = require('../surface/ReactionSurface');
-
-// noinspection JSUnusedLocalSymbols
-var logger = require('../../logger');
-var Promise = require("bluebird");
-
-var ObjectWithListeners = require('../../ObjectWithListeners');
-
-/**
- * @typedef {Object} IconData
- * @property {IdentifiedElement} element
- * @property {string[]} icons
- */
-
-/**
- *
- * @param {AbstractCustomMap} params.map
- * @constructor
- */
-function MarkerSurfaceCollection(params) {
-  var self = this;
-  ObjectWithListeners.call(this);
-
-  /**
-   * @type {Object.<string, IconData>}
-   */
-  self._overlayIcons = {};
-  // @type {Object.<string, AbstractMarker>}
-  self._markers = {};
-  // @type {Object.<string, Object.<string,AbstractMarker>>}
-  self._overlaySurfaces = {
-    ALIAS: [],
-    REACTION: [],
-    POINT: []
-  };
-
-  self.setMap(params.map);
-}
-
-MarkerSurfaceCollection.prototype = Object.create(ObjectWithListeners.prototype);
-MarkerSurfaceCollection.prototype.constructor = MarkerSurfaceCollection;
-
-/**
- *
- * @param {AbstractCustomMap} map
- */
-MarkerSurfaceCollection.prototype.setMap = function (map) {
-  if (map === undefined) {
-    throw new Error("Map must be defined");
-  }
-  this._map = map;
-};
-
-/**
- *
- * @returns {AbstractCustomMap}
- */
-MarkerSurfaceCollection.prototype.getMap = function () {
-  return this._map;
-};
-
-/**
- *
- * @param {AbstractDbOverlay} overlay
- * @returns {Promise}
- */
-MarkerSurfaceCollection.prototype.refreshOverlayMarkers = function (overlay) {
-  var promises = [];
-  var self = this;
-  var overlayData = self._overlayIcons[overlay.getName()];
-  for (var elementId in overlayData) {
-    if (overlayData.hasOwnProperty(elementId)) {
-      var x = function () {
-        var marker = self._markers[elementId];
-        promises.push(marker.hide().then(function () {
-          return marker.show();
-        }));
-      }();
-    }
-  }
-  overlayData = self._overlaySurfaces[overlay.getName()];
-  for (elementId in overlayData) {
-    if (overlayData.hasOwnProperty(elementId)) {
-      x = function () {
-        var surface = overlayData[elementId];
-        promises.push(surface.hide().then(function () {
-          return surface.show();
-        }));
-      }();
-    }
-  }
-  return Promise.all(promises);
-};
-
-/**
- *
- * @param {string[]} params.icons
- * @param {IdentifiedElement} params.element
- * @returns {Promise}
- */
-MarkerSurfaceCollection.prototype.addMarker = function (params) {
-  var element = params.element;
-  var icons = params.icons;
-
-  var self = this;
-
-  var result = self.getMarker(element);
-  if (result !== undefined) {
-    return result.addIcons(icons).then(function () {
-      return Promise.resolve(result);
-    });
-  }
-
-  var MarkerConstructor = null;
-  if (element.getType() === "ALIAS") {
-    MarkerConstructor = AliasMarker;
-  } else if (element.getType() === "REACTION") {
-    MarkerConstructor = ReactionMarker;
-  } else if (element.getType() === "POINT") {
-    MarkerConstructor = PointMarker;
-  } else {
-    throw new Error("Unknown type of the element in overlay: " + element.type);
-  }
-  result = new MarkerConstructor({
-    element: element,
-    map: self.getMap(),
-    onClick: [function () {
-      return self.getMap()._openInfoWindowForIdentifiedElement(element, result.getMarker());
-    }, function () {
-      return self.getMap().getTopMap().callListeners("onBioEntityClick", element);
-    }]
-  });
-  self.putMarker(element, result);
-  return result.setIcons(icons).then(function () {
-    if (self.getMap().isInitialized()) {
-      return result.init().then(function () {
-        return result;
-      });
-    } else {
-      return Promise.resolve(result);
-    }
-  });
-};
-
-/**
- *
- * @param {string[]} params.icons
- * @param {IdentifiedElement} params.element
- * @returns {Promise}
- */
-MarkerSurfaceCollection.prototype.removeMarker = function (params) {
-  var element = params.element;
-  var icons = params.icons;
-
-  var self = this;
-
-  var result = self.getMarker(element);
-  return result.removeIcons(icons);
-};
-
-/**
- *
- * @param {IdentifiedElement} element
- * @param {AbstractDbOverlay} dbOverlay
- * @returns {PromiseLike<any>}
- */
-MarkerSurfaceCollection.prototype.createSurfaceForDbOverlay = function (element, dbOverlay) {
-  var self = this;
-
-  var result = self.getSurface({element: element, overlay: dbOverlay});
-  if (result !== undefined) {
-    result.updateIdentifiedElement(element);
-    return Promise.resolve(result);
-  }
-
-  var map = self.getMap();
-  /**
-   * @type {function[]}
-   */
-  var onclickFunctions = [function () {
-    return self.getMap().getTopMap().callListeners("onBioEntityClick", element);
-  }];
-  if (element.getType() === "ALIAS") {
-    return map.getModel().getAliasById(element.getId()).then(function (alias) {
-      result = new AliasSurface({
-        alias: alias,
-        map: map,
-        onClick: onclickFunctions,
-        color: element.getColor(),
-        fillOpacity: element.getOpacity(),
-        strokeWeight: element.getLineWeight(),
-        strokeColor: element.getLineColor(),
-        strokeOpacity: element.getLineOpacity()
-      });
-      self.putSurface({element: element, overlay: dbOverlay}, result);
-      if (self.getMap().isInitialized()) {
-        return result.init().then(function () {
-          return result.show();
-        }).then(function () {
-          return result;
-        });
-      } else {
-        return result;
-      }
-    });
-  } else if (element.getType() === "REACTION") {
-    return map.getModel().getReactionById(element.getId()).then(function (reactionData) {
-      result = new ReactionSurface({
-        reaction: reactionData,
-        map: map,
-        customized: true,
-        color: element.getColor(),
-        onClick: onclickFunctions
-      });
-      result.addListener("onClick", function(){
-        return map.getTopMap().openInfoWindowForIdentifiedElement(element);
-      });
-      self.putSurface({element: element, overlay: dbOverlay}, result);
-      if (self.getMap().isInitialized()) {
-        return result.init().then(function () {
-          return result.show();
-        }).then(function () {
-          return result;
-        });
-      } else {
-        return result;
-      }
-    });
-  } else if (element.getType() === "POINT") {
-    throw new Error("Not implemented");
-  } else {
-    throw new Error("Unknown type of the element in overlay: " + element.getType());
-  }
-};
-
-/**
- *
- * @returns {AbstractMarker[]}
- */
-MarkerSurfaceCollection.prototype.getMarkers = function () {
-  var result = [];
-  var markers = this._markers;
-  for (var key in markers) {
-    if (markers.hasOwnProperty(key)) {
-      var marker = markers[key];
-      if (marker.isShown()) {
-        result.push(marker);
-      }
-    }
-  }
-
-  return result;
-};
-
-/**
- *
- * @returns {AbstractSurfaceElement[]}
- */
-MarkerSurfaceCollection.prototype.getSurfaces = function () {
-  var result = [];
-
-  var overlaySurfaces = this._overlaySurfaces;
-  for (var overlayName in overlaySurfaces) {
-    if (overlaySurfaces.hasOwnProperty(overlayName)) {
-      var surfaces = overlaySurfaces[overlayName];
-      for (var key in surfaces) {
-        if (surfaces.hasOwnProperty(key)) {
-          result.push(surfaces[key]);
-        }
-      }
-    }
-  }
-
-  return result;
-};
-
-/**
- *
- * @param {IdentifiedElement} element
- * @returns {AbstractMarker|undefined}
- */
-MarkerSurfaceCollection.prototype.getMarker = function (element) {
-  return this._markers[element.toString()];
-};
-
-/**
- *
- * @param {IdentifiedElement} element
- * @param {AbstractMarker} marker
- */
-MarkerSurfaceCollection.prototype.putMarker = function (element, marker) {
-  this._markers[element.toString()] = marker;
-};
-
-/**
- *
- * @param params
- * @returns {AbstractSurfaceElement|undefined}
- */
-MarkerSurfaceCollection.prototype.getSurface = function (params) {
-  var element = new IdentifiedElement(params.element);
-  var overlay = params.overlay;
-
-  var overlaySurfaces = this._overlaySurfaces[overlay.getName()];
-  if (overlaySurfaces === undefined) {
-    this._overlaySurfaces[overlay.getName()] = [];
-    overlaySurfaces = this._overlaySurfaces[overlay.getName()];
-  }
-  return overlaySurfaces[element.toString()];
-};
-
-/**
- *
- * @param {Object} params
- * @param {IdentifiedElement} params.element
- * @param {AbstractDbOverlay} params.overlay
- * @param {AbstractSurfaceElement} surface
- */
-MarkerSurfaceCollection.prototype.putSurface = function (params, surface) {
-  var element = params.element;
-  var overlay = params.overlay;
-
-  var overlaySurfaces = this._overlaySurfaces[overlay.getName()];
-  if (overlaySurfaces === undefined) {
-    this._overlaySurfaces[overlay.getName()] = [];
-    overlaySurfaces = this._overlaySurfaces[overlay.getName()];
-  }
-  overlaySurfaces[element.toString()] = surface;
-};
-
-/**
- *
- * @param {AbstractSurfaceElement[]} modifiedMarkersAndSurfaces
- * @param {AbstractDbOverlay} dbOverlay
- */
-MarkerSurfaceCollection.prototype.removeUnmodifiedSurfaces = function (modifiedMarkersAndSurfaces, dbOverlay) {
-  var modifiedSurfaces = {
-    "ALIAS": [],
-    "REACTION": [],
-    "POINT": []
-  };
-
-  for (var i = 0; i < modifiedMarkersAndSurfaces.length; i++) {
-    var object = modifiedMarkersAndSurfaces[i];
-    var identifiedElement = object.getIdentifiedElement();
-    if (object instanceof AbstractSurfaceElement) {
-      modifiedSurfaces[identifiedElement.toString()] = true;
-    } else {
-      throw new Error("Unknown class type: " + object.prototype.name);
-    }
-  }
-
-  var surfaceOverlaysPerType = this._overlaySurfaces[dbOverlay.getName()];
-  for (var key in surfaceOverlaysPerType) {
-    if (surfaceOverlaysPerType.hasOwnProperty(key)) {
-      if (!modifiedSurfaces[key]) {
-        surfaceOverlaysPerType[key].hide();
-        delete surfaceOverlaysPerType[key];
-      }
-    }
-  }
-};
-
-/**
- *
- * @param {IdentifiedElement[]} allElements
- * @param {AbstractDbOverlay} overlay
- * @returns {PromiseLike<any>}
- */
-MarkerSurfaceCollection.prototype.renderOverlay = function (allElements, overlay) {
-  var self = this;
-  var markerElements = [];
-  var surfaceElements = [];
-  for (var i = 0; i < allElements.length; i++) {
-    var element = allElements[i];
-    if (element.getModelId() === self.getMap().getId()) {
-      if (element.getIcon() !== null && element.getIcon() !== undefined) {
-        markerElements.push(element);
-      } else {
-        surfaceElements.push(element);
-      }
-    }
-  }
-
-  var markers;
-  return self.renderOverlayMarkers(markerElements, overlay).then(function (result) {
-    markers = result;
-    return self.renderOverlaySurfaces(surfaceElements, overlay);
-  }).then(function (surfaces) {
-    return markers.concat(surfaces);
-  });
-};
-
-/**
- *
- * @param {IdentifiedElement} element
- * @constructor
- */
-function IconDifference(element) {
-  this.element = element;
-  this.iconsToAdd = [];
-  this.iconsToRemove = [];
-}
-
-/**
- *
- * @param {string} icon
- */
-IconDifference.prototype.addIcon = function (icon) {
-  var index = this.iconsToRemove.indexOf(icon);
-  if (index > -1) {
-    this.iconsToRemove.splice(index, 1);
-  } else {
-    this.iconsToAdd.push(icon);
-  }
-};
-
-/**
- *
- * @param {string} icon
- */
-IconDifference.prototype.removeIcon = function (icon) {
-  var index = this.iconsToAdd.indexOf(icon);
-  if (index > -1) {
-    this.iconsToAdd.splice(index, 1);
-  } else {
-    this.iconsToRemove.push(icon);
-  }
-};
-
-/**
- *
- * @param {string[]} icons
- */
-IconDifference.prototype.removeIcons = function (icons) {
-  for (var i = 0; i < icons.length; i++) {
-    this.removeIcon(icons[i]);
-  }
-};
-
-/**
- *
- * @param {IdentifiedElement[]} elements
- * @param {AbstractDbOverlay} overlay
- * @returns {PromiseLike<any>}
- */
-MarkerSurfaceCollection.prototype.renderOverlayMarkers = function (elements, overlay) {
-  var self = this;
-
-  var markers = [];
-  return self.getMap().getModel().getByIdentifiedElements(elements).then(function () {
-    var elementsToProcess = [];
-    var i, element, icon, data, entry, key;
-    for (i = 0; i < elements.length; i++) {
-      element = elements[i];
-      icon = element.getIcon();
-      data = elementsToProcess[element.toString()];
-      if (data === undefined) {
-        elementsToProcess[element.toString()] = new IconDifference(element);
-        data = elementsToProcess[element.toString()]
-      }
-      data.addIcon(icon);
-    }
-    var iconData = self.getOverlayIconData(overlay);
-    for (key in iconData) {
-      if (iconData.hasOwnProperty(key)) {
-        entry = iconData[key];
-        element = entry.element;
-        data = elementsToProcess[element.toString()];
-        if (data === undefined) {
-          elementsToProcess[element.toString()] = new IconDifference(element);
-          data = elementsToProcess[element.toString()]
-        }
-        data.removeIcons(entry.icons);
-      }
-    }
-
-    var promises = [];
-
-    for (key in elementsToProcess) {
-      if (elementsToProcess.hasOwnProperty(key)) {
-        data = elementsToProcess[key];
-        if (data.iconsToAdd.length > 0) {
-          promises.push(self.addMarker({element: data.element, icons: data.iconsToAdd}).then(function (marker) {
-            markers.push(marker);
-          }));
-        }
-        if (data.iconsToRemove.length > 0) {
-          promises.push(self.removeMarker({element: data.element, icons: data.iconsToRemove}));
-        }
-      }
-    }
-    return Promise.all(promises);
-  }).then(function () {
-    self.createOverlayIconData(elements, overlay);
-    return markers;
-  });
-};
-
-/**
- *
- * @param {AbstractDbOverlay} overlay
- * @returns {IconData}
- */
-MarkerSurfaceCollection.prototype.getOverlayIconData = function (overlay) {
-  var iconData = this._overlayIcons[overlay.getName()];
-  if (iconData === undefined) {
-    this._overlayIcons[overlay.getName()] = {};
-    iconData = this._overlayIcons[overlay.getName()]
-  }
-  return iconData;
-};
-
-/**
- *
- * @param {IdentifiedElement[]} elements
- * @param {AbstractDbOverlay} overlay
- */
-MarkerSurfaceCollection.prototype.createOverlayIconData = function (elements, overlay) {
-  var iconData = {};
-  for (var i = 0; i < elements.length; i++) {
-    var element = elements[i];
-    if (iconData[element.toString()] === undefined) {
-      iconData[element.toString()] = {icons: [], element: element};
-    }
-    iconData[element.toString()].icons.push(element.getIcon());
-  }
-  this._overlayIcons[overlay.getName()] = iconData;
-};
-
-/**
- *
- * @param {IdentifiedElement[]} elements
- * @param {AbstractDbOverlay} overlay
- * @returns {PromiseLike<AbstractSurfaceElement>}
- */
-MarkerSurfaceCollection.prototype.renderOverlaySurfaces = function (elements, overlay) {
-  var self = this;
-  var surfaces = [];
-  return self.getMap().getModel().getByIdentifiedElements(elements).then(function () {
-    return Promise.each(elements, function (element) {
-      return self.createSurfaceForDbOverlay(element, overlay).then(function (mapOverlay) {
-        surfaces.push(mapOverlay);
-      });
-    });
-  }).then(function () {
-    self.removeUnmodifiedSurfaces(surfaces, overlay);
-    return surfaces;
-  });
-
-};
-
-module.exports = MarkerSurfaceCollection;
+"use strict";
+
+var AliasMarker = require('./AliasMarker');
+var IdentifiedElement = require('../data/IdentifiedElement');
+var PointMarker = require('./PointMarker');
+var ReactionMarker = require('./ReactionMarker');
+
+var AbstractSurfaceElement = require('../surface/AbstractSurfaceElement');
+var AliasSurface = require('../surface/AliasSurface');
+var ReactionSurface = require('../surface/ReactionSurface');
+
+// noinspection JSUnusedLocalSymbols
+var logger = require('../../logger');
+var Promise = require("bluebird");
+
+var ObjectWithListeners = require('../../ObjectWithListeners');
+
+/**
+ * @typedef {Object} IconData
+ * @property {IdentifiedElement} element
+ * @property {string[]} icons
+ */
+
+/**
+ *
+ * @param {AbstractCustomMap} params.map
+ * @constructor
+ */
+function MarkerSurfaceCollection(params) {
+  var self = this;
+  ObjectWithListeners.call(this);
+
+  /**
+   * @type {Object.<string, IconData>}
+   */
+  self._overlayIcons = {};
+  // @type {Object.<string, AbstractMarker>}
+  self._markers = {};
+  // @type {Object.<string, Object.<string,AbstractMarker>>}
+  self._overlaySurfaces = {
+    ALIAS: [],
+    REACTION: [],
+    POINT: []
+  };
+
+  self.setMap(params.map);
+}
+
+MarkerSurfaceCollection.prototype = Object.create(ObjectWithListeners.prototype);
+MarkerSurfaceCollection.prototype.constructor = MarkerSurfaceCollection;
+
+/**
+ *
+ * @param {AbstractCustomMap} map
+ */
+MarkerSurfaceCollection.prototype.setMap = function (map) {
+  if (map === undefined) {
+    throw new Error("Map must be defined");
+  }
+  this._map = map;
+};
+
+/**
+ *
+ * @returns {AbstractCustomMap}
+ */
+MarkerSurfaceCollection.prototype.getMap = function () {
+  return this._map;
+};
+
+/**
+ *
+ * @param {AbstractDbOverlay} overlay
+ * @returns {Promise}
+ */
+MarkerSurfaceCollection.prototype.refreshOverlayMarkers = function (overlay) {
+  var promises = [];
+  var self = this;
+  var overlayData = self._overlayIcons[overlay.getName()];
+  for (var elementId in overlayData) {
+    if (overlayData.hasOwnProperty(elementId)) {
+      var x = function () {
+        var marker = self._markers[elementId];
+        promises.push(marker.hide().then(function () {
+          return marker.show();
+        }));
+      }();
+    }
+  }
+  overlayData = self._overlaySurfaces[overlay.getName()];
+  for (elementId in overlayData) {
+    if (overlayData.hasOwnProperty(elementId)) {
+      x = function () {
+        var surface = overlayData[elementId];
+        promises.push(surface.hide().then(function () {
+          return surface.show();
+        }));
+      }();
+    }
+  }
+  return Promise.all(promises);
+};
+
+/**
+ *
+ * @param {string[]} params.icons
+ * @param {IdentifiedElement} params.element
+ * @returns {Promise}
+ */
+MarkerSurfaceCollection.prototype.addMarker = function (params) {
+  var element = params.element;
+  var icons = params.icons;
+
+  var self = this;
+
+  var result = self.getMarker(element);
+  if (result !== undefined) {
+    return result.addIcons(icons).then(function () {
+      return Promise.resolve(result);
+    });
+  }
+
+  var MarkerConstructor = null;
+  if (element.getType() === "ALIAS") {
+    MarkerConstructor = AliasMarker;
+  } else if (element.getType() === "REACTION") {
+    MarkerConstructor = ReactionMarker;
+  } else if (element.getType() === "POINT") {
+    MarkerConstructor = PointMarker;
+  } else {
+    throw new Error("Unknown type of the element in overlay: " + element.type);
+  }
+  result = new MarkerConstructor({
+    element: element,
+    map: self.getMap(),
+    onClick: [function () {
+      return self.getMap()._openInfoWindowForIdentifiedElement(element, result.getMarker());
+    }, function () {
+      return self.getMap().getTopMap().callListeners("onBioEntityClick", element);
+    }]
+  });
+  self.putMarker(element, result);
+  return result.setIcons(icons).then(function () {
+    if (self.getMap().isInitialized()) {
+      return result.init().then(function () {
+        return result;
+      });
+    } else {
+      return Promise.resolve(result);
+    }
+  });
+};
+
+/**
+ *
+ * @param {string[]} params.icons
+ * @param {IdentifiedElement} params.element
+ * @returns {Promise}
+ */
+MarkerSurfaceCollection.prototype.removeMarker = function (params) {
+  var element = params.element;
+  var icons = params.icons;
+
+  var self = this;
+
+  var result = self.getMarker(element);
+  return result.removeIcons(icons);
+};
+
+/**
+ *
+ * @param {IdentifiedElement} element
+ * @param {AbstractDbOverlay} dbOverlay
+ * @returns {PromiseLike<any>}
+ */
+MarkerSurfaceCollection.prototype.createSurfaceForDbOverlay = function (element, dbOverlay) {
+  var self = this;
+
+  var result = self.getSurface({element: element, overlay: dbOverlay});
+  if (result !== undefined) {
+    result.updateIdentifiedElement(element);
+    return Promise.resolve(result);
+  }
+
+  var map = self.getMap();
+  /**
+   * @type {function[]}
+   */
+  var onclickFunctions = [function () {
+    return self.getMap().getTopMap().callListeners("onBioEntityClick", element);
+  }];
+  if (element.getType() === "ALIAS") {
+    return map.getModel().getAliasById(element.getId()).then(function (alias) {
+      result = new AliasSurface({
+        alias: alias,
+        map: map,
+        onClick: onclickFunctions,
+        color: element.getColor(),
+        fillOpacity: element.getOpacity(),
+        strokeWeight: element.getLineWeight(),
+        strokeColor: element.getLineColor(),
+        strokeOpacity: element.getLineOpacity()
+      });
+      self.putSurface({element: element, overlay: dbOverlay}, result);
+      if (self.getMap().isInitialized()) {
+        return result.init().then(function () {
+          return result.show();
+        }).then(function () {
+          return result;
+        });
+      } else {
+        return result;
+      }
+    });
+  } else if (element.getType() === "REACTION") {
+    return map.getModel().getReactionById(element.getId()).then(function (reactionData) {
+      result = new ReactionSurface({
+        reaction: reactionData,
+        map: map,
+        customized: true,
+        color: element.getColor(),
+        onClick: onclickFunctions
+      });
+      result.addListener("onClick", function(){
+        return map.getTopMap().openInfoWindowForIdentifiedElement(element);
+      });
+      self.putSurface({element: element, overlay: dbOverlay}, result);
+      if (self.getMap().isInitialized()) {
+        return result.init().then(function () {
+          return result.show();
+        }).then(function () {
+          return result;
+        });
+      } else {
+        return result;
+      }
+    });
+  } else if (element.getType() === "POINT") {
+    throw new Error("Not implemented");
+  } else {
+    throw new Error("Unknown type of the element in overlay: " + element.getType());
+  }
+};
+
+/**
+ *
+ * @returns {AbstractMarker[]}
+ */
+MarkerSurfaceCollection.prototype.getMarkers = function () {
+  var result = [];
+  var markers = this._markers;
+  for (var key in markers) {
+    if (markers.hasOwnProperty(key)) {
+      var marker = markers[key];
+      if (marker.isShown()) {
+        result.push(marker);
+      }
+    }
+  }
+
+  return result;
+};
+
+/**
+ *
+ * @returns {AbstractSurfaceElement[]}
+ */
+MarkerSurfaceCollection.prototype.getSurfaces = function () {
+  var result = [];
+
+  var overlaySurfaces = this._overlaySurfaces;
+  for (var overlayName in overlaySurfaces) {
+    if (overlaySurfaces.hasOwnProperty(overlayName)) {
+      var surfaces = overlaySurfaces[overlayName];
+      for (var key in surfaces) {
+        if (surfaces.hasOwnProperty(key)) {
+          result.push(surfaces[key]);
+        }
+      }
+    }
+  }
+
+  return result;
+};
+
+/**
+ *
+ * @param {IdentifiedElement} element
+ * @returns {AbstractMarker|undefined}
+ */
+MarkerSurfaceCollection.prototype.getMarker = function (element) {
+  return this._markers[element.toString()];
+};
+
+/**
+ *
+ * @param {IdentifiedElement} element
+ * @param {AbstractMarker} marker
+ */
+MarkerSurfaceCollection.prototype.putMarker = function (element, marker) {
+  this._markers[element.toString()] = marker;
+};
+
+/**
+ *
+ * @param params
+ * @returns {AbstractSurfaceElement|undefined}
+ */
+MarkerSurfaceCollection.prototype.getSurface = function (params) {
+  var element = new IdentifiedElement(params.element);
+  var overlay = params.overlay;
+
+  var overlaySurfaces = this._overlaySurfaces[overlay.getName()];
+  if (overlaySurfaces === undefined) {
+    this._overlaySurfaces[overlay.getName()] = [];
+    overlaySurfaces = this._overlaySurfaces[overlay.getName()];
+  }
+  return overlaySurfaces[element.toString()];
+};
+
+/**
+ *
+ * @param {Object} params
+ * @param {IdentifiedElement} params.element
+ * @param {AbstractDbOverlay} params.overlay
+ * @param {AbstractSurfaceElement} surface
+ */
+MarkerSurfaceCollection.prototype.putSurface = function (params, surface) {
+  var element = params.element;
+  var overlay = params.overlay;
+
+  var overlaySurfaces = this._overlaySurfaces[overlay.getName()];
+  if (overlaySurfaces === undefined) {
+    this._overlaySurfaces[overlay.getName()] = [];
+    overlaySurfaces = this._overlaySurfaces[overlay.getName()];
+  }
+  overlaySurfaces[element.toString()] = surface;
+};
+
+/**
+ *
+ * @param {AbstractSurfaceElement[]} modifiedMarkersAndSurfaces
+ * @param {AbstractDbOverlay} dbOverlay
+ */
+MarkerSurfaceCollection.prototype.removeUnmodifiedSurfaces = function (modifiedMarkersAndSurfaces, dbOverlay) {
+  var modifiedSurfaces = {
+    "ALIAS": [],
+    "REACTION": [],
+    "POINT": []
+  };
+
+  for (var i = 0; i < modifiedMarkersAndSurfaces.length; i++) {
+    var object = modifiedMarkersAndSurfaces[i];
+    var identifiedElement = object.getIdentifiedElement();
+    if (object instanceof AbstractSurfaceElement) {
+      modifiedSurfaces[identifiedElement.toString()] = true;
+    } else {
+      throw new Error("Unknown class type: " + object.prototype.name);
+    }
+  }
+
+  var surfaceOverlaysPerType = this._overlaySurfaces[dbOverlay.getName()];
+  for (var key in surfaceOverlaysPerType) {
+    if (surfaceOverlaysPerType.hasOwnProperty(key)) {
+      if (!modifiedSurfaces[key]) {
+        surfaceOverlaysPerType[key].hide();
+        delete surfaceOverlaysPerType[key];
+      }
+    }
+  }
+};
+
+/**
+ *
+ * @param {IdentifiedElement[]} allElements
+ * @param {AbstractDbOverlay} overlay
+ * @returns {PromiseLike<any>}
+ */
+MarkerSurfaceCollection.prototype.renderOverlay = function (allElements, overlay) {
+  var self = this;
+  var markerElements = [];
+  var surfaceElements = [];
+  for (var i = 0; i < allElements.length; i++) {
+    var element = allElements[i];
+    if (element.getModelId() === self.getMap().getId()) {
+      if (element.getIcon() !== null && element.getIcon() !== undefined) {
+        markerElements.push(element);
+      } else {
+        surfaceElements.push(element);
+      }
+    }
+  }
+
+  var markers;
+  return self.renderOverlayMarkers(markerElements, overlay).then(function (result) {
+    markers = result;
+    return self.renderOverlaySurfaces(surfaceElements, overlay);
+  }).then(function (surfaces) {
+    return markers.concat(surfaces);
+  });
+};
+
+/**
+ *
+ * @param {IdentifiedElement} element
+ * @constructor
+ */
+function IconDifference(element) {
+  this.element = element;
+  this.iconsToAdd = [];
+  this.iconsToRemove = [];
+}
+
+/**
+ *
+ * @param {string} icon
+ */
+IconDifference.prototype.addIcon = function (icon) {
+  var index = this.iconsToRemove.indexOf(icon);
+  if (index > -1) {
+    this.iconsToRemove.splice(index, 1);
+  } else {
+    this.iconsToAdd.push(icon);
+  }
+};
+
+/**
+ *
+ * @param {string} icon
+ */
+IconDifference.prototype.removeIcon = function (icon) {
+  var index = this.iconsToAdd.indexOf(icon);
+  if (index > -1) {
+    this.iconsToAdd.splice(index, 1);
+  } else {
+    this.iconsToRemove.push(icon);
+  }
+};
+
+/**
+ *
+ * @param {string[]} icons
+ */
+IconDifference.prototype.removeIcons = function (icons) {
+  for (var i = 0; i < icons.length; i++) {
+    this.removeIcon(icons[i]);
+  }
+};
+
+/**
+ *
+ * @param {IdentifiedElement[]} elements
+ * @param {AbstractDbOverlay} overlay
+ * @returns {PromiseLike<any>}
+ */
+MarkerSurfaceCollection.prototype.renderOverlayMarkers = function (elements, overlay) {
+  var self = this;
+
+  var markers = [];
+  return self.getMap().getModel().getByIdentifiedElements(elements).then(function () {
+    var elementsToProcess = [];
+    var i, element, icon, data, entry, key;
+    for (i = 0; i < elements.length; i++) {
+      element = elements[i];
+      icon = element.getIcon();
+      data = elementsToProcess[element.toString()];
+      if (data === undefined) {
+        elementsToProcess[element.toString()] = new IconDifference(element);
+        data = elementsToProcess[element.toString()]
+      }
+      data.addIcon(icon);
+    }
+    var iconData = self.getOverlayIconData(overlay);
+    for (key in iconData) {
+      if (iconData.hasOwnProperty(key)) {
+        entry = iconData[key];
+        element = entry.element;
+        data = elementsToProcess[element.toString()];
+        if (data === undefined) {
+          elementsToProcess[element.toString()] = new IconDifference(element);
+          data = elementsToProcess[element.toString()]
+        }
+        data.removeIcons(entry.icons);
+      }
+    }
+
+    var promises = [];
+
+    for (key in elementsToProcess) {
+      if (elementsToProcess.hasOwnProperty(key)) {
+        data = elementsToProcess[key];
+        if (data.iconsToAdd.length > 0) {
+          promises.push(self.addMarker({element: data.element, icons: data.iconsToAdd}).then(function (marker) {
+            markers.push(marker);
+          }));
+        }
+        if (data.iconsToRemove.length > 0) {
+          promises.push(self.removeMarker({element: data.element, icons: data.iconsToRemove}));
+        }
+      }
+    }
+    return Promise.all(promises);
+  }).then(function () {
+    self.createOverlayIconData(elements, overlay);
+    return markers;
+  });
+};
+
+/**
+ *
+ * @param {AbstractDbOverlay} overlay
+ * @returns {IconData}
+ */
+MarkerSurfaceCollection.prototype.getOverlayIconData = function (overlay) {
+  var iconData = this._overlayIcons[overlay.getName()];
+  if (iconData === undefined) {
+    this._overlayIcons[overlay.getName()] = {};
+    iconData = this._overlayIcons[overlay.getName()]
+  }
+  return iconData;
+};
+
+/**
+ *
+ * @param {IdentifiedElement[]} elements
+ * @param {AbstractDbOverlay} overlay
+ */
+MarkerSurfaceCollection.prototype.createOverlayIconData = function (elements, overlay) {
+  var iconData = {};
+  for (var i = 0; i < elements.length; i++) {
+    var element = elements[i];
+    if (iconData[element.toString()] === undefined) {
+      iconData[element.toString()] = {icons: [], element: element};
+    }
+    iconData[element.toString()].icons.push(element.getIcon());
+  }
+  this._overlayIcons[overlay.getName()] = iconData;
+};
+
+/**
+ *
+ * @param {IdentifiedElement[]} elements
+ * @param {AbstractDbOverlay} overlay
+ * @returns {PromiseLike<AbstractSurfaceElement>}
+ */
+MarkerSurfaceCollection.prototype.renderOverlaySurfaces = function (elements, overlay) {
+  var self = this;
+  var surfaces = [];
+  return self.getMap().getModel().getByIdentifiedElements(elements).then(function () {
+    return Promise.each(elements, function (element) {
+      return self.createSurfaceForDbOverlay(element, overlay).then(function (mapOverlay) {
+        surfaces.push(mapOverlay);
+      });
+    });
+  }).then(function () {
+    self.removeUnmodifiedSurfaces(surfaces, overlay);
+    return surfaces;
+  });
+
+};
+
+module.exports = MarkerSurfaceCollection;
diff --git a/frontend-js/src/main/js/map/marker/PointMarker.js b/frontend-js/src/main/js/map/marker/PointMarker.js
index 63decdbe6674bb7f10a6e20f5a6fbc5e74d87a50..e477cfa41cd6c9cef123cfbcde740874d7b716f3 100644
--- a/frontend-js/src/main/js/map/marker/PointMarker.js
+++ b/frontend-js/src/main/js/map/marker/PointMarker.js
@@ -1,70 +1,70 @@
-"use strict";
-
-var AbstractMarker = require('./AbstractMarker');
-var PointData = require('../data/PointData');
-
-/**
- * This class describes Google maps marker (connected to some specific point,
- * but not to any element) that is visualized on the map.
- *
- * @param {IdentifiedElement} params.element
- * @param {AbstractCustomMap} params.map
- * @param {function|function[]} params.onclick
- * @constructor
- * @extends AbstractMarker
- */
-function PointMarker(params) {
-  var self = this;
-  AbstractMarker.call(self, params);
-  self.setPointData(new PointData(self.getIdentifiedElement()));
-}
-
-PointMarker.prototype = Object.create(AbstractMarker.prototype);
-PointMarker.prototype.constructor = PointMarker;
-
-/**
- *
- * @returns {Promise<any>}
- */
-PointMarker.prototype.init = function () {
-  var self = this;
-  return self._init().then(function () {
-    return self.show();
-  });
-};
-
-/**
- * Returns identifier of the object.
- *
- * @returns {string} identifier of the object
- */
-PointMarker.prototype.getId = function () {
-  return this.getPointData().getId();
-};
-
-/**
- * Returns a {@link PointData} that is connected to this marker.
- *
- * @returns {PointData} that is connected to this marker
- */
-PointMarker.prototype.getPointData = function () {
-  return this._pointData;
-};
-
-/**
- *
- * @param {PointData} pointData
- */
-PointMarker.prototype.setPointData = function (pointData) {
-  this._pointData = pointData;
-};
-
-/**
- *
- * @returns {Point}
- */
-PointMarker.prototype.getCoordinates = function () {
-  return this._pointData.getPoint();
-};
-
-module.exports = PointMarker;
+"use strict";
+
+var AbstractMarker = require('./AbstractMarker');
+var PointData = require('../data/PointData');
+
+/**
+ * This class describes Google maps marker (connected to some specific point,
+ * but not to any element) that is visualized on the map.
+ *
+ * @param {IdentifiedElement} params.element
+ * @param {AbstractCustomMap} params.map
+ * @param {function|function[]} params.onclick
+ * @constructor
+ * @extends AbstractMarker
+ */
+function PointMarker(params) {
+  var self = this;
+  AbstractMarker.call(self, params);
+  self.setPointData(new PointData(self.getIdentifiedElement()));
+}
+
+PointMarker.prototype = Object.create(AbstractMarker.prototype);
+PointMarker.prototype.constructor = PointMarker;
+
+/**
+ *
+ * @returns {Promise<any>}
+ */
+PointMarker.prototype.init = function () {
+  var self = this;
+  return self._init().then(function () {
+    return self.show();
+  });
+};
+
+/**
+ * Returns identifier of the object.
+ *
+ * @returns {string} identifier of the object
+ */
+PointMarker.prototype.getId = function () {
+  return this.getPointData().getId();
+};
+
+/**
+ * Returns a {@link PointData} that is connected to this marker.
+ *
+ * @returns {PointData} that is connected to this marker
+ */
+PointMarker.prototype.getPointData = function () {
+  return this._pointData;
+};
+
+/**
+ *
+ * @param {PointData} pointData
+ */
+PointMarker.prototype.setPointData = function (pointData) {
+  this._pointData = pointData;
+};
+
+/**
+ *
+ * @returns {Point}
+ */
+PointMarker.prototype.getCoordinates = function () {
+  return this._pointData.getPoint();
+};
+
+module.exports = PointMarker;
diff --git a/frontend-js/src/main/js/map/marker/ReactionMarker.js b/frontend-js/src/main/js/map/marker/ReactionMarker.js
index d7c793a7c81c03d5550202fc0a10a95f05155d38..e062ed356af1e7c93235413e4d1a7df4aa7dfba1 100644
--- a/frontend-js/src/main/js/map/marker/ReactionMarker.js
+++ b/frontend-js/src/main/js/map/marker/ReactionMarker.js
@@ -1,65 +1,65 @@
-"use strict";
-
-var AbstractMarker = require('./AbstractMarker');
-var Point = require('../canvas/Point');
-
-/**
- * This class describes Google maps marker (connected to {@link Reaction}) that
- * is visualized on the map.
- *
- * @param {IdentifiedElement} params.element
- * @param {AbstractCustomMap} params.map
- * @param {function|function[]} params.onclick
- * @constructor
- * @extends AbstractMarker
- */
-function ReactionMarker(params) {
-  AbstractMarker.call(this, params);
-}
-
-ReactionMarker.prototype = Object.create(AbstractMarker.prototype);
-ReactionMarker.prototype.constructor = ReactionMarker;
-
-/**
- *
- * @returns {PromiseLike<any>}
- */
-ReactionMarker.prototype.init = function () {
-  var self = this;
-  return self.getCustomMap().getModel().getReactionById(self.getId()).then(function (reactionData) {
-    self.setReactionData(reactionData);
-    return self._init();
-  }).then(function () {
-    return self.show();
-  });
-};
-
-/**
- * Returns {@link Reaction} data for this marker.
- *
- * @returns {Reaction} data for this marker
- */
-ReactionMarker.prototype.getReactionData = function () {
-  return this._reactionData;
-};
-
-/**
- * Sets {@link Reaction} data for this marker.
- *
- * @param {Reaction} data
- *           data for this marker
- */
-ReactionMarker.prototype.setReactionData = function (data) {
-  this._reactionData = data;
-};
-
-/**
- * Returns coordinates where marker is pointing.
- *
- * @returns {Point} - coordinates where marker is pointing
- */
-ReactionMarker.prototype.getCoordinates = function () {
-  return new Point(this._reactionData.getCenter().x, this._reactionData.getCenter().y);
-};
-
-module.exports = ReactionMarker;
+"use strict";
+
+var AbstractMarker = require('./AbstractMarker');
+var Point = require('../canvas/Point');
+
+/**
+ * This class describes Google maps marker (connected to {@link Reaction}) that
+ * is visualized on the map.
+ *
+ * @param {IdentifiedElement} params.element
+ * @param {AbstractCustomMap} params.map
+ * @param {function|function[]} params.onclick
+ * @constructor
+ * @extends AbstractMarker
+ */
+function ReactionMarker(params) {
+  AbstractMarker.call(this, params);
+}
+
+ReactionMarker.prototype = Object.create(AbstractMarker.prototype);
+ReactionMarker.prototype.constructor = ReactionMarker;
+
+/**
+ *
+ * @returns {PromiseLike<any>}
+ */
+ReactionMarker.prototype.init = function () {
+  var self = this;
+  return self.getCustomMap().getModel().getReactionById(self.getId()).then(function (reactionData) {
+    self.setReactionData(reactionData);
+    return self._init();
+  }).then(function () {
+    return self.show();
+  });
+};
+
+/**
+ * Returns {@link Reaction} data for this marker.
+ *
+ * @returns {Reaction} data for this marker
+ */
+ReactionMarker.prototype.getReactionData = function () {
+  return this._reactionData;
+};
+
+/**
+ * Sets {@link Reaction} data for this marker.
+ *
+ * @param {Reaction} data
+ *           data for this marker
+ */
+ReactionMarker.prototype.setReactionData = function (data) {
+  this._reactionData = data;
+};
+
+/**
+ * Returns coordinates where marker is pointing.
+ *
+ * @returns {Point} - coordinates where marker is pointing
+ */
+ReactionMarker.prototype.getCoordinates = function () {
+  return new Point(this._reactionData.getCenter().x, this._reactionData.getCenter().y);
+};
+
+module.exports = ReactionMarker;
diff --git a/frontend-js/src/main/js/map/overlay/AbstractDbOverlay.js b/frontend-js/src/main/js/map/overlay/AbstractDbOverlay.js
index 85906d905631f2323f1f1d6e243da80ff87f7c49..aedfaaa67dfbab6ad3ed8636a30b2dc31c471d89 100644
--- a/frontend-js/src/main/js/map/overlay/AbstractDbOverlay.js
+++ b/frontend-js/src/main/js/map/overlay/AbstractDbOverlay.js
@@ -1,318 +1,318 @@
-"use strict";
-
-/* exported logger */
-
-// noinspection JSUnusedLocalSymbols
-var logger = require('../../logger');
-
-var Promise = require("bluebird");
-
-var IdentifiedElement = require('../data/IdentifiedElement');
-var ObjectWithListeners = require('../../ObjectWithListeners');
-var Point= require('../canvas/Point');
-
-var ServerConnector = require('../../ServerConnector');
-
-function AbstractDbOverlay(params) {
-  // call super constructor
-  ObjectWithListeners.call(this);
-
-  if (params.map === undefined) {
-    throw new Error("map param must be defined");
-  }
-
-  this.setName(params.name);
-  this.setMap(params.map);
-
-  this.setAllowSearchById(params.allowSearchById);
-  this.setAllowGeneralSearch(params.allowGeneralSearch);
-
-  this.setIconType(params.iconType);
-  this.setIconStart(params.iconColorStart);
-
-  this._elementsByQuery = [];
-  this._elementsByQuery[""] = [];
-  this.registerListenerType('onSearch');
-  this.registerListenerType('onClear');
-  this.registerListenerType('onTargetVisibilityChange');
-
-  this.setQueries([]);
-
-  this.mapOverlays = {
-    ALIAS: [],
-    REACTION: [],
-    POINT: []
-  };
-
-}
-
-AbstractDbOverlay.prototype = Object.create(ObjectWithListeners.prototype);
-AbstractDbOverlay.prototype.constructor = AbstractDbOverlay;
-
-AbstractDbOverlay.QueryType = {
-  SEARCH_BY_COORDINATES: "SEARCH_BY_COORDINATES",
-  SEARCH_BY_TARGET: "SEARCH_BY_TARGET",
-  SEARCH_BY_QUERY: "SEARCH_BY_QUERY"
-};
-
-AbstractDbOverlay.prototype.encodeQuery = function (type, arg0, arg1, arg2) {
-  if (type === AbstractDbOverlay.QueryType.SEARCH_BY_COORDINATES) {
-    var modelId = arg0;
-    var coordinates = arg1;
-    // noinspection UnnecessaryLocalVariableJS
-    var zoom = arg2;
-    return JSON.stringify({
-      type: type,
-      modelId: modelId,
-      coordinates: coordinates,
-      zoom: zoom
-    });
-  } else if (type === AbstractDbOverlay.QueryType.SEARCH_BY_TARGET) {
-    // noinspection UnnecessaryLocalVariableJS
-    var target = arg0;
-    return JSON.stringify({
-      type: type,
-      target: target
-    });
-  } else if (type === AbstractDbOverlay.QueryType.SEARCH_BY_QUERY) {
-    var query = arg0;
-    // noinspection UnnecessaryLocalVariableJS
-    var perfect = arg1;
-    return JSON.stringify({
-      type: type,
-      query: query,
-      perfect: perfect
-    });
-  } else {
-    throw new Error("Unknown query type: " + type);
-  }
-};
-
-AbstractDbOverlay.prototype.decodeQuery = function (query) {
-  return JSON.parse(query);
-};
-
-AbstractDbOverlay.prototype.searchByQuery = function (originalQuery, perfect, fitBounds) {
-  var self = this;
-  var query = self.encodeQuery(AbstractDbOverlay.QueryType.SEARCH_BY_QUERY, originalQuery, perfect);
-  ServerConnector.getSessionData().setQuery({
-    type: self.getName(),
-    query: query
-  });
-
-  var res;
-  var encodedQueries = [];
-
-  var resultPromise;
-  if (originalQuery.indexOf(";") >= 0) {
-    var queries = self.splitQuery(originalQuery);
-
-    var promises = [];
-    for (var i = 0; i < queries.length; i++) {
-      encodedQueries.push(self.encodeQuery(AbstractDbOverlay.QueryType.SEARCH_BY_QUERY, queries[i], perfect));
-      promises.push(self.searchBySingleQuery(queries[i], perfect));
-    }
-    resultPromise = Promise.all(promises);
-  } else {
-    resultPromise = self.searchBySingleQuery(originalQuery, perfect).then(function (results) {
-      if (results.length > 0) {
-        encodedQueries.push(query);
-        return [results];
-      } else {
-        var queries = self.splitQuery(originalQuery);
-
-        var promises = [];
-        for (var i = 0; i < queries.length; i++) {
-          encodedQueries.push(self.encodeQuery(AbstractDbOverlay.QueryType.SEARCH_BY_QUERY, queries[i], perfect));
-          promises.push(self.searchBySingleQuery(queries[i], perfect));
-        }
-
-        return Promise.all(promises);
-      }
-    });
-  }
-  return resultPromise.then(function (results) {
-    self.setQueries(encodedQueries);
-    res = results;
-    return self.callListeners('onSearch', {
-      fitBounds: fitBounds,
-      identifiedElements: res,
-      type: AbstractDbOverlay.QueryType.SEARCH_BY_QUERY
-    });
-  }).then(function () {
-    return res;
-  });
-}
-;
-
-AbstractDbOverlay.prototype.setQueries = function (queries) {
-  this._queries = queries;
-};
-
-AbstractDbOverlay.prototype.getQueries = function () {
-  return this._queries;
-};
-
-AbstractDbOverlay.prototype.createIdentifiedElementsForTargetingClass = function (targetingElement, colourId) {
-  var self = this;
-  var result = [];
-  var iconCounter = 1;
-  var targets = targetingElement.getTargets();
-  for (var k = 0; k < targets.length; k++) {
-    var target = targets[k];
-    if (target.isVisible()) {
-      var elements = target.getTargetElements();
-      for (var l = 0; l < elements.length; l++) {
-        var element = elements[l];
-        var ie = new IdentifiedElement(element);
-        if (element.getType() === "ALIAS") {
-          ie.setIcon(self.getIcon(colourId, iconCounter));
-        } else if (element.getType() !== "REACTION") {
-          throw new Error("Unknown element type: " + element.getType());
-        }
-        result.push(ie);
-      }
-    }
-    iconCounter++;
-  }
-  return result;
-};
-
-/**
- * @returns {PromiseLike}
- */
-AbstractDbOverlay.prototype.refresh = function () {
-  throw new Error("Refreshing shouldn't be called");
-};
-
-/**
- *
- * @param {IdentifiedElement} element
- * @returns {Promise}
- */
-AbstractDbOverlay.prototype.searchByTarget = function (element) {
-  throw new Error("Not implemented");
-};
-
-AbstractDbOverlay.prototype.searchByEncodedQuery = function (originalQuery, fitBounds) {
-  var query = this.decodeQuery(originalQuery);
-  query.fitBounds = fitBounds;
-  if (query.type === AbstractDbOverlay.QueryType.SEARCH_BY_QUERY) {
-    return this.searchByQuery(query.query, query.perfect);
-  } else if (query.type === AbstractDbOverlay.QueryType.SEARCH_BY_TARGET) {
-    return this.searchByTarget(new IdentifiedElement(query.target));
-  } else if (query.type === AbstractDbOverlay.QueryType.SEARCH_BY_COORDINATES) {
-    query.coordinates = new Point(query.coordinates.x, query.coordinates.y);
-    if (this.getMap().getSubmapById(query.modelId) === null) {
-      //this can happen when cached data comes from project that was removed and something else
-      //was uploaded with the same name
-      logger.warn("Invalid search query. Model doesn't exist: " + query.modelId);
-      return Promise.resolve();
-    }
-    return this.searchByCoordinates(query);
-  } else {
-    throw new Error("Unknown type of query: " + query.type);
-  }
-};
-
-AbstractDbOverlay.prototype.clear = function () {
-  var self = this;
-  return self.searchByQuery("").then(function () {
-    return self.callListeners('onClear');
-  });
-};
-
-/**
- * Returns true if overlay allows to get general data for element.
- */
-AbstractDbOverlay.prototype.allowGeneralSearch = function () {
-  return this._allowGeneralSearch;
-};
-
-/**
- * Returns true if overlay allows to get data for element by search id.
- */
-AbstractDbOverlay.prototype.allowSearchById = function () {
-  return this._allowSearchById;
-};
-
-AbstractDbOverlay.prototype.setMap = function (map) {
-  this._map = map;
-};
-
-AbstractDbOverlay.prototype.getMap = function () {
-  return this._map;
-};
-
-AbstractDbOverlay.prototype.setName = function (name) {
-  this.name = name;
-};
-
-AbstractDbOverlay.prototype.getName = function () {
-  return this.name;
-};
-
-AbstractDbOverlay.prototype.setAllowSearchById = function (allowSearchById) {
-  // configure if the overlay can contain detailed data about elements that
-  // should be visualized in detailed mode of the Info Window
-  if (typeof allowSearchById === "boolean") {
-    this._allowSearchById = allowSearchById;
-  } else if (allowSearchById === undefined) {
-    this._allowSearchById = false;
-  } else {
-    throw new Error("Unknown type of allowSearchById: " + allowSearchById);
-  }
-};
-
-AbstractDbOverlay.prototype.setAllowGeneralSearch = function (allowGeneralSearch) {
-  if (typeof allowGeneralSearch === "boolean") {
-    this._allowGeneralSearch = allowGeneralSearch;
-  } else if (allowGeneralSearch === undefined) {
-    this._allowGeneralSearch = false;
-  } else {
-    throw new Error("Unknown type of allowSearchById: " + allowGeneralSearch);
-  }
-};
-
-AbstractDbOverlay.prototype.setIconType = function (iconType) {
-  this._iconType = iconType;
-};
-AbstractDbOverlay.prototype.setIconStart = function (iconStart) {
-  this._iconStart = iconStart;
-};
-
-AbstractDbOverlay.IconColors = ["red", "blue", "green", "purple", "yellow", "pink", "paleblue", "brown", "orange"];
-
-AbstractDbOverlay.prototype.getColor = function (colorId) {
-  var id = colorId + this._iconStart;
-  id %= AbstractDbOverlay.IconColors.length;
-  return AbstractDbOverlay.IconColors[id];
-};
-
-AbstractDbOverlay.prototype.getIcon = function (colorId, id) {
-  var suffix = "_" + id;
-  if (id >= 100 || id === undefined) {
-    suffix = "";
-  }
-  var color = this.getColor(colorId);
-  return "marker/" + this._iconType + "/" + this._iconType + "_" + color + suffix + ".png";
-};
-
-AbstractDbOverlay.prototype.splitQuery = function (query, useFullName) {
-  var result = [];
-  if (query.indexOf(";") >= 0) {
-    result = query.split(";");
-  } else {
-    result = query.split(",");
-  }
-
-  for (var i = 0; i < result.length; i++) {
-    result[i] = result[i].trim();
-  }
-  if (result.length > 1 && useFullName) {
-    result.push(query);
-  }
-  return result;
-};
-
-module.exports = AbstractDbOverlay;
+"use strict";
+
+/* exported logger */
+
+// noinspection JSUnusedLocalSymbols
+var logger = require('../../logger');
+
+var Promise = require("bluebird");
+
+var IdentifiedElement = require('../data/IdentifiedElement');
+var ObjectWithListeners = require('../../ObjectWithListeners');
+var Point= require('../canvas/Point');
+
+var ServerConnector = require('../../ServerConnector');
+
+function AbstractDbOverlay(params) {
+  // call super constructor
+  ObjectWithListeners.call(this);
+
+  if (params.map === undefined) {
+    throw new Error("map param must be defined");
+  }
+
+  this.setName(params.name);
+  this.setMap(params.map);
+
+  this.setAllowSearchById(params.allowSearchById);
+  this.setAllowGeneralSearch(params.allowGeneralSearch);
+
+  this.setIconType(params.iconType);
+  this.setIconStart(params.iconColorStart);
+
+  this._elementsByQuery = [];
+  this._elementsByQuery[""] = [];
+  this.registerListenerType('onSearch');
+  this.registerListenerType('onClear');
+  this.registerListenerType('onTargetVisibilityChange');
+
+  this.setQueries([]);
+
+  this.mapOverlays = {
+    ALIAS: [],
+    REACTION: [],
+    POINT: []
+  };
+
+}
+
+AbstractDbOverlay.prototype = Object.create(ObjectWithListeners.prototype);
+AbstractDbOverlay.prototype.constructor = AbstractDbOverlay;
+
+AbstractDbOverlay.QueryType = {
+  SEARCH_BY_COORDINATES: "SEARCH_BY_COORDINATES",
+  SEARCH_BY_TARGET: "SEARCH_BY_TARGET",
+  SEARCH_BY_QUERY: "SEARCH_BY_QUERY"
+};
+
+AbstractDbOverlay.prototype.encodeQuery = function (type, arg0, arg1, arg2) {
+  if (type === AbstractDbOverlay.QueryType.SEARCH_BY_COORDINATES) {
+    var modelId = arg0;
+    var coordinates = arg1;
+    // noinspection UnnecessaryLocalVariableJS
+    var zoom = arg2;
+    return JSON.stringify({
+      type: type,
+      modelId: modelId,
+      coordinates: coordinates,
+      zoom: zoom
+    });
+  } else if (type === AbstractDbOverlay.QueryType.SEARCH_BY_TARGET) {
+    // noinspection UnnecessaryLocalVariableJS
+    var target = arg0;
+    return JSON.stringify({
+      type: type,
+      target: target
+    });
+  } else if (type === AbstractDbOverlay.QueryType.SEARCH_BY_QUERY) {
+    var query = arg0;
+    // noinspection UnnecessaryLocalVariableJS
+    var perfect = arg1;
+    return JSON.stringify({
+      type: type,
+      query: query,
+      perfect: perfect
+    });
+  } else {
+    throw new Error("Unknown query type: " + type);
+  }
+};
+
+AbstractDbOverlay.prototype.decodeQuery = function (query) {
+  return JSON.parse(query);
+};
+
+AbstractDbOverlay.prototype.searchByQuery = function (originalQuery, perfect, fitBounds) {
+  var self = this;
+  var query = self.encodeQuery(AbstractDbOverlay.QueryType.SEARCH_BY_QUERY, originalQuery, perfect);
+  ServerConnector.getSessionData().setQuery({
+    type: self.getName(),
+    query: query
+  });
+
+  var res;
+  var encodedQueries = [];
+
+  var resultPromise;
+  if (originalQuery.indexOf(";") >= 0) {
+    var queries = self.splitQuery(originalQuery);
+
+    var promises = [];
+    for (var i = 0; i < queries.length; i++) {
+      encodedQueries.push(self.encodeQuery(AbstractDbOverlay.QueryType.SEARCH_BY_QUERY, queries[i], perfect));
+      promises.push(self.searchBySingleQuery(queries[i], perfect));
+    }
+    resultPromise = Promise.all(promises);
+  } else {
+    resultPromise = self.searchBySingleQuery(originalQuery, perfect).then(function (results) {
+      if (results.length > 0) {
+        encodedQueries.push(query);
+        return [results];
+      } else {
+        var queries = self.splitQuery(originalQuery);
+
+        var promises = [];
+        for (var i = 0; i < queries.length; i++) {
+          encodedQueries.push(self.encodeQuery(AbstractDbOverlay.QueryType.SEARCH_BY_QUERY, queries[i], perfect));
+          promises.push(self.searchBySingleQuery(queries[i], perfect));
+        }
+
+        return Promise.all(promises);
+      }
+    });
+  }
+  return resultPromise.then(function (results) {
+    self.setQueries(encodedQueries);
+    res = results;
+    return self.callListeners('onSearch', {
+      fitBounds: fitBounds,
+      identifiedElements: res,
+      type: AbstractDbOverlay.QueryType.SEARCH_BY_QUERY
+    });
+  }).then(function () {
+    return res;
+  });
+}
+;
+
+AbstractDbOverlay.prototype.setQueries = function (queries) {
+  this._queries = queries;
+};
+
+AbstractDbOverlay.prototype.getQueries = function () {
+  return this._queries;
+};
+
+AbstractDbOverlay.prototype.createIdentifiedElementsForTargetingClass = function (targetingElement, colourId) {
+  var self = this;
+  var result = [];
+  var iconCounter = 1;
+  var targets = targetingElement.getTargets();
+  for (var k = 0; k < targets.length; k++) {
+    var target = targets[k];
+    if (target.isVisible()) {
+      var elements = target.getTargetElements();
+      for (var l = 0; l < elements.length; l++) {
+        var element = elements[l];
+        var ie = new IdentifiedElement(element);
+        if (element.getType() === "ALIAS") {
+          ie.setIcon(self.getIcon(colourId, iconCounter));
+        } else if (element.getType() !== "REACTION") {
+          throw new Error("Unknown element type: " + element.getType());
+        }
+        result.push(ie);
+      }
+    }
+    iconCounter++;
+  }
+  return result;
+};
+
+/**
+ * @returns {PromiseLike}
+ */
+AbstractDbOverlay.prototype.refresh = function () {
+  throw new Error("Refreshing shouldn't be called");
+};
+
+/**
+ *
+ * @param {IdentifiedElement} element
+ * @returns {Promise}
+ */
+AbstractDbOverlay.prototype.searchByTarget = function (element) {
+  throw new Error("Not implemented");
+};
+
+AbstractDbOverlay.prototype.searchByEncodedQuery = function (originalQuery, fitBounds) {
+  var query = this.decodeQuery(originalQuery);
+  query.fitBounds = fitBounds;
+  if (query.type === AbstractDbOverlay.QueryType.SEARCH_BY_QUERY) {
+    return this.searchByQuery(query.query, query.perfect);
+  } else if (query.type === AbstractDbOverlay.QueryType.SEARCH_BY_TARGET) {
+    return this.searchByTarget(new IdentifiedElement(query.target));
+  } else if (query.type === AbstractDbOverlay.QueryType.SEARCH_BY_COORDINATES) {
+    query.coordinates = new Point(query.coordinates.x, query.coordinates.y);
+    if (this.getMap().getSubmapById(query.modelId) === null) {
+      //this can happen when cached data comes from project that was removed and something else
+      //was uploaded with the same name
+      logger.warn("Invalid search query. Model doesn't exist: " + query.modelId);
+      return Promise.resolve();
+    }
+    return this.searchByCoordinates(query);
+  } else {
+    throw new Error("Unknown type of query: " + query.type);
+  }
+};
+
+AbstractDbOverlay.prototype.clear = function () {
+  var self = this;
+  return self.searchByQuery("").then(function () {
+    return self.callListeners('onClear');
+  });
+};
+
+/**
+ * Returns true if overlay allows to get general data for element.
+ */
+AbstractDbOverlay.prototype.allowGeneralSearch = function () {
+  return this._allowGeneralSearch;
+};
+
+/**
+ * Returns true if overlay allows to get data for element by search id.
+ */
+AbstractDbOverlay.prototype.allowSearchById = function () {
+  return this._allowSearchById;
+};
+
+AbstractDbOverlay.prototype.setMap = function (map) {
+  this._map = map;
+};
+
+AbstractDbOverlay.prototype.getMap = function () {
+  return this._map;
+};
+
+AbstractDbOverlay.prototype.setName = function (name) {
+  this.name = name;
+};
+
+AbstractDbOverlay.prototype.getName = function () {
+  return this.name;
+};
+
+AbstractDbOverlay.prototype.setAllowSearchById = function (allowSearchById) {
+  // configure if the overlay can contain detailed data about elements that
+  // should be visualized in detailed mode of the Info Window
+  if (typeof allowSearchById === "boolean") {
+    this._allowSearchById = allowSearchById;
+  } else if (allowSearchById === undefined) {
+    this._allowSearchById = false;
+  } else {
+    throw new Error("Unknown type of allowSearchById: " + allowSearchById);
+  }
+};
+
+AbstractDbOverlay.prototype.setAllowGeneralSearch = function (allowGeneralSearch) {
+  if (typeof allowGeneralSearch === "boolean") {
+    this._allowGeneralSearch = allowGeneralSearch;
+  } else if (allowGeneralSearch === undefined) {
+    this._allowGeneralSearch = false;
+  } else {
+    throw new Error("Unknown type of allowSearchById: " + allowGeneralSearch);
+  }
+};
+
+AbstractDbOverlay.prototype.setIconType = function (iconType) {
+  this._iconType = iconType;
+};
+AbstractDbOverlay.prototype.setIconStart = function (iconStart) {
+  this._iconStart = iconStart;
+};
+
+AbstractDbOverlay.IconColors = ["red", "blue", "green", "purple", "yellow", "pink", "paleblue", "brown", "orange"];
+
+AbstractDbOverlay.prototype.getColor = function (colorId) {
+  var id = colorId + this._iconStart;
+  id %= AbstractDbOverlay.IconColors.length;
+  return AbstractDbOverlay.IconColors[id];
+};
+
+AbstractDbOverlay.prototype.getIcon = function (colorId, id) {
+  var suffix = "_" + id;
+  if (id >= 100 || id === undefined) {
+    suffix = "";
+  }
+  var color = this.getColor(colorId);
+  return "marker/" + this._iconType + "/" + this._iconType + "_" + color + suffix + ".png";
+};
+
+AbstractDbOverlay.prototype.splitQuery = function (query, useFullName) {
+  var result = [];
+  if (query.indexOf(";") >= 0) {
+    result = query.split(";");
+  } else {
+    result = query.split(",");
+  }
+
+  for (var i = 0; i < result.length; i++) {
+    result[i] = result[i].trim();
+  }
+  if (result.length > 1 && useFullName) {
+    result.push(query);
+  }
+  return result;
+};
+
+module.exports = AbstractDbOverlay;
diff --git a/frontend-js/src/main/js/map/overlay/AbstractTargettingDbOverlay.js b/frontend-js/src/main/js/map/overlay/AbstractTargettingDbOverlay.js
index 50540c08d777d15b6e3e2075b3e7b1b54e5efd16..c357e9cabd5175f13ef53a07c513843abc97b73d 100644
--- a/frontend-js/src/main/js/map/overlay/AbstractTargettingDbOverlay.js
+++ b/frontend-js/src/main/js/map/overlay/AbstractTargettingDbOverlay.js
@@ -1,187 +1,187 @@
-"use strict";
-
-/* exported logger */
-
-var logger = require('../../logger');
-
-var Promise = require("bluebird");
-
-var IdentifiedElement = require('../data/IdentifiedElement');
-var AbstractDbOverlay = require('./AbstractDbOverlay');
-
-function AbstractTargettingDbOverlay(params) {
-  // call super constructor
-  AbstractDbOverlay.call(this, params);
-}
-
-AbstractTargettingDbOverlay.prototype = Object.create(AbstractDbOverlay.prototype);
-AbstractTargettingDbOverlay.prototype.constructor = AbstractTargettingDbOverlay;
-
-AbstractTargettingDbOverlay.prototype.getElementsByQuery = function (query) {
-  var self = this;
-  return new Promise(function (resolve) {
-    var i;
-    var queryId = null;
-    var queries = self.getQueries();
-    for (i = 0; i < queries.length; i++) {
-      if (queries[i] === query) {
-        queryId = i;
-      }
-    }
-    if (queryId === null) {
-      throw new Error("Invalid query: " + query);
-    }
-    var colourId = queryId;
-    var elements = self._elementsByQuery[query];
-
-    var result = [];
-    if (elements.length > 0) {
-      if (elements.length > 1) {
-        logger.warn("More than one element per query not implemented");
-      }
-      var element = elements[0];
-      result.element = element;
-      var iconCounter = 1;
-      for (i = 0; i < element.getTargets().length; i++) {
-        var target = element.getTargets()[i];
-        var icon = self.getIcon(colourId, iconCounter++);
-        if (target.getTargetElements().length === 0) {
-          icon = null;
-        }
-        result.push({
-          element: target,
-          icon: icon
-        });
-      }
-    }
-    resolve(result);
-  });
-};
-
-AbstractTargettingDbOverlay.prototype.searchBySingleQuery = function (originalQuery) {
-  var self = this;
-  var query = self.encodeQuery(AbstractDbOverlay.QueryType.SEARCH_BY_QUERY, originalQuery);
-  if (self._elementsByQuery[query] !== undefined) {
-    return Promise.resolve(self._elementsByQuery[query]);
-  } else {
-    return self.getElementsByQueryFromServer({
-      query: originalQuery
-    }).then(function (elements) {
-      self._elementsByQuery[query] = elements;
-
-      var identifiedElements = [];
-      for (var i = 0; i < elements.length; i++) {
-        var targets = elements[i].getTargets();
-        for (var j = 0; j < targets.length; j++) {
-          var target = targets[j];
-          for (var k = 0; k < target.targetElements; k++) {
-            identifiedElements.push(new IdentifiedElement(target.targetElements[i]));
-          }
-        }
-      }
-      return self.getMap().fetchIdentifiedElements(identifiedElements, true);
-    }).then(function () {
-      return self._elementsByQuery[query];
-    });
-  }
-};
-
-AbstractTargettingDbOverlay.prototype.getIdentifiedElements = function () {
-  var self = this;
-
-  return new Promise(function (resolve) {
-    var queries = self.getQueries();
-    var result = [];
-    var colourId = 0;
-    for (var i = 0; i < queries.length; i++) {
-      var query = queries[i];
-      var elements = self._elementsByQuery[query];
-
-      for (var j = 0; j < elements.length; j++) {
-        var element = elements[j];
-
-        var targetElements = self.createIdentifiedElementsForTargetingClass(element, colourId);
-
-        result.push.apply(result, targetElements);
-
-        colourId++;
-      }
-    }
-    resolve(result);
-  });
-};
-
-/**
- *
- * @param {IdentifiedElement} element
- * @returns {Promise}
- */
-AbstractTargettingDbOverlay.prototype.searchByTarget = function (element) {
-  return this.searchNamesByTarget(element);
-};
-
-AbstractTargettingDbOverlay.prototype.searchNamesByTarget = function (element) {
-  var self = this;
-  var query = self.encodeQuery(AbstractDbOverlay.QueryType.SEARCH_BY_TARGET, element);
-
-  if (self._elementsByQuery[query] !== undefined) {
-    return Promise.resolve(self._elementsByQuery[query]);
-  } else {
-    return self.getNamesByTargetFromServer({
-      target: element
-    }).then(function (drugNames) {
-      self._elementsByQuery[query] = drugNames;
-      return self._elementsByQuery[query];
-    });
-  }
-};
-
-
-AbstractTargettingDbOverlay.prototype.getDetailDataByIdentifiedElement = function (element, general) {
-  var self = this;
-  if (general) {
-    return self.searchNamesByTarget(element).then(function (names) {
-      var promises = [];
-      names.forEach(function (name) {
-        promises.push(self.searchBySingleQuery(name));
-      });
-      return Promise.all(promises);
-    }).then(function (drugs) {
-      var result = [];
-      drugs.forEach(function (drugList) {
-        drugList.forEach(function (drug) {
-          result.push(drug);
-        });
-      });
-      return result;
-    });
-  } else {
-    return new Promise(function (resolve) {
-      var drugNames = [];
-      var result = [];
-      var queries = self.getQueries();
-      for (var i = 0; i < queries.length; i++) {
-        var drugs = self._elementsByQuery[queries[i]];
-        if (drugs === undefined) {
-          drugs = [];
-        }
-        for (var j = 0; j < drugs.length; j++) {
-          var drug = drugs[j];
-          var targets = drug.getTargets();
-          for (var k = 0; k < targets.length; k++) {
-            var elements = targets[k].getTargetElements();
-            for (var l = 0; l < elements.length; l++) {
-              if (element.equals(elements[l]) && drugNames[drug.getName()] === undefined) {
-                result.push(drug);
-                drugNames[drug.getName()] = true;
-              }
-            }
-          }
-        }
-      }
-      resolve(result);
-    });
-  }
-};
-
-module.exports = AbstractTargettingDbOverlay;
+"use strict";
+
+/* exported logger */
+
+var logger = require('../../logger');
+
+var Promise = require("bluebird");
+
+var IdentifiedElement = require('../data/IdentifiedElement');
+var AbstractDbOverlay = require('./AbstractDbOverlay');
+
+function AbstractTargettingDbOverlay(params) {
+  // call super constructor
+  AbstractDbOverlay.call(this, params);
+}
+
+AbstractTargettingDbOverlay.prototype = Object.create(AbstractDbOverlay.prototype);
+AbstractTargettingDbOverlay.prototype.constructor = AbstractTargettingDbOverlay;
+
+AbstractTargettingDbOverlay.prototype.getElementsByQuery = function (query) {
+  var self = this;
+  return new Promise(function (resolve) {
+    var i;
+    var queryId = null;
+    var queries = self.getQueries();
+    for (i = 0; i < queries.length; i++) {
+      if (queries[i] === query) {
+        queryId = i;
+      }
+    }
+    if (queryId === null) {
+      throw new Error("Invalid query: " + query);
+    }
+    var colourId = queryId;
+    var elements = self._elementsByQuery[query];
+
+    var result = [];
+    if (elements.length > 0) {
+      if (elements.length > 1) {
+        logger.warn("More than one element per query not implemented");
+      }
+      var element = elements[0];
+      result.element = element;
+      var iconCounter = 1;
+      for (i = 0; i < element.getTargets().length; i++) {
+        var target = element.getTargets()[i];
+        var icon = self.getIcon(colourId, iconCounter++);
+        if (target.getTargetElements().length === 0) {
+          icon = null;
+        }
+        result.push({
+          element: target,
+          icon: icon
+        });
+      }
+    }
+    resolve(result);
+  });
+};
+
+AbstractTargettingDbOverlay.prototype.searchBySingleQuery = function (originalQuery) {
+  var self = this;
+  var query = self.encodeQuery(AbstractDbOverlay.QueryType.SEARCH_BY_QUERY, originalQuery);
+  if (self._elementsByQuery[query] !== undefined) {
+    return Promise.resolve(self._elementsByQuery[query]);
+  } else {
+    return self.getElementsByQueryFromServer({
+      query: originalQuery
+    }).then(function (elements) {
+      self._elementsByQuery[query] = elements;
+
+      var identifiedElements = [];
+      for (var i = 0; i < elements.length; i++) {
+        var targets = elements[i].getTargets();
+        for (var j = 0; j < targets.length; j++) {
+          var target = targets[j];
+          for (var k = 0; k < target.targetElements; k++) {
+            identifiedElements.push(new IdentifiedElement(target.targetElements[i]));
+          }
+        }
+      }
+      return self.getMap().fetchIdentifiedElements(identifiedElements, true);
+    }).then(function () {
+      return self._elementsByQuery[query];
+    });
+  }
+};
+
+AbstractTargettingDbOverlay.prototype.getIdentifiedElements = function () {
+  var self = this;
+
+  return new Promise(function (resolve) {
+    var queries = self.getQueries();
+    var result = [];
+    var colourId = 0;
+    for (var i = 0; i < queries.length; i++) {
+      var query = queries[i];
+      var elements = self._elementsByQuery[query];
+
+      for (var j = 0; j < elements.length; j++) {
+        var element = elements[j];
+
+        var targetElements = self.createIdentifiedElementsForTargetingClass(element, colourId);
+
+        result.push.apply(result, targetElements);
+
+        colourId++;
+      }
+    }
+    resolve(result);
+  });
+};
+
+/**
+ *
+ * @param {IdentifiedElement} element
+ * @returns {Promise}
+ */
+AbstractTargettingDbOverlay.prototype.searchByTarget = function (element) {
+  return this.searchNamesByTarget(element);
+};
+
+AbstractTargettingDbOverlay.prototype.searchNamesByTarget = function (element) {
+  var self = this;
+  var query = self.encodeQuery(AbstractDbOverlay.QueryType.SEARCH_BY_TARGET, element);
+
+  if (self._elementsByQuery[query] !== undefined) {
+    return Promise.resolve(self._elementsByQuery[query]);
+  } else {
+    return self.getNamesByTargetFromServer({
+      target: element
+    }).then(function (drugNames) {
+      self._elementsByQuery[query] = drugNames;
+      return self._elementsByQuery[query];
+    });
+  }
+};
+
+
+AbstractTargettingDbOverlay.prototype.getDetailDataByIdentifiedElement = function (element, general) {
+  var self = this;
+  if (general) {
+    return self.searchNamesByTarget(element).then(function (names) {
+      var promises = [];
+      names.forEach(function (name) {
+        promises.push(self.searchBySingleQuery(name));
+      });
+      return Promise.all(promises);
+    }).then(function (drugs) {
+      var result = [];
+      drugs.forEach(function (drugList) {
+        drugList.forEach(function (drug) {
+          result.push(drug);
+        });
+      });
+      return result;
+    });
+  } else {
+    return new Promise(function (resolve) {
+      var drugNames = [];
+      var result = [];
+      var queries = self.getQueries();
+      for (var i = 0; i < queries.length; i++) {
+        var drugs = self._elementsByQuery[queries[i]];
+        if (drugs === undefined) {
+          drugs = [];
+        }
+        for (var j = 0; j < drugs.length; j++) {
+          var drug = drugs[j];
+          var targets = drug.getTargets();
+          for (var k = 0; k < targets.length; k++) {
+            var elements = targets[k].getTargetElements();
+            for (var l = 0; l < elements.length; l++) {
+              if (element.equals(elements[l]) && drugNames[drug.getName()] === undefined) {
+                result.push(drug);
+                drugNames[drug.getName()] = true;
+              }
+            }
+          }
+        }
+      }
+      resolve(result);
+    });
+  }
+};
+
+module.exports = AbstractTargettingDbOverlay;
diff --git a/frontend-js/src/main/js/map/overlay/ChemicalDbOverlay.js b/frontend-js/src/main/js/map/overlay/ChemicalDbOverlay.js
index 778f9e8ba5e6af9dbce4ebb2f10911950da63f6d..e77a9894107b3fa667c3d8b4170b1ab4fa7bb3d8 100644
--- a/frontend-js/src/main/js/map/overlay/ChemicalDbOverlay.js
+++ b/frontend-js/src/main/js/map/overlay/ChemicalDbOverlay.js
@@ -1,30 +1,30 @@
-"use strict";
-
-/* exported logger */
-
-var logger = require('../../logger');
-
-var AbstractTargettingDbOverlay = require('./AbstractTargettingDbOverlay');
-
-var ServerConnector = require('../../ServerConnector');
-
-function ChemicalDbOverlay(params) {
-  params.iconType= "ball";
-  params.iconColorStart = 1;
-  // call super constructor
-  AbstractTargettingDbOverlay.call(this, params);
-  
-}
-
-ChemicalDbOverlay.prototype = Object.create(AbstractTargettingDbOverlay.prototype);
-ChemicalDbOverlay.prototype.constructor = ChemicalDbOverlay;
-
-ChemicalDbOverlay.prototype.getNamesByTargetFromServer = function(param) {
-  return ServerConnector.getChemicalNamesByTarget(param);
-};
-
-ChemicalDbOverlay.prototype.getElementsByQueryFromServer = function(param) {
-  return ServerConnector.getChemicalsByQuery(param);
-};
-
-module.exports = ChemicalDbOverlay;
+"use strict";
+
+/* exported logger */
+
+var logger = require('../../logger');
+
+var AbstractTargettingDbOverlay = require('./AbstractTargettingDbOverlay');
+
+var ServerConnector = require('../../ServerConnector');
+
+function ChemicalDbOverlay(params) {
+  params.iconType= "ball";
+  params.iconColorStart = 1;
+  // call super constructor
+  AbstractTargettingDbOverlay.call(this, params);
+  
+}
+
+ChemicalDbOverlay.prototype = Object.create(AbstractTargettingDbOverlay.prototype);
+ChemicalDbOverlay.prototype.constructor = ChemicalDbOverlay;
+
+ChemicalDbOverlay.prototype.getNamesByTargetFromServer = function(param) {
+  return ServerConnector.getChemicalNamesByTarget(param);
+};
+
+ChemicalDbOverlay.prototype.getElementsByQueryFromServer = function(param) {
+  return ServerConnector.getChemicalsByQuery(param);
+};
+
+module.exports = ChemicalDbOverlay;
diff --git a/frontend-js/src/main/js/map/overlay/CommentDbOverlay.js b/frontend-js/src/main/js/map/overlay/CommentDbOverlay.js
index 4c86c71aa82e99c614a9739745550451bbc43f9f..da24726b03fcd373e989671c7e623c7836e9dad8 100644
--- a/frontend-js/src/main/js/map/overlay/CommentDbOverlay.js
+++ b/frontend-js/src/main/js/map/overlay/CommentDbOverlay.js
@@ -1,85 +1,85 @@
-"use strict";
-
-/* exported logger */
-
-var Promise = require("bluebird");
-
-var AbstractDbOverlay = require('./AbstractDbOverlay');
-var ServerConnector = require('../../ServerConnector');
-
-var logger = require('../../logger');
-
-function CommentDbOverlay(params) {
-  // call super constructor
-  AbstractDbOverlay.call(this, params);
-
-  this._elements = [];
-  this._detailDataByIdentifiedElement = [];
-  this.registerListenerType('onRefresh');
-}
-
-CommentDbOverlay.prototype = Object.create(AbstractDbOverlay.prototype);
-CommentDbOverlay.prototype.constructor = CommentDbOverlay;
-
-CommentDbOverlay.prototype.refresh = function() {
-  var self = this;
-  return ServerConnector.getLightComments({}).then(function(comments) {
-    self._elements = comments;
-    return self.callListeners('onRefresh');
-  }).then(function() {
-    return self._elements;
-  });
-};
-
-CommentDbOverlay.prototype.addComment = function(newComment) {
-  var self = this;
-  self._elements.push(newComment);
-  return self.callListeners('onRefresh').then(function() {
-    return self._elements;
-  });
-};
-
-CommentDbOverlay.prototype.clear = function() {
-  var self = this;
-  self._elements = [];
-  self._detailDataByIdentifiedElement = [];
-  return self.callListeners('onClear');
-};
-
-CommentDbOverlay.prototype.getDetailDataByIdentifiedElement = function(element) {
-  var self = this;
-  var elementKey = element.getId() + "," + element.getType() + "," + element.getModelId();
-  if (this._detailDataByIdentifiedElement[elementKey] !== undefined) {
-    return Promise.resolve(this._detailDataByIdentifiedElement[elementKey]);
-  } else {
-    var coordinates;
-    if (element.getType() === "POINT") {
-      coordinates = element.getPoint().x.toFixed(2) + "," + element.getPoint().y.toFixed(2);
-    }
-    return ServerConnector.getComments({
-      elementId : element.getId(),
-      elementType : element.getType(),
-      coordinates : coordinates
-    }).then(function(comments) {
-      self._detailDataByIdentifiedElement[elementKey] = comments;
-      return comments;
-    });
-  }
-};
-
-CommentDbOverlay.prototype.getIdentifiedElements = function() {
-  var self = this;
-  return new Promise(function(resolve) {
-    var result = [];
-    for (var i = 0; i < self._elements.length; i++) {
-      // we return only elements that are pinned to the map and weren't removed
-      var comment = self._elements[i];
-      if (!comment.isRemoved() && comment.isPinned()) {
-        result.push(comment.getIdentifiedElement());
-      }
-    }
-    resolve(result);
-  });
-};
-
-module.exports = CommentDbOverlay;
+"use strict";
+
+/* exported logger */
+
+var Promise = require("bluebird");
+
+var AbstractDbOverlay = require('./AbstractDbOverlay');
+var ServerConnector = require('../../ServerConnector');
+
+var logger = require('../../logger');
+
+function CommentDbOverlay(params) {
+  // call super constructor
+  AbstractDbOverlay.call(this, params);
+
+  this._elements = [];
+  this._detailDataByIdentifiedElement = [];
+  this.registerListenerType('onRefresh');
+}
+
+CommentDbOverlay.prototype = Object.create(AbstractDbOverlay.prototype);
+CommentDbOverlay.prototype.constructor = CommentDbOverlay;
+
+CommentDbOverlay.prototype.refresh = function() {
+  var self = this;
+  return ServerConnector.getLightComments({}).then(function(comments) {
+    self._elements = comments;
+    return self.callListeners('onRefresh');
+  }).then(function() {
+    return self._elements;
+  });
+};
+
+CommentDbOverlay.prototype.addComment = function(newComment) {
+  var self = this;
+  self._elements.push(newComment);
+  return self.callListeners('onRefresh').then(function() {
+    return self._elements;
+  });
+};
+
+CommentDbOverlay.prototype.clear = function() {
+  var self = this;
+  self._elements = [];
+  self._detailDataByIdentifiedElement = [];
+  return self.callListeners('onClear');
+};
+
+CommentDbOverlay.prototype.getDetailDataByIdentifiedElement = function(element) {
+  var self = this;
+  var elementKey = element.getId() + "," + element.getType() + "," + element.getModelId();
+  if (this._detailDataByIdentifiedElement[elementKey] !== undefined) {
+    return Promise.resolve(this._detailDataByIdentifiedElement[elementKey]);
+  } else {
+    var coordinates;
+    if (element.getType() === "POINT") {
+      coordinates = element.getPoint().x.toFixed(2) + "," + element.getPoint().y.toFixed(2);
+    }
+    return ServerConnector.getComments({
+      elementId : element.getId(),
+      elementType : element.getType(),
+      coordinates : coordinates
+    }).then(function(comments) {
+      self._detailDataByIdentifiedElement[elementKey] = comments;
+      return comments;
+    });
+  }
+};
+
+CommentDbOverlay.prototype.getIdentifiedElements = function() {
+  var self = this;
+  return new Promise(function(resolve) {
+    var result = [];
+    for (var i = 0; i < self._elements.length; i++) {
+      // we return only elements that are pinned to the map and weren't removed
+      var comment = self._elements[i];
+      if (!comment.isRemoved() && comment.isPinned()) {
+        result.push(comment.getIdentifiedElement());
+      }
+    }
+    resolve(result);
+  });
+};
+
+module.exports = CommentDbOverlay;
diff --git a/frontend-js/src/main/js/map/overlay/DbOverlayCollection.js b/frontend-js/src/main/js/map/overlay/DbOverlayCollection.js
index e98f689b21ec0ff72b5b2eef195b8f8119f93f6c..97eb7f90aaf00ebfd60061b0e94bf5f55b7783a2 100644
--- a/frontend-js/src/main/js/map/overlay/DbOverlayCollection.js
+++ b/frontend-js/src/main/js/map/overlay/DbOverlayCollection.js
@@ -1,67 +1,67 @@
-"use strict";
-
-/* exported logger */
-
-var logger = require('../../logger');
-
-var ObjectWithListeners = require('../../ObjectWithListeners');
-var ChemicalDbOverlay = require('./ChemicalDbOverlay');
-var CommentDbOverlay = require('./CommentDbOverlay');
-var DrugDbOverlay = require('./DrugDbOverlay');
-var MiRnaDbOverlay = require('./MiRnaDbOverlay');
-var SearchDbOverlay = require('./SearchDbOverlay');
-
-function DbOverlayCollection(params) {
-  // call super constructor
-  ObjectWithListeners.call(this);
-
-  var hasDisease = params.map.getProject().getDisease() !== undefined;
-
-  var dataCollections = [ {
-    name : "search"
-  }, {
-    name : "drug",
-    allowSearchById : true,
-    allowGeneralSearch : true
-  }, {
-    name : "chemical",
-    allowSearchById : hasDisease,
-    allowGeneralSearch : hasDisease
-  }, {
-    name : "mirna",
-    allowSearchById : true,
-    allowGeneralSearch : true
-  }, {
-    name : "comment",
-    allowSearchById : false,
-    allowGeneralSearch : true
-  } ];
-
-  var map = params.map;
-
-  for (var i = 0; i < dataCollections.length; i++) {
-    var collectionParams = dataCollections[i];
-    collectionParams.map = map;
-    var collection = null;
-    if (collectionParams.name === "comment") {
-      collection = new CommentDbOverlay(collectionParams);
-    } else if (collectionParams.name === "search") {
-      collection = new SearchDbOverlay(collectionParams);
-    } else if (collectionParams.name === "drug") {
-      collection = new DrugDbOverlay(collectionParams);
-    } else if (collectionParams.name === "mirna") {
-      collection = new MiRnaDbOverlay(collectionParams);
-    } else if (collectionParams.name === "chemical") {
-      collection = new ChemicalDbOverlay(collectionParams);
-    } else {
-      throw new Error("Unknown overlay db: " + collectionParams.name);
-    }
-    map.registerDbOverlay(collection);
-  }
-
-}
-
-DbOverlayCollection.prototype = Object.create(ObjectWithListeners.prototype);
-DbOverlayCollection.prototype.constructor = DbOverlayCollection;
-
-module.exports = DbOverlayCollection;
+"use strict";
+
+/* exported logger */
+
+var logger = require('../../logger');
+
+var ObjectWithListeners = require('../../ObjectWithListeners');
+var ChemicalDbOverlay = require('./ChemicalDbOverlay');
+var CommentDbOverlay = require('./CommentDbOverlay');
+var DrugDbOverlay = require('./DrugDbOverlay');
+var MiRnaDbOverlay = require('./MiRnaDbOverlay');
+var SearchDbOverlay = require('./SearchDbOverlay');
+
+function DbOverlayCollection(params) {
+  // call super constructor
+  ObjectWithListeners.call(this);
+
+  var hasDisease = params.map.getProject().getDisease() !== undefined;
+
+  var dataCollections = [ {
+    name : "search"
+  }, {
+    name : "drug",
+    allowSearchById : true,
+    allowGeneralSearch : true
+  }, {
+    name : "chemical",
+    allowSearchById : hasDisease,
+    allowGeneralSearch : hasDisease
+  }, {
+    name : "mirna",
+    allowSearchById : true,
+    allowGeneralSearch : true
+  }, {
+    name : "comment",
+    allowSearchById : false,
+    allowGeneralSearch : true
+  } ];
+
+  var map = params.map;
+
+  for (var i = 0; i < dataCollections.length; i++) {
+    var collectionParams = dataCollections[i];
+    collectionParams.map = map;
+    var collection = null;
+    if (collectionParams.name === "comment") {
+      collection = new CommentDbOverlay(collectionParams);
+    } else if (collectionParams.name === "search") {
+      collection = new SearchDbOverlay(collectionParams);
+    } else if (collectionParams.name === "drug") {
+      collection = new DrugDbOverlay(collectionParams);
+    } else if (collectionParams.name === "mirna") {
+      collection = new MiRnaDbOverlay(collectionParams);
+    } else if (collectionParams.name === "chemical") {
+      collection = new ChemicalDbOverlay(collectionParams);
+    } else {
+      throw new Error("Unknown overlay db: " + collectionParams.name);
+    }
+    map.registerDbOverlay(collection);
+  }
+
+}
+
+DbOverlayCollection.prototype = Object.create(ObjectWithListeners.prototype);
+DbOverlayCollection.prototype.constructor = DbOverlayCollection;
+
+module.exports = DbOverlayCollection;
diff --git a/frontend-js/src/main/js/map/overlay/DrugDbOverlay.js b/frontend-js/src/main/js/map/overlay/DrugDbOverlay.js
index bea3f1141d94da8cc26102deb6b39a014a056d64..23582176ede30f6ccc5aad12301aea9bb6e61048 100644
--- a/frontend-js/src/main/js/map/overlay/DrugDbOverlay.js
+++ b/frontend-js/src/main/js/map/overlay/DrugDbOverlay.js
@@ -1,29 +1,29 @@
-"use strict";
-
-/* exported logger */
-
-var logger = require('../../logger');
-
-var AbstractTargettingDbOverlay = require('./AbstractTargettingDbOverlay');
-
-var ServerConnector = require('../../ServerConnector');
-
-function DrugDbOverlay(params) {
-  params.iconType= "drug";
-  params.iconColorStart = 5;
-  // call super constructor
-  AbstractTargettingDbOverlay.call(this, params);
-}
-
-DrugDbOverlay.prototype = Object.create(AbstractTargettingDbOverlay.prototype);
-DrugDbOverlay.prototype.constructor = DrugDbOverlay;
-
-DrugDbOverlay.prototype.getNamesByTargetFromServer = function(param) {
-  return ServerConnector.getDrugNamesByTarget(param);
-};
-
-DrugDbOverlay.prototype.getElementsByQueryFromServer = function(param) {
-  return ServerConnector.getDrugsByQuery(param);
-};
-
-module.exports = DrugDbOverlay;
+"use strict";
+
+/* exported logger */
+
+var logger = require('../../logger');
+
+var AbstractTargettingDbOverlay = require('./AbstractTargettingDbOverlay');
+
+var ServerConnector = require('../../ServerConnector');
+
+function DrugDbOverlay(params) {
+  params.iconType= "drug";
+  params.iconColorStart = 5;
+  // call super constructor
+  AbstractTargettingDbOverlay.call(this, params);
+}
+
+DrugDbOverlay.prototype = Object.create(AbstractTargettingDbOverlay.prototype);
+DrugDbOverlay.prototype.constructor = DrugDbOverlay;
+
+DrugDbOverlay.prototype.getNamesByTargetFromServer = function(param) {
+  return ServerConnector.getDrugNamesByTarget(param);
+};
+
+DrugDbOverlay.prototype.getElementsByQueryFromServer = function(param) {
+  return ServerConnector.getDrugsByQuery(param);
+};
+
+module.exports = DrugDbOverlay;
diff --git a/frontend-js/src/main/js/map/overlay/MiRnaDbOverlay.js b/frontend-js/src/main/js/map/overlay/MiRnaDbOverlay.js
index 141c864befe0525ddd21de0fcd8fbc0050febb46..8526cf7c809040eea06a14a3397e2433725b5d21 100644
--- a/frontend-js/src/main/js/map/overlay/MiRnaDbOverlay.js
+++ b/frontend-js/src/main/js/map/overlay/MiRnaDbOverlay.js
@@ -1,30 +1,30 @@
-"use strict";
-
-/* exported logger */
-
-var logger = require('../../logger');
-
-var AbstractTargettingDbOverlay = require('./AbstractTargettingDbOverlay');
-
-var ServerConnector = require('../../ServerConnector');
-
-function MiRnaDbOverlay(params) {
-  params.iconType= "target";
-  params.iconColorStart = 2;
-  // call super constructor
-  AbstractTargettingDbOverlay.call(this, params);
-  
-}
-
-MiRnaDbOverlay.prototype = Object.create(AbstractTargettingDbOverlay.prototype);
-MiRnaDbOverlay.prototype.constructor = MiRnaDbOverlay;
-
-MiRnaDbOverlay.prototype.getNamesByTargetFromServer = function(param) {
-  return ServerConnector.getMiRnaNamesByTarget(param);
-};
-
-MiRnaDbOverlay.prototype.getElementsByQueryFromServer = function(param) {
-  return ServerConnector.getMiRnasByQuery(param);
-};
-
-module.exports = MiRnaDbOverlay;
+"use strict";
+
+/* exported logger */
+
+var logger = require('../../logger');
+
+var AbstractTargettingDbOverlay = require('./AbstractTargettingDbOverlay');
+
+var ServerConnector = require('../../ServerConnector');
+
+function MiRnaDbOverlay(params) {
+  params.iconType= "target";
+  params.iconColorStart = 2;
+  // call super constructor
+  AbstractTargettingDbOverlay.call(this, params);
+  
+}
+
+MiRnaDbOverlay.prototype = Object.create(AbstractTargettingDbOverlay.prototype);
+MiRnaDbOverlay.prototype.constructor = MiRnaDbOverlay;
+
+MiRnaDbOverlay.prototype.getNamesByTargetFromServer = function(param) {
+  return ServerConnector.getMiRnaNamesByTarget(param);
+};
+
+MiRnaDbOverlay.prototype.getElementsByQueryFromServer = function(param) {
+  return ServerConnector.getMiRnasByQuery(param);
+};
+
+module.exports = MiRnaDbOverlay;
diff --git a/frontend-js/src/main/js/map/overlay/SearchDbOverlay.js b/frontend-js/src/main/js/map/overlay/SearchDbOverlay.js
index 5f199aad9f22cb3dd89a040d47c0f3b0738a8d38..4720bfcac3877c8872918b68cbc7141f6932ab01 100644
--- a/frontend-js/src/main/js/map/overlay/SearchDbOverlay.js
+++ b/frontend-js/src/main/js/map/overlay/SearchDbOverlay.js
@@ -1,355 +1,355 @@
-"use strict";
-
-/* exported logger */
-
-var logger = require('../../logger');
-
-var Promise = require("bluebird");
-
-var AbstractDbOverlay = require('./AbstractDbOverlay');
-var Alias = require('../data/Alias');
-var IdentifiedElement = require('../data/IdentifiedElement');
-var InvalidArgumentException = require('../../InvalidArgumentError');
-var Reaction = require('../data/Reaction');
-var SearchBioEntityGroup = require('../data/SearchBioEntityGroup');
-
-
-var ServerConnector = require('../../ServerConnector');
-
-/**
- *
- * @param params
- * @constructor
- * @extends AbstractDbOverlay
- */
-function SearchDbOverlay(params) {
-  params.iconType = "marker";
-  params.iconColorStart = 0;
-  // call super constructor
-  AbstractDbOverlay.call(this, params);
-
-}
-
-SearchDbOverlay.prototype = Object.create(AbstractDbOverlay.prototype);
-SearchDbOverlay.prototype.constructor = SearchDbOverlay;
-
-SearchDbOverlay.prototype.getElementsByQuery = function (query) {
-  var self = this;
-  var i;
-  var queryId = null;
-  var queries = self.getQueries();
-  for (i = 0; i < queries.length; i++) {
-    if (queries[i] === query) {
-      queryId = i;
-    }
-  }
-  if (queryId === null) {
-    throw new Error("Invalid query: " + query);
-  }
-  var elements = self._elementsByQuery[query];
-  var promises = [];
-  for (i = 0; i < elements.length; i++) {
-    var model = self.getMap().getSubmapById(elements[0].getModelId()).getModel();
-    promises.push(model.getByIdentifiedElement(elements[i], true));
-  }
-  return Promise.all(promises).then(function (elements) {
-    var result = [];
-    var iconCounter = 1;
-    var groups = [];
-    for (var i = 0; i < elements.length; i++) {
-      var element = elements[i];
-      var alreadyExists = false;
-      var group;
-      for (var j = 0; j < groups.length; j++) {
-        group = groups[j];
-        if (group.bioEntityMatch(element)) {
-          alreadyExists = true;
-          group.addBioEntity(element);
-        }
-      }
-
-      if (!alreadyExists) {
-        var icon;
-        if (element instanceof Alias) {
-          icon = self.getIcon(queryId, iconCounter++)
-        }
-        group = new SearchBioEntityGroup(element);
-        group.setIcon(icon);
-        groups.push(group);
-        result.push({
-          element: group,
-          icon: icon
-        });
-      }
-    }
-    return result;
-  });
-};
-
-SearchDbOverlay.prototype._getFirstVisibleParentOrObject = function (identifiedElement, zoomLevel, coordinates) {
-  if (identifiedElement === undefined) {
-    return Promise.resolve();
-  }
-  var self = this;
-  var model = self.getMap().getSubmapById(identifiedElement.getModelId()).getModel();
-  return model.getByIdentifiedElement(identifiedElement, true).then(function (fullElement) {
-    if (fullElement.getHierarchyVisibilityLevel() <= zoomLevel) {
-      if (fullElement instanceof Alias) {
-        //transparent compartments shouldn't be clickable
-        if (fullElement.getTransparencyLevel() <= zoomLevel && fullElement.getType() === "Compartment") {
-          return undefined;
-        }
-      }
-      return identifiedElement;
-    } else {
-      var parentId;
-      if (fullElement instanceof Alias) {
-        if (fullElement.getComplexId() !== undefined) {
-          parentId = fullElement.getComplexId();
-        } else if (fullElement.getCompartmentId() !== undefined) {
-          parentId = fullElement.getCompartmentId();
-        }
-      }
-      if (parentId !== undefined) {
-        var parent = new IdentifiedElement({
-          id: parentId,
-          type: "ALIAS",
-          modelId: identifiedElement.getModelId()
-        });
-        return self._getFirstVisibleParentOrObject(parent, zoomLevel, coordinates);
-      } else {
-        logger.warn("Cannot find visible parent for object. (zoomLevel=" + zoomLevel + ")");
-        logger.warn(fullElement);
-        return identifiedElement;
-      }
-    }
-  });
-};
-SearchDbOverlay.prototype.searchByCoordinates = function (params) {
-  var modelId = params.modelId;
-  var coordinates = params.coordinates;
-  var zoom = params.zoom;
-
-  var self = this;
-  var query = self.encodeQuery(AbstractDbOverlay.QueryType.SEARCH_BY_COORDINATES, modelId, coordinates, zoom);
-
-  ServerConnector.getSessionData().setSearchQuery(query);
-
-  if (self._elementsByQuery[query] !== undefined) {
-    self.setQueries([query]);
-    return self.callListeners('onSearch', {
-      fitBounds: false,
-      identifiedElements: [self._elementsByQuery[query]],
-      type: AbstractDbOverlay.QueryType.SEARCH_BY_COORDINATES
-    }).then(function () {
-      return Promise.resolve(self._elementsByQuery[query]);
-    });
-  } else {
-    var searchResult = null;
-    var maxDistance;
-    var map = self.getMap().getSubmapById(modelId);
-    if (map === null) {
-      return Promise.reject(new InvalidArgumentException("model doesn't exist for modelId: " + modelId));
-    }
-    var model = map.getModel();
-    return ServerConnector.getMaxSearchDistance().then(function (distance) {
-      var maxZoom = model.getMaxZoom();
-      var zoomDiff = maxZoom - zoom;
-      for (var i = 0; i < zoomDiff; i++) {
-        distance = distance * 1.5;
-      }
-      maxDistance = distance;
-      return ServerConnector.getClosestElementsByCoordinates({
-        modelId: modelId,
-        coordinates: coordinates,
-        count: 1
-      });
-    }).then(function (elements) {
-      var nestedOverlay = "Pathways and compartments";
-      if (elements.length === 0) {
-        return undefined;
-      } else {
-        if (self.getMap().getBackgroundDataOverlay().getName() === nestedOverlay) {
-          return self._getFirstVisibleParentOrObject(elements[0], zoom - model.getMinZoom());
-        } else {
-          return elements[0];
-        }
-      }
-    }).then(function (visibleObject) {
-      if (visibleObject !== undefined) {
-        searchResult = [visibleObject];
-        if (searchResult[0].getType() === "REACTION") {
-          return model.getReactionById(searchResult[0].getId(), true).then(function (reaction) {
-            var reactionElements = reaction.getElements();
-            for (var i = 0; i < reactionElements.length; i++) {
-              searchResult.push(new IdentifiedElement(reactionElements[i]));
-            }
-          });
-        }
-      } else {
-        searchResult = [];
-      }
-    }).then(function () {
-      if (searchResult.length > 0) {
-        return self.getMap().getDistance({
-          modelId: modelId,
-          coordinates: coordinates,
-          element: searchResult[0]
-        });
-      } else {
-        return Number.POSITIVE_INFINITY;
-      }
-    }).then(function (distance) {
-      if (distance <= maxDistance) {
-        self._elementsByQuery[query] = searchResult;
-      } else {
-        return ServerConnector.getClosestElementsByCoordinates({
-          modelId: modelId,
-          coordinates: coordinates,
-          count: 1,
-          type: ["Compartment"]
-        }).then(function (elements) {
-          var nestedOverlay = "Pathways and compartments";
-          if (elements.length === 0) {
-            return undefined;
-          } else {
-            if (self.getMap().getBackgroundDataOverlay().getName() === nestedOverlay) {
-              return self._getFirstVisibleParentOrObject(elements[0], zoom - model.getMinZoom());
-            } else {
-              return undefined;
-            }
-          }
-        }).then(function (visibleObject) {
-          if (visibleObject !== undefined) {
-            self._elementsByQuery[query] = [visibleObject];
-          } else {
-            self._elementsByQuery[query] = [];
-          }
-        });
-      }
-    }).then(function () {
-      self.setQueries([query]);
-
-      return self.callListeners('onSearch', {
-        fitBounds: params.fitBounds,
-        identifiedElements: [self._elementsByQuery[query]],
-        type: AbstractDbOverlay.QueryType.SEARCH_BY_COORDINATES
-      });
-    }).then(function () {
-      return self._elementsByQuery[query];
-    });
-  }
-};
-
-SearchDbOverlay.prototype.searchBySingleQuery = function (originalQuery, perfect) {
-  var self = this;
-  var query = self.encodeQuery(AbstractDbOverlay.QueryType.SEARCH_BY_QUERY, originalQuery, perfect);
-  if (self._elementsByQuery[query] !== undefined) {
-    return Promise.resolve(self._elementsByQuery[query]);
-  } else {
-    return ServerConnector.getElementsByQuery({
-      query: originalQuery,
-      perfectMatch: perfect
-    }).then(function (elements) {
-      var result = [];
-      for (var i = 0; i < elements.length; i++) {
-        result.push(new IdentifiedElement(elements[i]));
-      }
-      self._elementsByQuery[query] = result;
-      return self.getMap().fetchIdentifiedElements(result, true);
-    }).then(function () {
-      return self._elementsByQuery[query];
-    });
-  }
-};
-
-/**
- *
- * @param {IdentifiedElement} element
- * @returns {Promise|PromiseLike}
- */
-SearchDbOverlay.prototype.searchByTarget = function (element) {
-  var self = this;
-  var query = self.encodeQuery(AbstractDbOverlay.QueryType.SEARCH_BY_TARGET, element);
-
-  ServerConnector.getSessionData().setSearchQuery(query);
-
-  if (self._elementsByQuery[query] === undefined) {
-    self._elementsByQuery[query] = [element];
-  }
-  return self.getMap().fetchIdentifiedElements([element], true).then(function () {
-    self.setQueries([query]);
-    return self.callListeners('onSearch', {
-      fitBounds: false,
-      identifiedElements: [self._elementsByQuery[query]],
-      type: AbstractDbOverlay.QueryType.SEARCH_BY_TARGET
-    });
-  }).then(function () {
-    return Promise.resolve(self._elementsByQuery[query]);
-  });
-};
-
-
-SearchDbOverlay.prototype.getIdentifiedElements = function () {
-  var self = this;
-  var queries = self.getQueries();
-  var result = [];
-
-  return Promise.each(queries, function (query, index) {
-    var identifiedElements = self._elementsByQuery[query];
-    return self.getMap().fetchIdentifiedElements(identifiedElements, true).then(function (elements) {
-      var iconCounter = 1;
-      var groups = [];
-      for (var i = 0; i < elements.length; i++) {
-        var element = elements[i];
-        var alreadyExists = false;
-        var icon = null;
-        var group;
-        for (var j = 0; j < groups.length; j++) {
-          group = groups[j];
-          if (group.bioEntityMatch(element)) {
-            alreadyExists = true;
-            group.addBioEntity(element);
-            icon = group.getIcon();
-          }
-        }
-
-        if (!alreadyExists) {
-          if (element instanceof Alias) {
-            icon = self.getIcon(index, iconCounter++)
-          }
-          group = new SearchBioEntityGroup(element);
-          group.setIcon(icon);
-          groups.push(group);
-
-        }
-        var ie = new IdentifiedElement(element);
-        if (element instanceof Alias) {
-          ie.setIcon(icon);
-        } else if (!(element instanceof Reaction)) {
-          throw new Error("Unknown element type: " + ie.getType());
-        }
-        result.push(ie);
-
-      }
-    });
-
-  }).then(function () {
-    return result;
-  });
-};
-
-/**
- *
- * @param element
- * @returns {Promise<BioEntity[]>}
- */
-SearchDbOverlay.prototype.getDetailDataByIdentifiedElement = function (element) {
-  if (element.getType() === "POINT") {
-    return Promise.resolve(null);
-  }
-  var model = this.getMap().getSubmapById(element.getModelId()).getModel();
-  return model.getByIdentifiedElement(element, true);
-};
-
-module.exports = SearchDbOverlay;
+"use strict";
+
+/* exported logger */
+
+var logger = require('../../logger');
+
+var Promise = require("bluebird");
+
+var AbstractDbOverlay = require('./AbstractDbOverlay');
+var Alias = require('../data/Alias');
+var IdentifiedElement = require('../data/IdentifiedElement');
+var InvalidArgumentException = require('../../InvalidArgumentError');
+var Reaction = require('../data/Reaction');
+var SearchBioEntityGroup = require('../data/SearchBioEntityGroup');
+
+
+var ServerConnector = require('../../ServerConnector');
+
+/**
+ *
+ * @param params
+ * @constructor
+ * @extends AbstractDbOverlay
+ */
+function SearchDbOverlay(params) {
+  params.iconType = "marker";
+  params.iconColorStart = 0;
+  // call super constructor
+  AbstractDbOverlay.call(this, params);
+
+}
+
+SearchDbOverlay.prototype = Object.create(AbstractDbOverlay.prototype);
+SearchDbOverlay.prototype.constructor = SearchDbOverlay;
+
+SearchDbOverlay.prototype.getElementsByQuery = function (query) {
+  var self = this;
+  var i;
+  var queryId = null;
+  var queries = self.getQueries();
+  for (i = 0; i < queries.length; i++) {
+    if (queries[i] === query) {
+      queryId = i;
+    }
+  }
+  if (queryId === null) {
+    throw new Error("Invalid query: " + query);
+  }
+  var elements = self._elementsByQuery[query];
+  var promises = [];
+  for (i = 0; i < elements.length; i++) {
+    var model = self.getMap().getSubmapById(elements[0].getModelId()).getModel();
+    promises.push(model.getByIdentifiedElement(elements[i], true));
+  }
+  return Promise.all(promises).then(function (elements) {
+    var result = [];
+    var iconCounter = 1;
+    var groups = [];
+    for (var i = 0; i < elements.length; i++) {
+      var element = elements[i];
+      var alreadyExists = false;
+      var group;
+      for (var j = 0; j < groups.length; j++) {
+        group = groups[j];
+        if (group.bioEntityMatch(element)) {
+          alreadyExists = true;
+          group.addBioEntity(element);
+        }
+      }
+
+      if (!alreadyExists) {
+        var icon;
+        if (element instanceof Alias) {
+          icon = self.getIcon(queryId, iconCounter++)
+        }
+        group = new SearchBioEntityGroup(element);
+        group.setIcon(icon);
+        groups.push(group);
+        result.push({
+          element: group,
+          icon: icon
+        });
+      }
+    }
+    return result;
+  });
+};
+
+SearchDbOverlay.prototype._getFirstVisibleParentOrObject = function (identifiedElement, zoomLevel, coordinates) {
+  if (identifiedElement === undefined) {
+    return Promise.resolve();
+  }
+  var self = this;
+  var model = self.getMap().getSubmapById(identifiedElement.getModelId()).getModel();
+  return model.getByIdentifiedElement(identifiedElement, true).then(function (fullElement) {
+    if (fullElement.getHierarchyVisibilityLevel() <= zoomLevel) {
+      if (fullElement instanceof Alias) {
+        //transparent compartments shouldn't be clickable
+        if (fullElement.getTransparencyLevel() <= zoomLevel && fullElement.getType() === "Compartment") {
+          return undefined;
+        }
+      }
+      return identifiedElement;
+    } else {
+      var parentId;
+      if (fullElement instanceof Alias) {
+        if (fullElement.getComplexId() !== undefined) {
+          parentId = fullElement.getComplexId();
+        } else if (fullElement.getCompartmentId() !== undefined) {
+          parentId = fullElement.getCompartmentId();
+        }
+      }
+      if (parentId !== undefined) {
+        var parent = new IdentifiedElement({
+          id: parentId,
+          type: "ALIAS",
+          modelId: identifiedElement.getModelId()
+        });
+        return self._getFirstVisibleParentOrObject(parent, zoomLevel, coordinates);
+      } else {
+        logger.warn("Cannot find visible parent for object. (zoomLevel=" + zoomLevel + ")");
+        logger.warn(fullElement);
+        return identifiedElement;
+      }
+    }
+  });
+};
+SearchDbOverlay.prototype.searchByCoordinates = function (params) {
+  var modelId = params.modelId;
+  var coordinates = params.coordinates;
+  var zoom = params.zoom;
+
+  var self = this;
+  var query = self.encodeQuery(AbstractDbOverlay.QueryType.SEARCH_BY_COORDINATES, modelId, coordinates, zoom);
+
+  ServerConnector.getSessionData().setSearchQuery(query);
+
+  if (self._elementsByQuery[query] !== undefined) {
+    self.setQueries([query]);
+    return self.callListeners('onSearch', {
+      fitBounds: false,
+      identifiedElements: [self._elementsByQuery[query]],
+      type: AbstractDbOverlay.QueryType.SEARCH_BY_COORDINATES
+    }).then(function () {
+      return Promise.resolve(self._elementsByQuery[query]);
+    });
+  } else {
+    var searchResult = null;
+    var maxDistance;
+    var map = self.getMap().getSubmapById(modelId);
+    if (map === null) {
+      return Promise.reject(new InvalidArgumentException("model doesn't exist for modelId: " + modelId));
+    }
+    var model = map.getModel();
+    return ServerConnector.getMaxSearchDistance().then(function (distance) {
+      var maxZoom = model.getMaxZoom();
+      var zoomDiff = maxZoom - zoom;
+      for (var i = 0; i < zoomDiff; i++) {
+        distance = distance * 1.5;
+      }
+      maxDistance = distance;
+      return ServerConnector.getClosestElementsByCoordinates({
+        modelId: modelId,
+        coordinates: coordinates,
+        count: 1
+      });
+    }).then(function (elements) {
+      var nestedOverlay = "Pathways and compartments";
+      if (elements.length === 0) {
+        return undefined;
+      } else {
+        if (self.getMap().getBackgroundDataOverlay().getName() === nestedOverlay) {
+          return self._getFirstVisibleParentOrObject(elements[0], zoom - model.getMinZoom());
+        } else {
+          return elements[0];
+        }
+      }
+    }).then(function (visibleObject) {
+      if (visibleObject !== undefined) {
+        searchResult = [visibleObject];
+        if (searchResult[0].getType() === "REACTION") {
+          return model.getReactionById(searchResult[0].getId(), true).then(function (reaction) {
+            var reactionElements = reaction.getElements();
+            for (var i = 0; i < reactionElements.length; i++) {
+              searchResult.push(new IdentifiedElement(reactionElements[i]));
+            }
+          });
+        }
+      } else {
+        searchResult = [];
+      }
+    }).then(function () {
+      if (searchResult.length > 0) {
+        return self.getMap().getDistance({
+          modelId: modelId,
+          coordinates: coordinates,
+          element: searchResult[0]
+        });
+      } else {
+        return Number.POSITIVE_INFINITY;
+      }
+    }).then(function (distance) {
+      if (distance <= maxDistance) {
+        self._elementsByQuery[query] = searchResult;
+      } else {
+        return ServerConnector.getClosestElementsByCoordinates({
+          modelId: modelId,
+          coordinates: coordinates,
+          count: 1,
+          type: ["Compartment"]
+        }).then(function (elements) {
+          var nestedOverlay = "Pathways and compartments";
+          if (elements.length === 0) {
+            return undefined;
+          } else {
+            if (self.getMap().getBackgroundDataOverlay().getName() === nestedOverlay) {
+              return self._getFirstVisibleParentOrObject(elements[0], zoom - model.getMinZoom());
+            } else {
+              return undefined;
+            }
+          }
+        }).then(function (visibleObject) {
+          if (visibleObject !== undefined) {
+            self._elementsByQuery[query] = [visibleObject];
+          } else {
+            self._elementsByQuery[query] = [];
+          }
+        });
+      }
+    }).then(function () {
+      self.setQueries([query]);
+
+      return self.callListeners('onSearch', {
+        fitBounds: params.fitBounds,
+        identifiedElements: [self._elementsByQuery[query]],
+        type: AbstractDbOverlay.QueryType.SEARCH_BY_COORDINATES
+      });
+    }).then(function () {
+      return self._elementsByQuery[query];
+    });
+  }
+};
+
+SearchDbOverlay.prototype.searchBySingleQuery = function (originalQuery, perfect) {
+  var self = this;
+  var query = self.encodeQuery(AbstractDbOverlay.QueryType.SEARCH_BY_QUERY, originalQuery, perfect);
+  if (self._elementsByQuery[query] !== undefined) {
+    return Promise.resolve(self._elementsByQuery[query]);
+  } else {
+    return ServerConnector.getElementsByQuery({
+      query: originalQuery,
+      perfectMatch: perfect
+    }).then(function (elements) {
+      var result = [];
+      for (var i = 0; i < elements.length; i++) {
+        result.push(new IdentifiedElement(elements[i]));
+      }
+      self._elementsByQuery[query] = result;
+      return self.getMap().fetchIdentifiedElements(result, true);
+    }).then(function () {
+      return self._elementsByQuery[query];
+    });
+  }
+};
+
+/**
+ *
+ * @param {IdentifiedElement} element
+ * @returns {Promise|PromiseLike}
+ */
+SearchDbOverlay.prototype.searchByTarget = function (element) {
+  var self = this;
+  var query = self.encodeQuery(AbstractDbOverlay.QueryType.SEARCH_BY_TARGET, element);
+
+  ServerConnector.getSessionData().setSearchQuery(query);
+
+  if (self._elementsByQuery[query] === undefined) {
+    self._elementsByQuery[query] = [element];
+  }
+  return self.getMap().fetchIdentifiedElements([element], true).then(function () {
+    self.setQueries([query]);
+    return self.callListeners('onSearch', {
+      fitBounds: false,
+      identifiedElements: [self._elementsByQuery[query]],
+      type: AbstractDbOverlay.QueryType.SEARCH_BY_TARGET
+    });
+  }).then(function () {
+    return Promise.resolve(self._elementsByQuery[query]);
+  });
+};
+
+
+SearchDbOverlay.prototype.getIdentifiedElements = function () {
+  var self = this;
+  var queries = self.getQueries();
+  var result = [];
+
+  return Promise.each(queries, function (query, index) {
+    var identifiedElements = self._elementsByQuery[query];
+    return self.getMap().fetchIdentifiedElements(identifiedElements, true).then(function (elements) {
+      var iconCounter = 1;
+      var groups = [];
+      for (var i = 0; i < elements.length; i++) {
+        var element = elements[i];
+        var alreadyExists = false;
+        var icon = null;
+        var group;
+        for (var j = 0; j < groups.length; j++) {
+          group = groups[j];
+          if (group.bioEntityMatch(element)) {
+            alreadyExists = true;
+            group.addBioEntity(element);
+            icon = group.getIcon();
+          }
+        }
+
+        if (!alreadyExists) {
+          if (element instanceof Alias) {
+            icon = self.getIcon(index, iconCounter++)
+          }
+          group = new SearchBioEntityGroup(element);
+          group.setIcon(icon);
+          groups.push(group);
+
+        }
+        var ie = new IdentifiedElement(element);
+        if (element instanceof Alias) {
+          ie.setIcon(icon);
+        } else if (!(element instanceof Reaction)) {
+          throw new Error("Unknown element type: " + ie.getType());
+        }
+        result.push(ie);
+
+      }
+    });
+
+  }).then(function () {
+    return result;
+  });
+};
+
+/**
+ *
+ * @param element
+ * @returns {Promise<BioEntity[]>}
+ */
+SearchDbOverlay.prototype.getDetailDataByIdentifiedElement = function (element) {
+  if (element.getType() === "POINT") {
+    return Promise.resolve(null);
+  }
+  var model = this.getMap().getSubmapById(element.getModelId()).getModel();
+  return model.getByIdentifiedElement(element, true);
+};
+
+module.exports = SearchDbOverlay;
diff --git a/frontend-js/src/main/js/map/overlay/UserDbOverlay.js b/frontend-js/src/main/js/map/overlay/UserDbOverlay.js
index f8298eab0302c99b85c5add04a166297ad08594f..eac4eea005536b9c957edbfd2bfc12ef98b79470 100644
--- a/frontend-js/src/main/js/map/overlay/UserDbOverlay.js
+++ b/frontend-js/src/main/js/map/overlay/UserDbOverlay.js
@@ -1,248 +1,248 @@
-"use strict";
-
-/* exported logger */
-
-var logger = require('../../logger');
-
-var AbstractDbOverlay = require('./AbstractDbOverlay');
-
-var IdentifiedElement = require('../data/IdentifiedElement');
-var InvalidArgumentError = require('../../InvalidArgumentError');
-
-var Promise = require("bluebird");
-
-function UserDbOverlay(params) {
-  params.iconType = "marker";
-  params.iconColorStart = 1;
-  // call super constructor
-  AbstractDbOverlay.call(this, params);
-
-  this._markerIdentifiedElements = {
-    ALIAS: [],
-    REACTION: [],
-    POINT: []
-  };
-  this._surfaceIdentifiedElements = {
-    ALIAS: [],
-    REACTION: [],
-    POINT: []
-  };
-}
-
-UserDbOverlay.prototype = Object.create(AbstractDbOverlay.prototype);
-UserDbOverlay.prototype.constructor = UserDbOverlay;
-
-UserDbOverlay.prototype.getDetailDataByIdentifiedElement = function (element) {
-  if (element.getType() === "POINT") {
-    return Promise.resolve(null);
-  }
-  var model = this.getMap().getSubmapById(element.getModelId()).getModel();
-  return model.getByIdentifiedElement(element, true);
-};
-
-UserDbOverlay.prototype._createIdentifiedElements = function (params, sourceArray, mustBeUndefined) {
-  var self = this;
-  var result = [];
-  var promises = [];
-  var mustBeDefined = !mustBeUndefined;
-  for (var i = 0; i < params.length; i++) {
-    var singleElementParam = params[i];
-    var element = new IdentifiedElement(singleElementParam.element);
-    if (singleElementParam.icon !== undefined) {
-      element.setIcon(singleElementParam.icon);
-    }
-    if (singleElementParam.options !== undefined) {
-      element.setColor(singleElementParam.options.color);
-      element.setOpacity(singleElementParam.options.opacity);
-      element.setLineColor(singleElementParam.options.lineColor);
-      element.setLineWeight(singleElementParam.options.lineWeight);
-      element.setLineOpacity(singleElementParam.options.lineOpacity);
-    }
-    if (sourceArray[element.getType()][element.getId()] !== undefined && mustBeUndefined) {
-      return Promise.reject(new Error("Element already highlighted: " + element.getId()));
-    }
-    if (sourceArray[element.getType()][element.getId()] === undefined && mustBeDefined) {
-      return Promise.reject(new Error("Element is not highlighted: " + element.getId()));
-    }
-    result.push(element);
-    var submap = self.getMap().getSubmapById(element.getModelId());
-    if (submap === null) {
-      return Promise.reject(new InvalidArgumentError("Submap doesn't exist: " + result[i].getModelId()));
-    }
-    promises.push(submap.getModel().getByIdentifiedElement(element));
-  }
-  return Promise.all(promises).then(function (elementsFromModel) {
-    for (var i = 0; i < elementsFromModel.length; i++) {
-      if (elementsFromModel[i] === undefined || elementsFromModel[i] === null) {
-        return Promise.reject(new InvalidArgumentError("Element doesn't exist: " + result[i].getId()));
-      }
-    }
-    return result;
-  });
-};
-
-UserDbOverlay.prototype.addMarker = function (params) {
-  var self = this;
-  self.disableAddRemoveElements();
-
-  if (params.length === undefined) {
-    params = [params];
-  }
-  return self._createIdentifiedElements(params, self._markerIdentifiedElements, true).then(function (elements) {
-    for (var i = 0; i < elements.length; i++) {
-      var element = elements[i];
-      self._markerIdentifiedElements[element.getType()][element.getId()] = element;
-    }
-    return self.getIdentifiedElements();
-  }).then(function (elements) {
-    self.enableAddRemoveElements();
-    return self.callListeners("onSearch", {
-      fitBounds: false,
-      identifiedElements: elements
-    });
-  }).then(null, function (error) {
-    self.enableAddRemoveElements();
-    return Promise.reject(error);
-  });
-};
-
-UserDbOverlay.prototype.addSurface = function (params) {
-  var self = this;
-  self.disableAddRemoveElements();
-
-  if (params.length === undefined) {
-    params = [params];
-  }
-
-  return self._createIdentifiedElements(params, self._surfaceIdentifiedElements, true).then(function (elements) {
-    for (var i = 0; i < elements.length; i++) {
-      var element = elements[i];
-      self._surfaceIdentifiedElements[element.getType()][element.getId()] = element;
-    }
-    return self.getIdentifiedElements();
-  }).then(function (elements) {
-    self.enableAddRemoveElements();
-    return self.callListeners("onSearch", {
-      fitBounds: false,
-      identifiedElements: elements
-    });
-  }).then(null, function (error) {
-    self.enableAddRemoveElements();
-    return Promise.reject(error);
-  });
-};
-
-UserDbOverlay.prototype.removeMarker = function (params) {
-  var self = this;
-  self.disableAddRemoveElements();
-
-  if (params.length === undefined) {
-    params = [params];
-  }
-
-  return self._createIdentifiedElements(params, self._markerIdentifiedElements, false).then(function (elements) {
-    for (var i = 0; i < elements.length; i++) {
-      var element = elements[i];
-      self._markerIdentifiedElements[element.getType()][element.getId()] = undefined;
-      delete self._markerIdentifiedElements[element.getType()][element.getId()];
-    }
-    return self.getIdentifiedElements();
-  }).then(function (elements) {
-    self.enableAddRemoveElements();
-    return self.callListeners("onSearch", {
-      fitBounds: false,
-      identifiedElements: elements
-    });
-  }).then(null, function (error) {
-    self.enableAddRemoveElements();
-    return Promise.reject(error);
-  });
-};
-
-UserDbOverlay.prototype.removeSurface = function (params) {
-  var self = this;
-  self.disableAddRemoveElements();
-
-  if (params.length === undefined) {
-    params = [params];
-  }
-  return self._createIdentifiedElements(params, self._surfaceIdentifiedElements, false).then(function (elements) {
-    for (var i = 0; i < elements.length; i++) {
-      var element = elements[i];
-      self._surfaceIdentifiedElements[element.getType()][element.getId()] = undefined;
-      delete self._surfaceIdentifiedElements[element.getType()][element.getId()];
-    }
-    return self.getIdentifiedElements();
-  }).then(function (elements) {
-    self.enableAddRemoveElements();
-    return self.callListeners("onSearch", {
-      fitBounds: false,
-      identifiedElements: elements
-    });
-  }).then(null, function (error) {
-    self.enableAddRemoveElements();
-    return Promise.reject(error);
-  });
-};
-
-UserDbOverlay.prototype.disableAddRemoveElements = function () {
-  if (this._addRemoveElementsDisabled) {
-    throw new Error("wait until previous Promise for showBioEntity/hideBioEntity is resolved");
-  } else {
-    this._addRemoveElementsDisabled = true;
-  }
-};
-UserDbOverlay.prototype.enableAddRemoveElements = function () {
-  if (this._addRemoveElementsDisabled) {
-    this._addRemoveElementsDisabled = false;
-  } else {
-    logger.warn("showBioEntity/hideBioEntity is not disabled");
-  }
-};
-
-UserDbOverlay.prototype.getIdentifiedElements = function () {
-  var result = [];
-  var markerType, key, markers;
-  for (markerType in this._markerIdentifiedElements) {
-    if (this._markerIdentifiedElements.hasOwnProperty(markerType)) {
-      markers = this._markerIdentifiedElements[markerType];
-      for (key in markers) {
-        if (markers.hasOwnProperty(key)) {
-          var identifiedElement = markers[key];
-          if (identifiedElement.getIcon() === undefined) {
-            identifiedElement.setIcon("marker/generic/search_red.png");
-          }
-          result.push(identifiedElement);
-        }
-      }
-    }
-  }
-
-  for (markerType in this._surfaceIdentifiedElements) {
-    if (this._surfaceIdentifiedElements.hasOwnProperty(markerType)) {
-      markers = this._surfaceIdentifiedElements[markerType];
-      for (key in markers) {
-        if (markers.hasOwnProperty(key)) {
-          result.push(markers[key]);
-        }
-      }
-    }
-  }
-
-  return Promise.resolve(result);
-};
-
-UserDbOverlay.prototype.clear = function () {
-  var self = this;
-  self._markerIdentifiedElements = {
-    ALIAS: [],
-    REACTION: [],
-    POINT: []
-  };
-  return self.callListeners("onSearch", {
-    fitBounds: false,
-    identifiedElements: []
-  });
-};
-
-module.exports = UserDbOverlay;
+"use strict";
+
+/* exported logger */
+
+var logger = require('../../logger');
+
+var AbstractDbOverlay = require('./AbstractDbOverlay');
+
+var IdentifiedElement = require('../data/IdentifiedElement');
+var InvalidArgumentError = require('../../InvalidArgumentError');
+
+var Promise = require("bluebird");
+
+function UserDbOverlay(params) {
+  params.iconType = "marker";
+  params.iconColorStart = 1;
+  // call super constructor
+  AbstractDbOverlay.call(this, params);
+
+  this._markerIdentifiedElements = {
+    ALIAS: [],
+    REACTION: [],
+    POINT: []
+  };
+  this._surfaceIdentifiedElements = {
+    ALIAS: [],
+    REACTION: [],
+    POINT: []
+  };
+}
+
+UserDbOverlay.prototype = Object.create(AbstractDbOverlay.prototype);
+UserDbOverlay.prototype.constructor = UserDbOverlay;
+
+UserDbOverlay.prototype.getDetailDataByIdentifiedElement = function (element) {
+  if (element.getType() === "POINT") {
+    return Promise.resolve(null);
+  }
+  var model = this.getMap().getSubmapById(element.getModelId()).getModel();
+  return model.getByIdentifiedElement(element, true);
+};
+
+UserDbOverlay.prototype._createIdentifiedElements = function (params, sourceArray, mustBeUndefined) {
+  var self = this;
+  var result = [];
+  var promises = [];
+  var mustBeDefined = !mustBeUndefined;
+  for (var i = 0; i < params.length; i++) {
+    var singleElementParam = params[i];
+    var element = new IdentifiedElement(singleElementParam.element);
+    if (singleElementParam.icon !== undefined) {
+      element.setIcon(singleElementParam.icon);
+    }
+    if (singleElementParam.options !== undefined) {
+      element.setColor(singleElementParam.options.color);
+      element.setOpacity(singleElementParam.options.opacity);
+      element.setLineColor(singleElementParam.options.lineColor);
+      element.setLineWeight(singleElementParam.options.lineWeight);
+      element.setLineOpacity(singleElementParam.options.lineOpacity);
+    }
+    if (sourceArray[element.getType()][element.getId()] !== undefined && mustBeUndefined) {
+      return Promise.reject(new Error("Element already highlighted: " + element.getId()));
+    }
+    if (sourceArray[element.getType()][element.getId()] === undefined && mustBeDefined) {
+      return Promise.reject(new Error("Element is not highlighted: " + element.getId()));
+    }
+    result.push(element);
+    var submap = self.getMap().getSubmapById(element.getModelId());
+    if (submap === null) {
+      return Promise.reject(new InvalidArgumentError("Submap doesn't exist: " + result[i].getModelId()));
+    }
+    promises.push(submap.getModel().getByIdentifiedElement(element));
+  }
+  return Promise.all(promises).then(function (elementsFromModel) {
+    for (var i = 0; i < elementsFromModel.length; i++) {
+      if (elementsFromModel[i] === undefined || elementsFromModel[i] === null) {
+        return Promise.reject(new InvalidArgumentError("Element doesn't exist: " + result[i].getId()));
+      }
+    }
+    return result;
+  });
+};
+
+UserDbOverlay.prototype.addMarker = function (params) {
+  var self = this;
+  self.disableAddRemoveElements();
+
+  if (params.length === undefined) {
+    params = [params];
+  }
+  return self._createIdentifiedElements(params, self._markerIdentifiedElements, true).then(function (elements) {
+    for (var i = 0; i < elements.length; i++) {
+      var element = elements[i];
+      self._markerIdentifiedElements[element.getType()][element.getId()] = element;
+    }
+    return self.getIdentifiedElements();
+  }).then(function (elements) {
+    self.enableAddRemoveElements();
+    return self.callListeners("onSearch", {
+      fitBounds: false,
+      identifiedElements: elements
+    });
+  }).then(null, function (error) {
+    self.enableAddRemoveElements();
+    return Promise.reject(error);
+  });
+};
+
+UserDbOverlay.prototype.addSurface = function (params) {
+  var self = this;
+  self.disableAddRemoveElements();
+
+  if (params.length === undefined) {
+    params = [params];
+  }
+
+  return self._createIdentifiedElements(params, self._surfaceIdentifiedElements, true).then(function (elements) {
+    for (var i = 0; i < elements.length; i++) {
+      var element = elements[i];
+      self._surfaceIdentifiedElements[element.getType()][element.getId()] = element;
+    }
+    return self.getIdentifiedElements();
+  }).then(function (elements) {
+    self.enableAddRemoveElements();
+    return self.callListeners("onSearch", {
+      fitBounds: false,
+      identifiedElements: elements
+    });
+  }).then(null, function (error) {
+    self.enableAddRemoveElements();
+    return Promise.reject(error);
+  });
+};
+
+UserDbOverlay.prototype.removeMarker = function (params) {
+  var self = this;
+  self.disableAddRemoveElements();
+
+  if (params.length === undefined) {
+    params = [params];
+  }
+
+  return self._createIdentifiedElements(params, self._markerIdentifiedElements, false).then(function (elements) {
+    for (var i = 0; i < elements.length; i++) {
+      var element = elements[i];
+      self._markerIdentifiedElements[element.getType()][element.getId()] = undefined;
+      delete self._markerIdentifiedElements[element.getType()][element.getId()];
+    }
+    return self.getIdentifiedElements();
+  }).then(function (elements) {
+    self.enableAddRemoveElements();
+    return self.callListeners("onSearch", {
+      fitBounds: false,
+      identifiedElements: elements
+    });
+  }).then(null, function (error) {
+    self.enableAddRemoveElements();
+    return Promise.reject(error);
+  });
+};
+
+UserDbOverlay.prototype.removeSurface = function (params) {
+  var self = this;
+  self.disableAddRemoveElements();
+
+  if (params.length === undefined) {
+    params = [params];
+  }
+  return self._createIdentifiedElements(params, self._surfaceIdentifiedElements, false).then(function (elements) {
+    for (var i = 0; i < elements.length; i++) {
+      var element = elements[i];
+      self._surfaceIdentifiedElements[element.getType()][element.getId()] = undefined;
+      delete self._surfaceIdentifiedElements[element.getType()][element.getId()];
+    }
+    return self.getIdentifiedElements();
+  }).then(function (elements) {
+    self.enableAddRemoveElements();
+    return self.callListeners("onSearch", {
+      fitBounds: false,
+      identifiedElements: elements
+    });
+  }).then(null, function (error) {
+    self.enableAddRemoveElements();
+    return Promise.reject(error);
+  });
+};
+
+UserDbOverlay.prototype.disableAddRemoveElements = function () {
+  if (this._addRemoveElementsDisabled) {
+    throw new Error("wait until previous Promise for showBioEntity/hideBioEntity is resolved");
+  } else {
+    this._addRemoveElementsDisabled = true;
+  }
+};
+UserDbOverlay.prototype.enableAddRemoveElements = function () {
+  if (this._addRemoveElementsDisabled) {
+    this._addRemoveElementsDisabled = false;
+  } else {
+    logger.warn("showBioEntity/hideBioEntity is not disabled");
+  }
+};
+
+UserDbOverlay.prototype.getIdentifiedElements = function () {
+  var result = [];
+  var markerType, key, markers;
+  for (markerType in this._markerIdentifiedElements) {
+    if (this._markerIdentifiedElements.hasOwnProperty(markerType)) {
+      markers = this._markerIdentifiedElements[markerType];
+      for (key in markers) {
+        if (markers.hasOwnProperty(key)) {
+          var identifiedElement = markers[key];
+          if (identifiedElement.getIcon() === undefined) {
+            identifiedElement.setIcon("marker/generic/search_red.png");
+          }
+          result.push(identifiedElement);
+        }
+      }
+    }
+  }
+
+  for (markerType in this._surfaceIdentifiedElements) {
+    if (this._surfaceIdentifiedElements.hasOwnProperty(markerType)) {
+      markers = this._surfaceIdentifiedElements[markerType];
+      for (key in markers) {
+        if (markers.hasOwnProperty(key)) {
+          result.push(markers[key]);
+        }
+      }
+    }
+  }
+
+  return Promise.resolve(result);
+};
+
+UserDbOverlay.prototype.clear = function () {
+  var self = this;
+  self._markerIdentifiedElements = {
+    ALIAS: [],
+    REACTION: [],
+    POINT: []
+  };
+  return self.callListeners("onSearch", {
+    fitBounds: false,
+    identifiedElements: []
+  });
+};
+
+module.exports = UserDbOverlay;
diff --git a/frontend-js/src/main/js/map/surface/AbstractSurfaceElement.js b/frontend-js/src/main/js/map/surface/AbstractSurfaceElement.js
index 4e058339ecb3da145ffd68e12a64579818dc171d..e3fd29c3ed937a7845360b6c1d1f5cf52728e3cb 100644
--- a/frontend-js/src/main/js/map/surface/AbstractSurfaceElement.js
+++ b/frontend-js/src/main/js/map/surface/AbstractSurfaceElement.js
@@ -1,221 +1,221 @@
-"use strict";
-
-var logger = require('../../logger');
-
-var Bounds = require('../canvas/Bounds');
-var ObjectWithListeners = require('../../ObjectWithListeners');
-var Promise = require('bluebird');
-
-/**
- * Class representing abstract overlay element on the map relevant for a
- * specific overlay.
- *
- * @param {IdentifiedElement} params.element
- * @param {AbstractCustomMap} params.map
- * @param {function|function[]} params.onClick
- * @constructor
- */
-function AbstractSurfaceElement(params) {
-  var self = this;
-  // call super constructor
-  ObjectWithListeners.call(this);
-
-  self.registerListenerType("onClick");
-  self.setCustomMap(params.map);
-  if (params.element !== undefined && params.element !== null) {
-    self.setIdentifiedElement(params.element);
-  }
-  self._mapCanvasObjects = [];
-
-  if (params.onClick !== undefined) {
-    if (typeof params.onClick !== "function") {
-      for (var i = 0; i < params.onClick.length; i++) {
-        self.addListener("onClick", params.onClick[i]);
-      }
-    } else {
-      self.addListener("onClick", params.onClick);
-    }
-  }
-}
-
-AbstractSurfaceElement.prototype = Object.create(ObjectWithListeners.prototype);
-AbstractSurfaceElement.prototype.constructor = AbstractSurfaceElement;
-
-/**
- *
- * @returns {boolean}
- */
-AbstractSurfaceElement.prototype.isShown = function () {
-  var result = false;
-  for (var i = 0; i < this.getMapCanvasObjects().length; i++) {
-    if (this.getMapCanvasObjects()[i].isShown()) {
-      result = true;
-    }
-  }
-  return result;
-};
-
-/**
- *
- * @returns {Promise}
- */
-AbstractSurfaceElement.prototype.show = function () {
-  var self = this;
-  if (!this.isInitialized()) {
-    return this.init().then(function () {
-      return self.show();
-    });
-  }
-  if (this.isShown()) {
-    logger.warn("Surface already shown");
-    return Promise.resolve();
-  }
-  var promises = [];
-  for (var i = 0; i < this.getMapCanvasObjects().length; i++) {
-    promises.push(this.getMapCanvasObjects()[i].show());
-  }
-  return Promise.all(promises);
-};
-
-/**
- *
- * @returns {boolean}
- */
-AbstractSurfaceElement.prototype.isInitialized = function () {
-  return this.getMapCanvasObjects().length > 0;
-};
-
-/**
- *
- * @returns {Promise}
- */
-AbstractSurfaceElement.prototype.hide = function () {
-  var promises = [];
-  for (var i = 0; i < this.getMapCanvasObjects().length; i++) {
-    promises.push(this.getMapCanvasObjects()[i].hide());
-  }
-  return Promise.all(promises);
-};
-
-/**
- *
- * @returns {Promise|PromiseLike}
- */
-AbstractSurfaceElement.prototype.onClickHandler = function () {
-  return this.callListeners("onClick");
-};
-
-/**
- *
- * @returns {Array}
- */
-AbstractSurfaceElement.prototype.getMapCanvasObjects = function () {
-  return this._mapCanvasObjects;
-};
-
-/**
- *
- * @param {Rectangle|Polyline} object
- */
-AbstractSurfaceElement.prototype.addMapCanvasObject = function (object) {
-  this._mapCanvasObjects.push(object);
-
-  var self = this;
-  var onclick = function () {
-    return self.onClickHandler();
-  };
-  object.addListener('click', onclick);
-};
-
-/**
- *
- * @returns {IdentifiedElement}
- */
-AbstractSurfaceElement.prototype.getIdentifiedElement = function () {
-  return this._identifiedElement;
-};
-
-/**
- *
- * @param {IdentifiedElement} identifiedElement
- */
-AbstractSurfaceElement.prototype.setIdentifiedElement = function (identifiedElement) {
-  this._identifiedElement = identifiedElement;
-};
-
-/**
- *
- * @returns {BioEntity}
- */
-AbstractSurfaceElement.prototype.getBioEntity = function () {
-  return this._bioEntity;
-};
-
-/**
- *
- * @param {BioEntity} bioEntity
- */
-AbstractSurfaceElement.prototype.setBioEntity = function (bioEntity) {
-  this._bioEntity = bioEntity;
-};
-
-
-/**
- *
- * @returns {number}
- */
-AbstractSurfaceElement.prototype.getModelId = function () {
-  return this.getIdentifiedElement().getModelId();
-};
-
-/**
- *
- * @param {IdentifiedElement} identifiedElement
- */
-AbstractSurfaceElement.prototype.updateIdentifiedElement = function (identifiedElement) {
-  if (identifiedElement.getColor() !== undefined) {
-    this.setColor(identifiedElement.getColor());
-  }
-};
-
-/**
- *
- * @returns {Bounds}
- */
-AbstractSurfaceElement.prototype.getBounds = function () {
-  var self = this;
-  var bounds = new Bounds();
-  for (var i = 0; i < self.getMapCanvasObjects().length; i++) {
-    var elementBounds = self.getMapCanvasObjects()[i].getBounds();
-    bounds.extend(elementBounds.getTopLeft());
-    bounds.extend(elementBounds.getRightBottom());
-  }
-  return bounds;
-};
-
-/**
- * Returns {@link AbstractCustomMap} where surface is located.
- *
- * @returns {AbstractCustomMap} where surface is located
- */
-AbstractSurfaceElement.prototype.getCustomMap = function () {
-  return this._customMap;
-};
-
-/**
- *
- * @param {AbstractCustomMap} customMap
- */
-AbstractSurfaceElement.prototype.setCustomMap = function (customMap) {
-  this._customMap = customMap;
-};
-
-/**
- *
- * @returns {Point}
- */
-AbstractSurfaceElement.prototype.getCenter = function () {
-  return this.getBioEntity().getCenter();
-};
-
-module.exports = AbstractSurfaceElement;
+"use strict";
+
+var logger = require('../../logger');
+
+var Bounds = require('../canvas/Bounds');
+var ObjectWithListeners = require('../../ObjectWithListeners');
+var Promise = require('bluebird');
+
+/**
+ * Class representing abstract overlay element on the map relevant for a
+ * specific overlay.
+ *
+ * @param {IdentifiedElement} params.element
+ * @param {AbstractCustomMap} params.map
+ * @param {function|function[]} params.onClick
+ * @constructor
+ */
+function AbstractSurfaceElement(params) {
+  var self = this;
+  // call super constructor
+  ObjectWithListeners.call(this);
+
+  self.registerListenerType("onClick");
+  self.setCustomMap(params.map);
+  if (params.element !== undefined && params.element !== null) {
+    self.setIdentifiedElement(params.element);
+  }
+  self._mapCanvasObjects = [];
+
+  if (params.onClick !== undefined) {
+    if (typeof params.onClick !== "function") {
+      for (var i = 0; i < params.onClick.length; i++) {
+        self.addListener("onClick", params.onClick[i]);
+      }
+    } else {
+      self.addListener("onClick", params.onClick);
+    }
+  }
+}
+
+AbstractSurfaceElement.prototype = Object.create(ObjectWithListeners.prototype);
+AbstractSurfaceElement.prototype.constructor = AbstractSurfaceElement;
+
+/**
+ *
+ * @returns {boolean}
+ */
+AbstractSurfaceElement.prototype.isShown = function () {
+  var result = false;
+  for (var i = 0; i < this.getMapCanvasObjects().length; i++) {
+    if (this.getMapCanvasObjects()[i].isShown()) {
+      result = true;
+    }
+  }
+  return result;
+};
+
+/**
+ *
+ * @returns {Promise}
+ */
+AbstractSurfaceElement.prototype.show = function () {
+  var self = this;
+  if (!this.isInitialized()) {
+    return this.init().then(function () {
+      return self.show();
+    });
+  }
+  if (this.isShown()) {
+    logger.warn("Surface already shown");
+    return Promise.resolve();
+  }
+  var promises = [];
+  for (var i = 0; i < this.getMapCanvasObjects().length; i++) {
+    promises.push(this.getMapCanvasObjects()[i].show());
+  }
+  return Promise.all(promises);
+};
+
+/**
+ *
+ * @returns {boolean}
+ */
+AbstractSurfaceElement.prototype.isInitialized = function () {
+  return this.getMapCanvasObjects().length > 0;
+};
+
+/**
+ *
+ * @returns {Promise}
+ */
+AbstractSurfaceElement.prototype.hide = function () {
+  var promises = [];
+  for (var i = 0; i < this.getMapCanvasObjects().length; i++) {
+    promises.push(this.getMapCanvasObjects()[i].hide());
+  }
+  return Promise.all(promises);
+};
+
+/**
+ *
+ * @returns {Promise|PromiseLike}
+ */
+AbstractSurfaceElement.prototype.onClickHandler = function () {
+  return this.callListeners("onClick");
+};
+
+/**
+ *
+ * @returns {Array}
+ */
+AbstractSurfaceElement.prototype.getMapCanvasObjects = function () {
+  return this._mapCanvasObjects;
+};
+
+/**
+ *
+ * @param {Rectangle|Polyline} object
+ */
+AbstractSurfaceElement.prototype.addMapCanvasObject = function (object) {
+  this._mapCanvasObjects.push(object);
+
+  var self = this;
+  var onclick = function () {
+    return self.onClickHandler();
+  };
+  object.addListener('click', onclick);
+};
+
+/**
+ *
+ * @returns {IdentifiedElement}
+ */
+AbstractSurfaceElement.prototype.getIdentifiedElement = function () {
+  return this._identifiedElement;
+};
+
+/**
+ *
+ * @param {IdentifiedElement} identifiedElement
+ */
+AbstractSurfaceElement.prototype.setIdentifiedElement = function (identifiedElement) {
+  this._identifiedElement = identifiedElement;
+};
+
+/**
+ *
+ * @returns {BioEntity}
+ */
+AbstractSurfaceElement.prototype.getBioEntity = function () {
+  return this._bioEntity;
+};
+
+/**
+ *
+ * @param {BioEntity} bioEntity
+ */
+AbstractSurfaceElement.prototype.setBioEntity = function (bioEntity) {
+  this._bioEntity = bioEntity;
+};
+
+
+/**
+ *
+ * @returns {number}
+ */
+AbstractSurfaceElement.prototype.getModelId = function () {
+  return this.getIdentifiedElement().getModelId();
+};
+
+/**
+ *
+ * @param {IdentifiedElement} identifiedElement
+ */
+AbstractSurfaceElement.prototype.updateIdentifiedElement = function (identifiedElement) {
+  if (identifiedElement.getColor() !== undefined) {
+    this.setColor(identifiedElement.getColor());
+  }
+};
+
+/**
+ *
+ * @returns {Bounds}
+ */
+AbstractSurfaceElement.prototype.getBounds = function () {
+  var self = this;
+  var bounds = new Bounds();
+  for (var i = 0; i < self.getMapCanvasObjects().length; i++) {
+    var elementBounds = self.getMapCanvasObjects()[i].getBounds();
+    bounds.extend(elementBounds.getTopLeft());
+    bounds.extend(elementBounds.getRightBottom());
+  }
+  return bounds;
+};
+
+/**
+ * Returns {@link AbstractCustomMap} where surface is located.
+ *
+ * @returns {AbstractCustomMap} where surface is located
+ */
+AbstractSurfaceElement.prototype.getCustomMap = function () {
+  return this._customMap;
+};
+
+/**
+ *
+ * @param {AbstractCustomMap} customMap
+ */
+AbstractSurfaceElement.prototype.setCustomMap = function (customMap) {
+  this._customMap = customMap;
+};
+
+/**
+ *
+ * @returns {Point}
+ */
+AbstractSurfaceElement.prototype.getCenter = function () {
+  return this.getBioEntity().getCenter();
+};
+
+module.exports = AbstractSurfaceElement;
diff --git a/frontend-js/src/main/js/map/surface/ReactionSurface.js b/frontend-js/src/main/js/map/surface/ReactionSurface.js
index 8b8a0520a82df550b515ef5d53bd6d8143cae473..b750368fcbf609325c0c9f31d3c5835b3cf59167 100644
--- a/frontend-js/src/main/js/map/surface/ReactionSurface.js
+++ b/frontend-js/src/main/js/map/surface/ReactionSurface.js
@@ -1,313 +1,313 @@
-"use strict";
-
-var Bounds = require('../canvas/Bounds');
-var Point = require('../canvas/Point');
-var Promise = require("bluebird");
-
-/* exported logger */
-
-var functions = require('../../Functions');
-// noinspection JSUnusedLocalSymbols
-var logger = require('../../logger');
-
-var AbstractSurfaceElement = require('./AbstractSurfaceElement');
-var IdentifiedElement = require('../data/IdentifiedElement');
-
-/**
- *
- * @param {IdentifiedElement} [params.element]
- * @param {AbstractCustomMap} params.map
- * @param {function|function[]} [params.onClick]
- * @param {Reaction} params.reaction
- * @param {LayoutReaction} [params.layoutReaction]
- * @param {boolean} params.customized
- * @param {string} [params.color]
- * @constructor
- * @extends AbstractSurfaceElement
- */
-function ReactionSurface(params) {
-  // call super constructor
-  AbstractSurfaceElement.call(this, params);
-
-  this.setWidth(5.0);
-  this.setOverlayData(params.layoutReaction);
-  this.setBioEntity(params.reaction);
-
-  var color = params.color;
-
-  if (color === undefined) {
-    color = "#0000FF";
-  }
-
-  this.setColor(color);
-  this.setCustomized(params.customized);
-  this.setIdentifiedElement(new IdentifiedElement(this.getBioEntity()));
-}
-
-ReactionSurface.prototype = Object.create(AbstractSurfaceElement.prototype);
-ReactionSurface.prototype.constructor = ReactionSurface;
-
-/**
- * Returns {@link Bounds} of all google maps elements
- * included in the object.
- *
- * @returns {Bounds} of all google maps elements
- *          included in the object
- */
-ReactionSurface.prototype.getBounds = function () {
-  var bounds = new Bounds();
-
-  for (var i = 0; i < this.getMapCanvasObjects().length; i++) {
-    var line = this.getMapCanvasObjects()[i];
-    bounds.extend(line.getBounds());
-  }
-  return bounds;
-};
-
-/**
- *
- * @param {boolean} customized
- */
-ReactionSurface.prototype.setCustomized = function (customized) {
-  this.customized = customized;
-};
-
-/**
- * Sets color to be used by the reaction overlay visualization when visualized
- * in customized mode.
- *
- * @param {string} color
- *          new color value
- */
-ReactionSurface.prototype.setColor = function (color) {
-  this._color = color;
-  var mapCanvasObjects = this.getMapCanvasObjects();
-  for (var i = 0; i < mapCanvasObjects.length; i++) {
-    mapCanvasObjects[i].setOptions({
-      strokeColor: color
-    });
-  }
-  this.customized = true;
-};
-
-/**
- * Sets width of line to be used by the reaction overlay visualization when
- * visualized in customized mode.
- *
- * @param {number} width
- *          new width value
- */
-ReactionSurface.prototype.setWidth = function (width) {
-  if (width !== undefined && width !== null) {
-    this.width = width;
-  } else {
-    this.width = 1.0;
-  }
-
-};
-
-/**
- * Returns color that should be used when visualized in customized mode.
- *
- * @returns {string} color that should be used when visualized in customized mode.
- */
-ReactionSurface.prototype.getColor = function () {
-  return this._color;
-};
-
-/**
- * Returns width that should be used when visualized in customized mode.
- *
- * @returns {number} width that should be used when visualized in customized mode.
- */
-ReactionSurface.prototype.getWidth = function () {
-  return this.width;
-};
-
-/**
- * This function is used when some overlays are added/removed from visualization.
- * The syntax is compatible with AliasSurface class so they can be handled in
- * the same way. When visualizing more than one overlay startX or endX will be
- * set to a value between 0..1 (not inclusive). In such case the visualization
- * of reaction should turn to some default mode where we know that reaction is
- * highlighted, but we have no more information. In this way user will know that
- * he should investigate the reaction manually.
- *
- * @param {number} startX
- *          see {AliasSurface} class for details, in this implementation the
- *          only important information is that when there are more than one
- *          overlay visualized at least one of the two parameters (startX,endX)
- *          will differ from {0.0, 1.0} values
- * @param {number} endX
- *          see {AliasSurface} class for details, in this implementation the
- *          only important information is that when there are more than one
- *          overlay visualized at least one of the two parameters (startX,endX)
- *          will differ from {0.0, 1.0} values
- */
-ReactionSurface.prototype.setBoundsForAlias = function (startX, endX) {
-  if (this.isCustomized() && (startX > 0 || endX < 1)) {
-    this.changedToDefault();
-  } else if (!this.isCustomized() && (startX <= 0 && endX >= 1)) {
-    this.changedToCustomized();
-  }
-};
-
-/**
- * Changes visualization of the ReactionSurface to default mode where we mark
- * reaction as highlighted, but we skip customized reaction overlay data.
- */
-ReactionSurface.prototype.changedToDefault = function () {
-  for (var i = 0; i < this.getMapCanvasObjects().length; i++) {
-    this.getMapCanvasObjects()[i].setOptions({
-      strokeColor: "#0000FF",
-      strokeWeight: 5
-    });
-  }
-  this.customized = false;
-};
-
-/**
- * Changes visualization of the ReactionSurface to customized mode where we mark
- * reaction as highlighted with customized reaction overlay data.
- */
-ReactionSurface.prototype.changedToCustomized = function () {
-  for (var i = 0; i < this.getMapCanvasObjects().length; i++) {
-    this.getMapCanvasObjects()[i].setOptions({
-      strokeColor: this.getColor(),
-      strokeWeight: this.getWidth()
-    });
-  }
-  this.customized = true;
-};
-
-/**
- * Creates {google.maps.Polyline} from input data.
- *
- * @param {Object} line
- *          raw data about line taken from server
- * @param {number} line.start.x
- * @param {number} line.start.y
- * @param {number} line.end.x
- * @param {number} line.end.y
- *
- * @param {string} color
- *          color that should be used for visualization of the line
- * @param {number} width
- *          width that should be used for visualization of the line
- * @param {AbstractCustomMap} map
- *          where line should be visualized
- * @returns {Polyline} from input data
- */
-ReactionSurface.createLine = function (line, color, width, map) {
-  var pointA = new Point(line.start.x, line.start.y);
-  var pointB = new Point(line.end.x, line.end.y);
-  var path = [pointA, pointB];
-
-  return map.getMapCanvas().createPolyline({
-    strokeColor: color,
-    strokeOpacity: 1.0,
-    strokeWeight: width,
-    path: path
-  });
-};
-
-/**
- *
- * @returns {number}
- */
-ReactionSurface.prototype.getId = function () {
-  return this._id;
-};
-
-/**
- *
- * @param {number} id
- */
-ReactionSurface.prototype.setId = function (id) {
-  this._id = id;
-};
-
-/**
- *
- * @returns {LayoutReaction}
- */
-ReactionSurface.prototype.getOverlayData = function () {
-  return this._overlayData;
-};
-
-/**
- *
- * @param {LayoutReaction} overlayData
- */
-ReactionSurface.prototype.setOverlayData = function (overlayData) {
-  this._overlayData = overlayData;
-  if (overlayData !== undefined) {
-    if (overlayData.width) {
-      this.setWidth(overlayData.width);
-    }
-  }
-};
-
-/**
- *
- * @param {BioEntity} bioEntity
- */
-ReactionSurface.prototype.setBioEntity = function (bioEntity) {
-  if (bioEntity === undefined || bioEntity === null) {
-    throw new Error("Reaction must be defined");
-  }
-  AbstractSurfaceElement.prototype.setBioEntity.call(this, bioEntity);
-  this.setId(bioEntity.getId());
-};
-
-/**
- *
- * @returns {boolean}
- */
-ReactionSurface.prototype.isCustomized = function () {
-  return this.customized;
-};
-
-/**
- *
- * @returns {Promise}
- */
-ReactionSurface.prototype.init = function () {
-  var self = this;
-  var reaction = this.getBioEntity();
-  var overlayData = this.getOverlayData();
-
-  var promise = Promise.resolve(self.getColor());
-  if (overlayData !== undefined && overlayData !== null) {
-    promise = functions.overlayToColor(overlayData);
-  }
-  return promise.then(function (color) {
-    if (color === undefined) {
-      color = "#0000FF";
-    }
-    self.setColor(color);
-    var i;
-    var line;
-    var googleLine;
-    for (i = 0; i < reaction.startLines.length; i++) {
-      line = reaction.startLines[i];
-      googleLine = ReactionSurface.createLine(line, self.getColor(), self.getWidth(), self.getCustomMap());
-      self.addMapCanvasObject(googleLine);
-    }
-    for (i = 0; i < reaction.endLines.length; i++) {
-      line = reaction.endLines[i];
-      googleLine = ReactionSurface.createLine(line, self.getColor(), self.getWidth(), self.getCustomMap());
-      self.addMapCanvasObject(googleLine);
-    }
-    for (i = 0; i < reaction.midLines.length; i++) {
-      line = reaction.midLines[i];
-      googleLine = ReactionSurface.createLine(line, self.getColor(), self.getWidth(), self.getCustomMap());
-      self.addMapCanvasObject(googleLine);
-    }
-    if (!self.isCustomized()) {
-      self.changedToDefault();
-    }
-  });
-};
-
-module.exports = ReactionSurface;
+"use strict";
+
+var Bounds = require('../canvas/Bounds');
+var Point = require('../canvas/Point');
+var Promise = require("bluebird");
+
+/* exported logger */
+
+var functions = require('../../Functions');
+// noinspection JSUnusedLocalSymbols
+var logger = require('../../logger');
+
+var AbstractSurfaceElement = require('./AbstractSurfaceElement');
+var IdentifiedElement = require('../data/IdentifiedElement');
+
+/**
+ *
+ * @param {IdentifiedElement} [params.element]
+ * @param {AbstractCustomMap} params.map
+ * @param {function|function[]} [params.onClick]
+ * @param {Reaction} params.reaction
+ * @param {LayoutReaction} [params.layoutReaction]
+ * @param {boolean} params.customized
+ * @param {string} [params.color]
+ * @constructor
+ * @extends AbstractSurfaceElement
+ */
+function ReactionSurface(params) {
+  // call super constructor
+  AbstractSurfaceElement.call(this, params);
+
+  this.setWidth(5.0);
+  this.setOverlayData(params.layoutReaction);
+  this.setBioEntity(params.reaction);
+
+  var color = params.color;
+
+  if (color === undefined) {
+    color = "#0000FF";
+  }
+
+  this.setColor(color);
+  this.setCustomized(params.customized);
+  this.setIdentifiedElement(new IdentifiedElement(this.getBioEntity()));
+}
+
+ReactionSurface.prototype = Object.create(AbstractSurfaceElement.prototype);
+ReactionSurface.prototype.constructor = ReactionSurface;
+
+/**
+ * Returns {@link Bounds} of all google maps elements
+ * included in the object.
+ *
+ * @returns {Bounds} of all google maps elements
+ *          included in the object
+ */
+ReactionSurface.prototype.getBounds = function () {
+  var bounds = new Bounds();
+
+  for (var i = 0; i < this.getMapCanvasObjects().length; i++) {
+    var line = this.getMapCanvasObjects()[i];
+    bounds.extend(line.getBounds());
+  }
+  return bounds;
+};
+
+/**
+ *
+ * @param {boolean} customized
+ */
+ReactionSurface.prototype.setCustomized = function (customized) {
+  this.customized = customized;
+};
+
+/**
+ * Sets color to be used by the reaction overlay visualization when visualized
+ * in customized mode.
+ *
+ * @param {string} color
+ *          new color value
+ */
+ReactionSurface.prototype.setColor = function (color) {
+  this._color = color;
+  var mapCanvasObjects = this.getMapCanvasObjects();
+  for (var i = 0; i < mapCanvasObjects.length; i++) {
+    mapCanvasObjects[i].setOptions({
+      strokeColor: color
+    });
+  }
+  this.customized = true;
+};
+
+/**
+ * Sets width of line to be used by the reaction overlay visualization when
+ * visualized in customized mode.
+ *
+ * @param {number} width
+ *          new width value
+ */
+ReactionSurface.prototype.setWidth = function (width) {
+  if (width !== undefined && width !== null) {
+    this.width = width;
+  } else {
+    this.width = 1.0;
+  }
+
+};
+
+/**
+ * Returns color that should be used when visualized in customized mode.
+ *
+ * @returns {string} color that should be used when visualized in customized mode.
+ */
+ReactionSurface.prototype.getColor = function () {
+  return this._color;
+};
+
+/**
+ * Returns width that should be used when visualized in customized mode.
+ *
+ * @returns {number} width that should be used when visualized in customized mode.
+ */
+ReactionSurface.prototype.getWidth = function () {
+  return this.width;
+};
+
+/**
+ * This function is used when some overlays are added/removed from visualization.
+ * The syntax is compatible with AliasSurface class so they can be handled in
+ * the same way. When visualizing more than one overlay startX or endX will be
+ * set to a value between 0..1 (not inclusive). In such case the visualization
+ * of reaction should turn to some default mode where we know that reaction is
+ * highlighted, but we have no more information. In this way user will know that
+ * he should investigate the reaction manually.
+ *
+ * @param {number} startX
+ *          see {AliasSurface} class for details, in this implementation the
+ *          only important information is that when there are more than one
+ *          overlay visualized at least one of the two parameters (startX,endX)
+ *          will differ from {0.0, 1.0} values
+ * @param {number} endX
+ *          see {AliasSurface} class for details, in this implementation the
+ *          only important information is that when there are more than one
+ *          overlay visualized at least one of the two parameters (startX,endX)
+ *          will differ from {0.0, 1.0} values
+ */
+ReactionSurface.prototype.setBoundsForAlias = function (startX, endX) {
+  if (this.isCustomized() && (startX > 0 || endX < 1)) {
+    this.changedToDefault();
+  } else if (!this.isCustomized() && (startX <= 0 && endX >= 1)) {
+    this.changedToCustomized();
+  }
+};
+
+/**
+ * Changes visualization of the ReactionSurface to default mode where we mark
+ * reaction as highlighted, but we skip customized reaction overlay data.
+ */
+ReactionSurface.prototype.changedToDefault = function () {
+  for (var i = 0; i < this.getMapCanvasObjects().length; i++) {
+    this.getMapCanvasObjects()[i].setOptions({
+      strokeColor: "#0000FF",
+      strokeWeight: 5
+    });
+  }
+  this.customized = false;
+};
+
+/**
+ * Changes visualization of the ReactionSurface to customized mode where we mark
+ * reaction as highlighted with customized reaction overlay data.
+ */
+ReactionSurface.prototype.changedToCustomized = function () {
+  for (var i = 0; i < this.getMapCanvasObjects().length; i++) {
+    this.getMapCanvasObjects()[i].setOptions({
+      strokeColor: this.getColor(),
+      strokeWeight: this.getWidth()
+    });
+  }
+  this.customized = true;
+};
+
+/**
+ * Creates {google.maps.Polyline} from input data.
+ *
+ * @param {Object} line
+ *          raw data about line taken from server
+ * @param {number} line.start.x
+ * @param {number} line.start.y
+ * @param {number} line.end.x
+ * @param {number} line.end.y
+ *
+ * @param {string} color
+ *          color that should be used for visualization of the line
+ * @param {number} width
+ *          width that should be used for visualization of the line
+ * @param {AbstractCustomMap} map
+ *          where line should be visualized
+ * @returns {Polyline} from input data
+ */
+ReactionSurface.createLine = function (line, color, width, map) {
+  var pointA = new Point(line.start.x, line.start.y);
+  var pointB = new Point(line.end.x, line.end.y);
+  var path = [pointA, pointB];
+
+  return map.getMapCanvas().createPolyline({
+    strokeColor: color,
+    strokeOpacity: 1.0,
+    strokeWeight: width,
+    path: path
+  });
+};
+
+/**
+ *
+ * @returns {number}
+ */
+ReactionSurface.prototype.getId = function () {
+  return this._id;
+};
+
+/**
+ *
+ * @param {number} id
+ */
+ReactionSurface.prototype.setId = function (id) {
+  this._id = id;
+};
+
+/**
+ *
+ * @returns {LayoutReaction}
+ */
+ReactionSurface.prototype.getOverlayData = function () {
+  return this._overlayData;
+};
+
+/**
+ *
+ * @param {LayoutReaction} overlayData
+ */
+ReactionSurface.prototype.setOverlayData = function (overlayData) {
+  this._overlayData = overlayData;
+  if (overlayData !== undefined) {
+    if (overlayData.width) {
+      this.setWidth(overlayData.width);
+    }
+  }
+};
+
+/**
+ *
+ * @param {BioEntity} bioEntity
+ */
+ReactionSurface.prototype.setBioEntity = function (bioEntity) {
+  if (bioEntity === undefined || bioEntity === null) {
+    throw new Error("Reaction must be defined");
+  }
+  AbstractSurfaceElement.prototype.setBioEntity.call(this, bioEntity);
+  this.setId(bioEntity.getId());
+};
+
+/**
+ *
+ * @returns {boolean}
+ */
+ReactionSurface.prototype.isCustomized = function () {
+  return this.customized;
+};
+
+/**
+ *
+ * @returns {Promise}
+ */
+ReactionSurface.prototype.init = function () {
+  var self = this;
+  var reaction = this.getBioEntity();
+  var overlayData = this.getOverlayData();
+
+  var promise = Promise.resolve(self.getColor());
+  if (overlayData !== undefined && overlayData !== null) {
+    promise = functions.overlayToColor(overlayData);
+  }
+  return promise.then(function (color) {
+    if (color === undefined) {
+      color = "#0000FF";
+    }
+    self.setColor(color);
+    var i;
+    var line;
+    var googleLine;
+    for (i = 0; i < reaction.startLines.length; i++) {
+      line = reaction.startLines[i];
+      googleLine = ReactionSurface.createLine(line, self.getColor(), self.getWidth(), self.getCustomMap());
+      self.addMapCanvasObject(googleLine);
+    }
+    for (i = 0; i < reaction.endLines.length; i++) {
+      line = reaction.endLines[i];
+      googleLine = ReactionSurface.createLine(line, self.getColor(), self.getWidth(), self.getCustomMap());
+      self.addMapCanvasObject(googleLine);
+    }
+    for (i = 0; i < reaction.midLines.length; i++) {
+      line = reaction.midLines[i];
+      googleLine = ReactionSurface.createLine(line, self.getColor(), self.getWidth(), self.getCustomMap());
+      self.addMapCanvasObject(googleLine);
+    }
+    if (!self.isCustomized()) {
+      self.changedToDefault();
+    }
+  });
+};
+
+module.exports = ReactionSurface;
diff --git a/frontend-js/src/main/js/minerva.js b/frontend-js/src/main/js/minerva.js
index 88c4a9baf3c732deb5eaa3f16b0fa6050360b402..3a7e83e4f4c693eae4d6db66666c232a58f0c9b1 100644
--- a/frontend-js/src/main/js/minerva.js
+++ b/frontend-js/src/main/js/minerva.js
@@ -1,654 +1,654 @@
-'use strict';
-
-var functions = require('./Functions');
-
-var AbstractDbOverlay = require('./map/overlay/AbstractDbOverlay');
-var Admin = require('./Admin');
-var DbOverlayCollection = require('./map/overlay/DbOverlayCollection');
-var ConfigurationType = require('./ConfigurationType');
-var CustomMap = require('./map/CustomMap');
-var CustomMapOptions = require('./map/CustomMapOptions');
-var Export = require('./Export');
-var GuiUtils = require('./gui/leftPanel/GuiUtils');
-var PluginManager = require('./plugin/PluginManager');
-var Point = require('./map/canvas/Point');
-var SearchDbOverlay = require('./map/overlay/SearchDbOverlay');
-
-var LeftPanel = require('./gui/leftPanel/LeftPanel');
-var TopMenu = require('./gui/topMenu/TopMenu');
-var Legend = require('./gui/Legend');
-var MapContextMenu = require('./gui/MapContextMenu');
-var SelectionContextMenu = require('./gui/SelectionContextMenu');
-
-var GuiConnector = require('./GuiConnector');
-var ServerConnector = require('./ServerConnector');
-
-var MolArt = require('./map/structure/MolArt');
-
-var Promise = require("bluebird");
-
-var logger = require('./logger');
-
-
-var customMap, leftPanel, topMenu, legend, mapContextMenu, selectionContextMenu;
-
-function processUrlGetParams(params) {
-  var project = params.getProject();
-  var sessionData = ServerConnector.getSessionData(project);
-
-  var modelId;
-  if (GuiConnector.getParams["submap"] !== undefined) {
-    modelId = parseInt(GuiConnector.getParams["submap"]);
-  } else {
-    modelId = project.getModels()[0].getId()
-  }
-
-  var model = project.getModelById(modelId);
-
-  if (GuiConnector.getParams["x"] !== undefined && GuiConnector.getParams["y"] !== undefined) {
-    var point = new Point(GuiConnector.getParams["x"], GuiConnector.getParams["y"]);
-    sessionData.setCenter(model, point);
-  }
-  if (GuiConnector.getParams["zoom"] !== undefined) {
-    sessionData.setZoomLevel(model, GuiConnector.getParams["zoom"]);
-  }
-
-  if (GuiConnector.getParams["comments"] === "on") {
-    sessionData.setShowComments(true);
-  }
-  if (GuiConnector.getParams["search"] !== undefined) {
-    var query = SearchDbOverlay.prototype.encodeQuery(AbstractDbOverlay.QueryType.SEARCH_BY_QUERY,
-      GuiConnector.getParams["search"]);
-    sessionData.setSearchQuery(query);
-  }
-
-}
-
-/**
- *
- * @param {User} user
- * @param {string} termsOfUseUrl
- */
-function requestConsent(user, termsOfUseUrl) {
-  if (termsOfUseUrl === "") {
-    return;
-  }
-  var dialog = document.createElement("div");
-  var dialogContent = document.createElement("div");
-  dialogContent.appendChild(functions.createElement({
-    type: "span",
-    content: "I agree to the minerva <a href='" + termsOfUseUrl + "' target='_blank'>Terms of Use</a>."
-  }));
-  var checkbox = functions.createElement({type: "input", inputType: "checkbox", style: "float: left"});
-  var okButton = functions.createElement({
-    type: "button",
-    content: "OK",
-    className: "ui-button ui-corner-all ui-widget",
-    onclick: function () {
-      user.setTermsOfUseConsent($(checkbox).is(':checked'));
-      return ServerConnector.updateUser(user).then(function () {
-        $(dialog).dialog("close");
-      }).catch(GuiConnector.alert);
-    }
-  });
-  var cancelButton = functions.createElement({
-    type: "button",
-    content: "I disagree",
-    className: "ui-button ui-corner-all ui-widget",
-    onclick: function () {
-      return ServerConnector.logout().catch(GuiConnector.alert);
-    }
-  });
-  $(okButton).prop("disabled", true);
-  $(checkbox).change(function () {
-    $(okButton).prop("disabled", !$(checkbox).is(':checked'));
-  });
-  dialogContent.appendChild(checkbox);
-  dialogContent.appendChild(okButton);
-  dialogContent.appendChild(cancelButton);
-
-  dialog.appendChild(dialogContent);
-  document.body.appendChild(dialog);
-  $(dialog).dialog({
-    classes: {
-      "ui-dialog": "ui-state-error"
-    },
-    modal: true,
-    closeOnEscape: false,
-    title: "Terms of Use"
-  }).siblings('.ui-dialog-titlebar').css("background", "red");
-  $(".ui-dialog-titlebar-close", $(dialog).dialog().siblings('.ui-dialog-titlebar')).hide();
-  $(dialog).dialog("open");
-}
-
-function insertGoogleAnalyticsCode() {
-  return ServerConnector.getConfigurationParam(ConfigurationType.GOOGLE_ANALYTICS_IDENTIFIER).then(function (identifier) {
-    if (identifier === "" || identifier === undefined || identifier === null) {
-      return Promise.resolve();
-    } else {
-      global._gaq = global._gaq || [];
-      global._gaq.push(['_setAccount', identifier]);
-      global._gaq.push(['_trackPageview']);
-
-      (function () {
-        var ga = document.createElement('script');
-        ga.type = 'text/javascript';
-        ga.async = true;
-        ga.src = ('https:' === document.location.protocol ? 'https://ssl' : 'http://www')
-          + '.google-analytics.com/ga.js';
-        var s = document.getElementsByTagName('script')[0];
-        s.parentNode.insertBefore(ga, s);
-      })();
-      return Promise.resolve();
-    }
-  });
-}
-
-function createDivStructure(element) {
-  var tableDiv = functions.createElement({
-    type: "div",
-    className: "minerva-root"
-  });
-  element.appendChild(tableDiv);
-  var leftPanelDiv = functions.createElement({
-    type: "div",
-    className: "minerva-left-panel"
-  });
-  tableDiv.appendChild(leftPanelDiv);
-  var middlePanelDiv = functions.createElement({
-    type: "div",
-    className: "minerva-middle-panel"
-  });
-  tableDiv.appendChild(middlePanelDiv);
-
-  //this container is required because google maps API modifies DOM and it will crash
-  var middlePanelContainerDiv = functions.createElement({type: "div"});
-  middlePanelDiv.appendChild(middlePanelContainerDiv);
-
-  var splitBar = functions.createElement({
-    type: "div",
-    className: "minerva-plugin-split-bar",
-    content: "&nbsp"
-  });
-  tableDiv.appendChild(splitBar);
-
-  var rightPanelDiv = functions.createElement({
-    type: "div",
-    className: "minerva-plugin"
-  });
-  tableDiv.appendChild(rightPanelDiv);
-
-  var menuDiv = functions.createElement({
-    type: "div",
-    className: "minerva-top-menu"
-  });
-  middlePanelContainerDiv.appendChild(menuDiv);
-
-  var mapDiv = functions.createElement({
-    type: "div",
-    className: "minerva-map"
-  });
-  middlePanelContainerDiv.appendChild(mapDiv);
-
-  var legendDiv = functions.createElement({
-    type: "div",
-    name: "legendDiv",
-    className: "minerva-legend",
-    style: "display:none"
-  });
-  middlePanelContainerDiv.appendChild(legendDiv);
-
-  var contextMenu = functions.createElement({
-    type: "ul",
-    name: "contextMenu"
-  });
-  element.appendChild(contextMenu);
-  var selectionContextMenu = functions.createElement({
-    type: "ul",
-    name: "selectionContextMenu"
-  });
-  element.appendChild(selectionContextMenu);
-}
-
-
-function initGlobals(params) {
-  if (global.ServerConnector === undefined) {
-    global.ServerConnector = ServerConnector;
-    if (params.isDebug()) {
-      logger.setLevel("debug");
-    } else {
-      logger.setLevel("info");
-    }
-    GuiConnector.init();
-    if (GuiConnector.getParams['debug'] !== undefined) {
-      logger.setLevel("debug");
-    }
-  } else {
-    logger.warn("global ServerConnector found");
-  }
-
-}
-
-function verifyBrowser() {
-
-  var browser = functions.browser;
-  if (browser.name === "IE") {
-    if (browser.version <= 8 || browser.compatibilityMode) {
-      var message = "This web page works only with Internet Explorer version 9 or greater.\n"
-        + "If you have Internet Explorer version 9 or greater and still see this message, please, turn the 'Compatibility mode off:\n"
-        + "Open Internet Explorer and press the Alt key on your keyboard.\n"
-        + "Select 'Tools' menu item. \n"
-        + "Select the 'Compatibility View' settings option. \n"
-        + "Make sure the 'Display all websites in Compatibility View' check box is unchecked and that the 'Compatibility View; list of websites is cleared.\n"
-        + "\n" + "Alternatively, please, use other browsers: Chrome, Firefox or Safari.";
-      GuiConnector.alert(message);
-    }
-  }
-}
-
-function getProject(params) {
-  if (params.getProject() !== undefined) {
-    return Promise.resolve(params.getProject());
-  } else {
-    return ServerConnector.getProject(params.getProjectId());
-  }
-}
-
-function modifyParamsForTouchTable(params) {
-  if (params.bigLogo === undefined) {
-    // noinspection UnnecessaryLocalVariableJS
-    var isTouchTable = ((navigator.appVersion.indexOf("Win") > -1) && ('ontouchstart' in document.documentElement));
-    params.bigLogo = isTouchTable;
-  }
-  return params;
-}
-
-function assignSplitBarHandler(customMap, pluginManager) {
-  var splitBar = $('.minerva-plugin-split-bar');
-  var rightPanelDiv = $('.minerva-plugin');
-  var mouseDownHandler = function (e) {
-    e.preventDefault();
-    //TODO should use global size (but element size)
-    var x = $("body").width() - e.pageX;
-    $(rightPanelDiv).css("flex", "0 0 " + x + "px");
-    customMap.getMapCanvas().triggerListeners('resize');
-    return pluginManager.callListeners("onResize");
-  };
-  $(splitBar).mousedown(function (e) {
-    e.preventDefault();
-    $(document).mousemove(mouseDownHandler);
-  });
-  $(document).mouseup(function () {
-    $(document).unbind('mousemove', mouseDownHandler);
-  });
-}
-
-function create(params) {
-  params = modifyParamsForTouchTable(params);
-  if (!(params instanceof CustomMapOptions)) {
-    params = new CustomMapOptions(params);
-  }
-  params.setServerConnector(ServerConnector);
-  initGlobals(params);
-  params.getElement().innerHTML = "<div style='position:relative; width:100%;height:100%'>"
-    + "<img src='resources/images/icons/ajax-loader.gif' style='position:absolute;top:0;bottom:0;left:0;right:0;margin:auto;'/>" + "</div>";
-
-  // make sure that we are logged in
-  return ServerConnector.createSession().then(function () {
-    return ServerConnector.getConfiguration();
-  }).then(function (configuration) {
-    params.setConfiguration(configuration);
-    return getProject(params);
-  }).then(function (project) {
-    if (project === null) {
-      var message = "Project with given id doesn't exist.";
-      message += "<p>Please go to <a href='" + ServerConnector.getServerBaseUrl() + "'>default map</a>";
-      return Promise.reject(new Error(message));
-    }
-    params.setProject(project);
-    var promise = Promise.resolve();
-    if (params.getProject().getMapCanvasType() === "GOOGLE_MAPS_API") {
-      var apiKeySuffixString = '';
-      if (params.getConfiguration().getOption(ConfigurationType.GOOGLE_MAPS_API_KEY).getValue()) {
-        apiKeySuffixString = '&key=' + params.getConfiguration().getOption(ConfigurationType.GOOGLE_MAPS_API_KEY).getValue();
-      }
-      promise = functions.loadScript("https://maps.google.com/maps/api/js?libraries=drawing" + apiKeySuffixString);
-    }
-    return promise;
-  }).then(function () {
-    var element = params.getElement();
-
-    verifyBrowser();
-
-    processUrlGetParams(params);
-
-    params.getElement().innerHTML = "";
-    createDivStructure(element);
-    params.setElement(functions.getElementByClassName(element, "minerva-map"));
-
-    customMap = new CustomMap(params);
-
-
-    new DbOverlayCollection({
-      map: customMap
-    });
-
-    leftPanel = new LeftPanel({
-      element: functions.getElementByClassName(element, "minerva-left-panel"),
-      customMap: customMap,
-      configuration: params.getConfiguration()
-    });
-
-    var pluginManager = new PluginManager({
-      element: functions.getElementByClassName(element, "minerva-plugin"),
-      map: customMap,
-      project: params.getProject(),
-      configuration: params.getConfiguration()
-    });
-    leftPanel.setPluginManager(pluginManager);
-    assignSplitBarHandler(customMap, pluginManager);
-
-    topMenu = new TopMenu({
-      element: functions.getElementByClassName(element, "minerva-top-menu"),
-      customMap: customMap
-    });
-
-    legend = new Legend({
-      element: functions.getElementByName(element, "legendDiv"),
-      customMap: customMap
-    });
-
-    mapContextMenu = new MapContextMenu({
-      element: functions.getElementByName(element, "contextMenu"),
-      customMap: customMap,
-      molArt: new MolArt(element, customMap)
-    });
-    customMap.setContextMenu(mapContextMenu);
-
-    selectionContextMenu = new SelectionContextMenu({
-      element: functions.getElementByName(element, "selectionContextMenu"),
-      customMap: customMap
-    });
-    customMap.setSelectionContextMenu(selectionContextMenu);
-
-    topMenu.setLegend(legend);
-    topMenu.setLeftPanel(leftPanel);
-
-    return customMap.init();
-  }).then(function () {
-    return insertGoogleAnalyticsCode(customMap);
-  }).then(function () {
-    return leftPanel.init();
-  }).then(function () {
-    return legend.init();
-  }).then(function () {
-    return topMenu.init();
-  }).then(function () {
-    return selectionContextMenu.init();
-  }).then(function () {
-    return mapContextMenu.init();
-  }).then(function () {
-    if (GuiConnector.getParams["layout"] !== undefined) {
-      var overlays = params.getProject().getDataOverlays();
-      for (var j = 0; j < overlays.length; j++) {
-        var overlay = overlays[j];
-        if (overlay.getName() === GuiConnector.getParams["layout"]) {
-          return customMap.openDataOverlay(overlay);
-        }
-      }
-    }
-  }).then(function () {
-
-    var submapId = GuiConnector.getParams["submap"];
-    if (submapId !== undefined) {
-      return customMap.openSubmap(submapId);
-    }
-  }).then(function () {
-    var promises = [];
-    for (var i = 0; i < params.getPlugins().length; i++) {
-      promises.push(leftPanel.getPluginManager().addPlugin(params.getPlugins()[i]))
-    }
-    return Promise.all(promises);
-  }).then(function () {
-    return ServerConnector.getLoggedUser();
-  }).then(function (user) {
-    if (leftPanel.isGoogleLicenseConsentRequired()) {
-      GuiConnector.warn("Visualization of data overlays (Overlays tab) requires consent to terms of the <a href='https://cloud.google.com/maps-platform/terms/' target='_blank'>license of Google Maps Platform</a>. Click the \"Edit\" button for the overlay to do so.");
-    }
-    if (user.getLogin() !== "anonymous" && !user.isTermsOfUseConsent()) {
-      requestConsent(user, params.getConfiguration().getOption(ConfigurationType.TERMS_OF_USE).getValue());
-    }
-    var result = {
-      destroy: function () {
-        return leftPanel.destroy().then(function () {
-          customMap.destroy();
-          return topMenu.destroy();
-        });
-      },
-      getProject: function () {
-        return customMap.getProject();
-      }
-    };
-
-    if (params.isDebug()) {
-      result.leftPanel = leftPanel;
-      result.customMap = customMap;
-    }
-    return result;
-  });
-
-}
-
-function createFooter() {
-  var logoLink, logoText, logoImg;
-  return ServerConnector.getConfigurationParam(ConfigurationType.LOGO_LINK).then(function (result) {
-    logoLink = result;
-    return ServerConnector.getConfigurationParam(ConfigurationType.LOGO_TEXT);
-  }).then(function (result) {
-    logoText = result;
-    return ServerConnector.getConfigurationParam(ConfigurationType.LOGO_IMG);
-  }).then(function (result) {
-    logoImg = result;
-    return ServerConnector.getConfiguration();
-  }).then(function (configuration) {
-    return functions.createElement({
-      type: "div",
-      className: "minerva-footer-table",
-      content: '<table width="100%" border="0" cellspacing="0" cellpadding="0">' +
-      '<tr>' +
-      '<td align="left"><a href="' + logoLink + '" title="' + logoText + '" target="_blank">' +
-      '<img src="' + GuiConnector.getImgPrefix() + logoImg + '" width="80" height="80" border="0" alt="' + logoText + '"/>' +
-      '</a></td>' +
-      '<td align="center" class="minerva-footer-text">MiNERVA version ' + configuration.getVersion() + ';<br/>' +
-      'build ' + configuration.getBuildDate() + ';<br/>' +
-      'git: ' + configuration.getGitHash() + '</td>' +
-      '<td align="right"><a href="http://wwwen.uni.lu/lcsb/" title="LCSB - Luxembourg Centre for Systems Biomedicine" target="_blank">' +
-      '<img src="' + GuiConnector.getImgPrefix() + 'lcsb.png" width="80" height="80" border="0" alt="LCSB - Luxembourg Centre for Systems Biomedicine"/>' +
-      '</a></td>' +
-      '</tr>\n' +
-      '</table>', xss: false
-    });
-  })
-}
-
-function createLoginDiv() {
-  var loggedIn = false;
-
-  var result = functions.createElement({type: "center"});
-  var resultDiv = functions.createElement({type: "div", className: "minerva-login-form", style: "text-align:left"});
-  result.appendChild(resultDiv);
-  resultDiv.appendChild(functions.createElement({
-    type: "div",
-    className: "minerva-login-form-title",
-    content: "AUTHORIZATION FORM"
-  }));
-  var guiUtils = new GuiUtils();
-  var table = functions.createElement({
-    type: "div",
-    className: "loginDataPanelGrid",
-    style: "display: table;border-spacing:5px"
-  });
-  table.appendChild(guiUtils.createTableRow([
-    functions.createElement({type: "label", className: "labelText", content: "LOGIN:"}),
-    functions.createElement({type: "input", className: "minerva-input-text", id: "username"})]
-  ));
-  table.appendChild(guiUtils.createTableRow([
-    functions.createElement({type: "label", className: "labelText", content: "PASSWORD:"}),
-    functions.createElement({
-      type: "input",
-      inputType: "password",
-      className: "minerva-input-password",
-      id: "password"
-    })]
-  ));
-
-  table.appendChild(guiUtils.createTableRow([
-    functions.createElement({type: "label", className: "labelText"}),
-    functions.createElement({type: "button", className: "labelText", id: "login", content: "LOGIN"})]
-  ));
-
-  resultDiv.appendChild(table);
-  resultDiv.appendChild(functions.createElement({type: "br"}));
-  resultDiv.appendChild(functions.createElement({type: "br"}));
-  resultDiv.appendChild(functions.createElement({
-    type: "a",
-    href: "javascript:;",
-    id: "go_to_map_button",
-    className: "adminLink",
-    content: '<i class="fa fa-chevron-right"></i> BACK TO MAP',
-    xss: false
-  }));
-  resultDiv.appendChild(functions.createElement({type: "br"}));
-  resultDiv.appendChild(functions.createElement({
-    type: "a",
-    href: "javascript:;",
-    id: "register_button",
-    className: "adminLink",
-    content: '<i class="fa fa-chevron-right"></i> REQUEST AN ACCOUNT</a>',
-    xss: false
-  }));
-
-  var fromPage = GuiConnector.getParams["from"];
-
-  $("#login", result).on("click", function login() {
-    var loginString = document.getElementById('username').value;
-    var passwordString = document.getElementById('password').value;
-    return ServerConnector.login(loginString, passwordString).then(function () {
-      loggedIn = true;
-      if (fromPage !== undefined) {
-        window.location.href = fromPage;
-      } else {
-        window.location.href = ServerConnector.getServerBaseUrl();
-      }
-    }, function (error) {
-      if (error.constructor.name === "InvalidCredentialsError") {
-        GuiConnector.alert("invalid credentials");
-      } else {
-        GuiConnector.alert(error);
-      }
-    });
-  });
-  $('#go_to_map_button', result).click(function () {
-    return ServerConnector.getProjectId().then(function (projectId) {
-      window.location.href = ServerConnector.getServerBaseUrl() + '?id=' + projectId;
-    });
-  });
-  $('#register_button', result).click(function () {
-    var email, content;
-    return ServerConnector.getConfigurationParam("REQUEST_ACCOUNT_EMAIL").then(function (result) {
-      email = result;
-      return ServerConnector.getConfigurationParam("REQUEST_ACCOUNT_DEFAULT_CONTENT");
-    }).then(function (result) {
-      content = encodeURIComponent(result);
-      document.location.href = 'mailto:' + email + '?subject=MINERVA account request&body=' + content;
-    });
-  });
-
-  return result;
-}
-
-
-function createLogin(params) {
-  params = modifyParamsForTouchTable(params);
-  if (!(params instanceof CustomMapOptions)) {
-    params = new CustomMapOptions(params);
-  }
-  initGlobals(params);
-  // make sure that we are logged in
-  return ServerConnector.createSession().then(function () {
-    return ServerConnector.getConfiguration();
-  }).then(function () {
-    var loginDiv = createLoginDiv(params);
-    params.getElement().appendChild(loginDiv);
-    return createFooter();
-  }).then(function (footer) {
-    params.getElement().appendChild(footer);
-    return insertGoogleAnalyticsCode();
-  })
-}
-
-function createExport(params) {
-  params = modifyParamsForTouchTable(params);
-  if (!(params instanceof CustomMapOptions)) {
-    params = new CustomMapOptions(params);
-  }
-  initGlobals(params);
-  params.getElement().style.display = "table";
-  params.getElement().innerHTML = "<div style='vertical-align:middle;display:table-cell;text-align: center'>"
-    + "<img src='resources/images/icons/ajax-loader.gif'/>" + "</div>";
-
-  var result;
-  // make sure that we are logged in
-  return ServerConnector.getConfiguration().then(function (configuration) {
-    params.setConfiguration(configuration);
-    return getProject(params);
-  }).then(function (project) {
-    params.setProject(project);
-    result = new Export(params);
-    return result.init();
-  }).then(function () {
-    return result;
-  });
-}
-
-function createAdmin(params) {
-  params = modifyParamsForTouchTable(params);
-  if (!(params instanceof CustomMapOptions)) {
-    params = new CustomMapOptions(params);
-  }
-  params.setServerConnector(ServerConnector);
-  initGlobals(params);
-  params.getElement().style.display = "table";
-  params.getElement().innerHTML = "<div style='vertical-align:middle;display:table-cell;text-align: center'>"
-    + "<img src='resources/images/icons/ajax-loader.gif'/>" + "</div>";
-  if (ServerConnector.getSessionData(null).getLogin() === "anonymous") {
-    window.location.href = ServerConnector.getServerBaseUrl() + "login.xhtml?from=" + encodeURI(window.location.href);
-    return Promise.resolve()
-  }
-
-  var result;
-  // make sure that we are logged in
-  return ServerConnector.createSession().then(function () {
-    return ServerConnector.getConfiguration();
-  }).then(function (configuration) {
-    params.setConfiguration(configuration);
-    result = new Admin(params);
-    return createFooter();
-  }).then(function (footer) {
-    params.getElement().appendChild(footer);
-    return result.init();
-  }).then(function () {
-    return result;
-  });
-}
-
-var minerva = {
-  create: create,
-  createLogin: createLogin,
-  createExport: createExport,
-  createAdmin: createAdmin,
-  ServerConnector: ServerConnector,
-  GuiConnector: GuiConnector
-};
-
-module.exports = minerva;
+'use strict';
+
+var functions = require('./Functions');
+
+var AbstractDbOverlay = require('./map/overlay/AbstractDbOverlay');
+var Admin = require('./Admin');
+var DbOverlayCollection = require('./map/overlay/DbOverlayCollection');
+var ConfigurationType = require('./ConfigurationType');
+var CustomMap = require('./map/CustomMap');
+var CustomMapOptions = require('./map/CustomMapOptions');
+var Export = require('./Export');
+var GuiUtils = require('./gui/leftPanel/GuiUtils');
+var PluginManager = require('./plugin/PluginManager');
+var Point = require('./map/canvas/Point');
+var SearchDbOverlay = require('./map/overlay/SearchDbOverlay');
+
+var LeftPanel = require('./gui/leftPanel/LeftPanel');
+var TopMenu = require('./gui/topMenu/TopMenu');
+var Legend = require('./gui/Legend');
+var MapContextMenu = require('./gui/MapContextMenu');
+var SelectionContextMenu = require('./gui/SelectionContextMenu');
+
+var GuiConnector = require('./GuiConnector');
+var ServerConnector = require('./ServerConnector');
+
+var MolArt = require('./map/structure/MolArt');
+
+var Promise = require("bluebird");
+
+var logger = require('./logger');
+
+
+var customMap, leftPanel, topMenu, legend, mapContextMenu, selectionContextMenu;
+
+function processUrlGetParams(params) {
+  var project = params.getProject();
+  var sessionData = ServerConnector.getSessionData(project);
+
+  var modelId;
+  if (GuiConnector.getParams["submap"] !== undefined) {
+    modelId = parseInt(GuiConnector.getParams["submap"]);
+  } else {
+    modelId = project.getModels()[0].getId()
+  }
+
+  var model = project.getModelById(modelId);
+
+  if (GuiConnector.getParams["x"] !== undefined && GuiConnector.getParams["y"] !== undefined) {
+    var point = new Point(GuiConnector.getParams["x"], GuiConnector.getParams["y"]);
+    sessionData.setCenter(model, point);
+  }
+  if (GuiConnector.getParams["zoom"] !== undefined) {
+    sessionData.setZoomLevel(model, GuiConnector.getParams["zoom"]);
+  }
+
+  if (GuiConnector.getParams["comments"] === "on") {
+    sessionData.setShowComments(true);
+  }
+  if (GuiConnector.getParams["search"] !== undefined) {
+    var query = SearchDbOverlay.prototype.encodeQuery(AbstractDbOverlay.QueryType.SEARCH_BY_QUERY,
+      GuiConnector.getParams["search"]);
+    sessionData.setSearchQuery(query);
+  }
+
+}
+
+/**
+ *
+ * @param {User} user
+ * @param {string} termsOfUseUrl
+ */
+function requestConsent(user, termsOfUseUrl) {
+  if (termsOfUseUrl === "") {
+    return;
+  }
+  var dialog = document.createElement("div");
+  var dialogContent = document.createElement("div");
+  dialogContent.appendChild(functions.createElement({
+    type: "span",
+    content: "I agree to the minerva <a href='" + termsOfUseUrl + "' target='_blank'>Terms of Use</a>."
+  }));
+  var checkbox = functions.createElement({type: "input", inputType: "checkbox", style: "float: left"});
+  var okButton = functions.createElement({
+    type: "button",
+    content: "OK",
+    className: "ui-button ui-corner-all ui-widget",
+    onclick: function () {
+      user.setTermsOfUseConsent($(checkbox).is(':checked'));
+      return ServerConnector.updateUser(user).then(function () {
+        $(dialog).dialog("close");
+      }).catch(GuiConnector.alert);
+    }
+  });
+  var cancelButton = functions.createElement({
+    type: "button",
+    content: "I disagree",
+    className: "ui-button ui-corner-all ui-widget",
+    onclick: function () {
+      return ServerConnector.logout().catch(GuiConnector.alert);
+    }
+  });
+  $(okButton).prop("disabled", true);
+  $(checkbox).change(function () {
+    $(okButton).prop("disabled", !$(checkbox).is(':checked'));
+  });
+  dialogContent.appendChild(checkbox);
+  dialogContent.appendChild(okButton);
+  dialogContent.appendChild(cancelButton);
+
+  dialog.appendChild(dialogContent);
+  document.body.appendChild(dialog);
+  $(dialog).dialog({
+    classes: {
+      "ui-dialog": "ui-state-error"
+    },
+    modal: true,
+    closeOnEscape: false,
+    title: "Terms of Use"
+  }).siblings('.ui-dialog-titlebar').css("background", "red");
+  $(".ui-dialog-titlebar-close", $(dialog).dialog().siblings('.ui-dialog-titlebar')).hide();
+  $(dialog).dialog("open");
+}
+
+function insertGoogleAnalyticsCode() {
+  return ServerConnector.getConfigurationParam(ConfigurationType.GOOGLE_ANALYTICS_IDENTIFIER).then(function (identifier) {
+    if (identifier === "" || identifier === undefined || identifier === null) {
+      return Promise.resolve();
+    } else {
+      global._gaq = global._gaq || [];
+      global._gaq.push(['_setAccount', identifier]);
+      global._gaq.push(['_trackPageview']);
+
+      (function () {
+        var ga = document.createElement('script');
+        ga.type = 'text/javascript';
+        ga.async = true;
+        ga.src = ('https:' === document.location.protocol ? 'https://ssl' : 'http://www')
+          + '.google-analytics.com/ga.js';
+        var s = document.getElementsByTagName('script')[0];
+        s.parentNode.insertBefore(ga, s);
+      })();
+      return Promise.resolve();
+    }
+  });
+}
+
+function createDivStructure(element) {
+  var tableDiv = functions.createElement({
+    type: "div",
+    className: "minerva-root"
+  });
+  element.appendChild(tableDiv);
+  var leftPanelDiv = functions.createElement({
+    type: "div",
+    className: "minerva-left-panel"
+  });
+  tableDiv.appendChild(leftPanelDiv);
+  var middlePanelDiv = functions.createElement({
+    type: "div",
+    className: "minerva-middle-panel"
+  });
+  tableDiv.appendChild(middlePanelDiv);
+
+  //this container is required because google maps API modifies DOM and it will crash
+  var middlePanelContainerDiv = functions.createElement({type: "div"});
+  middlePanelDiv.appendChild(middlePanelContainerDiv);
+
+  var splitBar = functions.createElement({
+    type: "div",
+    className: "minerva-plugin-split-bar",
+    content: "&nbsp"
+  });
+  tableDiv.appendChild(splitBar);
+
+  var rightPanelDiv = functions.createElement({
+    type: "div",
+    className: "minerva-plugin"
+  });
+  tableDiv.appendChild(rightPanelDiv);
+
+  var menuDiv = functions.createElement({
+    type: "div",
+    className: "minerva-top-menu"
+  });
+  middlePanelContainerDiv.appendChild(menuDiv);
+
+  var mapDiv = functions.createElement({
+    type: "div",
+    className: "minerva-map"
+  });
+  middlePanelContainerDiv.appendChild(mapDiv);
+
+  var legendDiv = functions.createElement({
+    type: "div",
+    name: "legendDiv",
+    className: "minerva-legend",
+    style: "display:none"
+  });
+  middlePanelContainerDiv.appendChild(legendDiv);
+
+  var contextMenu = functions.createElement({
+    type: "ul",
+    name: "contextMenu"
+  });
+  element.appendChild(contextMenu);
+  var selectionContextMenu = functions.createElement({
+    type: "ul",
+    name: "selectionContextMenu"
+  });
+  element.appendChild(selectionContextMenu);
+}
+
+
+function initGlobals(params) {
+  if (global.ServerConnector === undefined) {
+    global.ServerConnector = ServerConnector;
+    if (params.isDebug()) {
+      logger.setLevel("debug");
+    } else {
+      logger.setLevel("info");
+    }
+    GuiConnector.init();
+    if (GuiConnector.getParams['debug'] !== undefined) {
+      logger.setLevel("debug");
+    }
+  } else {
+    logger.warn("global ServerConnector found");
+  }
+
+}
+
+function verifyBrowser() {
+
+  var browser = functions.browser;
+  if (browser.name === "IE") {
+    if (browser.version <= 8 || browser.compatibilityMode) {
+      var message = "This web page works only with Internet Explorer version 9 or greater.\n"
+        + "If you have Internet Explorer version 9 or greater and still see this message, please, turn the 'Compatibility mode off:\n"
+        + "Open Internet Explorer and press the Alt key on your keyboard.\n"
+        + "Select 'Tools' menu item. \n"
+        + "Select the 'Compatibility View' settings option. \n"
+        + "Make sure the 'Display all websites in Compatibility View' check box is unchecked and that the 'Compatibility View; list of websites is cleared.\n"
+        + "\n" + "Alternatively, please, use other browsers: Chrome, Firefox or Safari.";
+      GuiConnector.alert(message);
+    }
+  }
+}
+
+function getProject(params) {
+  if (params.getProject() !== undefined) {
+    return Promise.resolve(params.getProject());
+  } else {
+    return ServerConnector.getProject(params.getProjectId());
+  }
+}
+
+function modifyParamsForTouchTable(params) {
+  if (params.bigLogo === undefined) {
+    // noinspection UnnecessaryLocalVariableJS
+    var isTouchTable = ((navigator.appVersion.indexOf("Win") > -1) && ('ontouchstart' in document.documentElement));
+    params.bigLogo = isTouchTable;
+  }
+  return params;
+}
+
+function assignSplitBarHandler(customMap, pluginManager) {
+  var splitBar = $('.minerva-plugin-split-bar');
+  var rightPanelDiv = $('.minerva-plugin');
+  var mouseDownHandler = function (e) {
+    e.preventDefault();
+    //TODO should use global size (but element size)
+    var x = $("body").width() - e.pageX;
+    $(rightPanelDiv).css("flex", "0 0 " + x + "px");
+    customMap.getMapCanvas().triggerListeners('resize');
+    return pluginManager.callListeners("onResize");
+  };
+  $(splitBar).mousedown(function (e) {
+    e.preventDefault();
+    $(document).mousemove(mouseDownHandler);
+  });
+  $(document).mouseup(function () {
+    $(document).unbind('mousemove', mouseDownHandler);
+  });
+}
+
+function create(params) {
+  params = modifyParamsForTouchTable(params);
+  if (!(params instanceof CustomMapOptions)) {
+    params = new CustomMapOptions(params);
+  }
+  params.setServerConnector(ServerConnector);
+  initGlobals(params);
+  params.getElement().innerHTML = "<div style='position:relative; width:100%;height:100%'>"
+    + "<img src='resources/images/icons/ajax-loader.gif' style='position:absolute;top:0;bottom:0;left:0;right:0;margin:auto;'/>" + "</div>";
+
+  // make sure that we are logged in
+  return ServerConnector.createSession().then(function () {
+    return ServerConnector.getConfiguration();
+  }).then(function (configuration) {
+    params.setConfiguration(configuration);
+    return getProject(params);
+  }).then(function (project) {
+    if (project === null) {
+      var message = "Project with given id doesn't exist.";
+      message += "<p>Please go to <a href='" + ServerConnector.getServerBaseUrl() + "'>default map</a>";
+      return Promise.reject(new Error(message));
+    }
+    params.setProject(project);
+    var promise = Promise.resolve();
+    if (params.getProject().getMapCanvasType() === "GOOGLE_MAPS_API") {
+      var apiKeySuffixString = '';
+      if (params.getConfiguration().getOption(ConfigurationType.GOOGLE_MAPS_API_KEY).getValue()) {
+        apiKeySuffixString = '&key=' + params.getConfiguration().getOption(ConfigurationType.GOOGLE_MAPS_API_KEY).getValue();
+      }
+      promise = functions.loadScript("https://maps.google.com/maps/api/js?libraries=drawing" + apiKeySuffixString);
+    }
+    return promise;
+  }).then(function () {
+    var element = params.getElement();
+
+    verifyBrowser();
+
+    processUrlGetParams(params);
+
+    params.getElement().innerHTML = "";
+    createDivStructure(element);
+    params.setElement(functions.getElementByClassName(element, "minerva-map"));
+
+    customMap = new CustomMap(params);
+
+
+    new DbOverlayCollection({
+      map: customMap
+    });
+
+    leftPanel = new LeftPanel({
+      element: functions.getElementByClassName(element, "minerva-left-panel"),
+      customMap: customMap,
+      configuration: params.getConfiguration()
+    });
+
+    var pluginManager = new PluginManager({
+      element: functions.getElementByClassName(element, "minerva-plugin"),
+      map: customMap,
+      project: params.getProject(),
+      configuration: params.getConfiguration()
+    });
+    leftPanel.setPluginManager(pluginManager);
+    assignSplitBarHandler(customMap, pluginManager);
+
+    topMenu = new TopMenu({
+      element: functions.getElementByClassName(element, "minerva-top-menu"),
+      customMap: customMap
+    });
+
+    legend = new Legend({
+      element: functions.getElementByName(element, "legendDiv"),
+      customMap: customMap
+    });
+
+    mapContextMenu = new MapContextMenu({
+      element: functions.getElementByName(element, "contextMenu"),
+      customMap: customMap,
+      molArt: new MolArt(element, customMap)
+    });
+    customMap.setContextMenu(mapContextMenu);
+
+    selectionContextMenu = new SelectionContextMenu({
+      element: functions.getElementByName(element, "selectionContextMenu"),
+      customMap: customMap
+    });
+    customMap.setSelectionContextMenu(selectionContextMenu);
+
+    topMenu.setLegend(legend);
+    topMenu.setLeftPanel(leftPanel);
+
+    return customMap.init();
+  }).then(function () {
+    return insertGoogleAnalyticsCode(customMap);
+  }).then(function () {
+    return leftPanel.init();
+  }).then(function () {
+    return legend.init();
+  }).then(function () {
+    return topMenu.init();
+  }).then(function () {
+    return selectionContextMenu.init();
+  }).then(function () {
+    return mapContextMenu.init();
+  }).then(function () {
+    if (GuiConnector.getParams["layout"] !== undefined) {
+      var overlays = params.getProject().getDataOverlays();
+      for (var j = 0; j < overlays.length; j++) {
+        var overlay = overlays[j];
+        if (overlay.getName() === GuiConnector.getParams["layout"]) {
+          return customMap.openDataOverlay(overlay);
+        }
+      }
+    }
+  }).then(function () {
+
+    var submapId = GuiConnector.getParams["submap"];
+    if (submapId !== undefined) {
+      return customMap.openSubmap(submapId);
+    }
+  }).then(function () {
+    var promises = [];
+    for (var i = 0; i < params.getPlugins().length; i++) {
+      promises.push(leftPanel.getPluginManager().addPlugin(params.getPlugins()[i]))
+    }
+    return Promise.all(promises);
+  }).then(function () {
+    return ServerConnector.getLoggedUser();
+  }).then(function (user) {
+    if (leftPanel.isGoogleLicenseConsentRequired()) {
+      GuiConnector.warn("Visualization of data overlays (Overlays tab) requires consent to terms of the <a href='https://cloud.google.com/maps-platform/terms/' target='_blank'>license of Google Maps Platform</a>. Click the \"Edit\" button for the overlay to do so.");
+    }
+    if (user.getLogin() !== "anonymous" && !user.isTermsOfUseConsent()) {
+      requestConsent(user, params.getConfiguration().getOption(ConfigurationType.TERMS_OF_USE).getValue());
+    }
+    var result = {
+      destroy: function () {
+        return leftPanel.destroy().then(function () {
+          customMap.destroy();
+          return topMenu.destroy();
+        });
+      },
+      getProject: function () {
+        return customMap.getProject();
+      }
+    };
+
+    if (params.isDebug()) {
+      result.leftPanel = leftPanel;
+      result.customMap = customMap;
+    }
+    return result;
+  });
+
+}
+
+function createFooter() {
+  var logoLink, logoText, logoImg;
+  return ServerConnector.getConfigurationParam(ConfigurationType.LOGO_LINK).then(function (result) {
+    logoLink = result;
+    return ServerConnector.getConfigurationParam(ConfigurationType.LOGO_TEXT);
+  }).then(function (result) {
+    logoText = result;
+    return ServerConnector.getConfigurationParam(ConfigurationType.LOGO_IMG);
+  }).then(function (result) {
+    logoImg = result;
+    return ServerConnector.getConfiguration();
+  }).then(function (configuration) {
+    return functions.createElement({
+      type: "div",
+      className: "minerva-footer-table",
+      content: '<table width="100%" border="0" cellspacing="0" cellpadding="0">' +
+      '<tr>' +
+      '<td align="left"><a href="' + logoLink + '" title="' + logoText + '" target="_blank">' +
+      '<img src="' + GuiConnector.getImgPrefix() + logoImg + '" width="80" height="80" border="0" alt="' + logoText + '"/>' +
+      '</a></td>' +
+      '<td align="center" class="minerva-footer-text">MiNERVA version ' + configuration.getVersion() + ';<br/>' +
+      'build ' + configuration.getBuildDate() + ';<br/>' +
+      'git: ' + configuration.getGitHash() + '</td>' +
+      '<td align="right"><a href="http://wwwen.uni.lu/lcsb/" title="LCSB - Luxembourg Centre for Systems Biomedicine" target="_blank">' +
+      '<img src="' + GuiConnector.getImgPrefix() + 'lcsb.png" width="80" height="80" border="0" alt="LCSB - Luxembourg Centre for Systems Biomedicine"/>' +
+      '</a></td>' +
+      '</tr>\n' +
+      '</table>', xss: false
+    });
+  })
+}
+
+function createLoginDiv() {
+  var loggedIn = false;
+
+  var result = functions.createElement({type: "center"});
+  var resultDiv = functions.createElement({type: "div", className: "minerva-login-form", style: "text-align:left"});
+  result.appendChild(resultDiv);
+  resultDiv.appendChild(functions.createElement({
+    type: "div",
+    className: "minerva-login-form-title",
+    content: "AUTHORIZATION FORM"
+  }));
+  var guiUtils = new GuiUtils();
+  var table = functions.createElement({
+    type: "div",
+    className: "loginDataPanelGrid",
+    style: "display: table;border-spacing:5px"
+  });
+  table.appendChild(guiUtils.createTableRow([
+    functions.createElement({type: "label", className: "labelText", content: "LOGIN:"}),
+    functions.createElement({type: "input", className: "minerva-input-text", id: "username"})]
+  ));
+  table.appendChild(guiUtils.createTableRow([
+    functions.createElement({type: "label", className: "labelText", content: "PASSWORD:"}),
+    functions.createElement({
+      type: "input",
+      inputType: "password",
+      className: "minerva-input-password",
+      id: "password"
+    })]
+  ));
+
+  table.appendChild(guiUtils.createTableRow([
+    functions.createElement({type: "label", className: "labelText"}),
+    functions.createElement({type: "button", className: "labelText", id: "login", content: "LOGIN"})]
+  ));
+
+  resultDiv.appendChild(table);
+  resultDiv.appendChild(functions.createElement({type: "br"}));
+  resultDiv.appendChild(functions.createElement({type: "br"}));
+  resultDiv.appendChild(functions.createElement({
+    type: "a",
+    href: "javascript:;",
+    id: "go_to_map_button",
+    className: "adminLink",
+    content: '<i class="fa fa-chevron-right"></i> BACK TO MAP',
+    xss: false
+  }));
+  resultDiv.appendChild(functions.createElement({type: "br"}));
+  resultDiv.appendChild(functions.createElement({
+    type: "a",
+    href: "javascript:;",
+    id: "register_button",
+    className: "adminLink",
+    content: '<i class="fa fa-chevron-right"></i> REQUEST AN ACCOUNT</a>',
+    xss: false
+  }));
+
+  var fromPage = GuiConnector.getParams["from"];
+
+  $("#login", result).on("click", function login() {
+    var loginString = document.getElementById('username').value;
+    var passwordString = document.getElementById('password').value;
+    return ServerConnector.login(loginString, passwordString).then(function () {
+      loggedIn = true;
+      if (fromPage !== undefined) {
+        window.location.href = fromPage;
+      } else {
+        window.location.href = ServerConnector.getServerBaseUrl();
+      }
+    }, function (error) {
+      if (error.constructor.name === "InvalidCredentialsError") {
+        GuiConnector.alert("invalid credentials");
+      } else {
+        GuiConnector.alert(error);
+      }
+    });
+  });
+  $('#go_to_map_button', result).click(function () {
+    return ServerConnector.getProjectId().then(function (projectId) {
+      window.location.href = ServerConnector.getServerBaseUrl() + '?id=' + projectId;
+    });
+  });
+  $('#register_button', result).click(function () {
+    var email, content;
+    return ServerConnector.getConfigurationParam("REQUEST_ACCOUNT_EMAIL").then(function (result) {
+      email = result;
+      return ServerConnector.getConfigurationParam("REQUEST_ACCOUNT_DEFAULT_CONTENT");
+    }).then(function (result) {
+      content = encodeURIComponent(result);
+      document.location.href = 'mailto:' + email + '?subject=MINERVA account request&body=' + content;
+    });
+  });
+
+  return result;
+}
+
+
+function createLogin(params) {
+  params = modifyParamsForTouchTable(params);
+  if (!(params instanceof CustomMapOptions)) {
+    params = new CustomMapOptions(params);
+  }
+  initGlobals(params);
+  // make sure that we are logged in
+  return ServerConnector.createSession().then(function () {
+    return ServerConnector.getConfiguration();
+  }).then(function () {
+    var loginDiv = createLoginDiv(params);
+    params.getElement().appendChild(loginDiv);
+    return createFooter();
+  }).then(function (footer) {
+    params.getElement().appendChild(footer);
+    return insertGoogleAnalyticsCode();
+  })
+}
+
+function createExport(params) {
+  params = modifyParamsForTouchTable(params);
+  if (!(params instanceof CustomMapOptions)) {
+    params = new CustomMapOptions(params);
+  }
+  initGlobals(params);
+  params.getElement().style.display = "table";
+  params.getElement().innerHTML = "<div style='vertical-align:middle;display:table-cell;text-align: center'>"
+    + "<img src='resources/images/icons/ajax-loader.gif'/>" + "</div>";
+
+  var result;
+  // make sure that we are logged in
+  return ServerConnector.getConfiguration().then(function (configuration) {
+    params.setConfiguration(configuration);
+    return getProject(params);
+  }).then(function (project) {
+    params.setProject(project);
+    result = new Export(params);
+    return result.init();
+  }).then(function () {
+    return result;
+  });
+}
+
+function createAdmin(params) {
+  params = modifyParamsForTouchTable(params);
+  if (!(params instanceof CustomMapOptions)) {
+    params = new CustomMapOptions(params);
+  }
+  params.setServerConnector(ServerConnector);
+  initGlobals(params);
+  params.getElement().style.display = "table";
+  params.getElement().innerHTML = "<div style='vertical-align:middle;display:table-cell;text-align: center'>"
+    + "<img src='resources/images/icons/ajax-loader.gif'/>" + "</div>";
+  if (ServerConnector.getSessionData(null).getLogin() === "anonymous") {
+    window.location.href = ServerConnector.getServerBaseUrl() + "login.xhtml?from=" + encodeURI(window.location.href);
+    return Promise.resolve()
+  }
+
+  var result;
+  // make sure that we are logged in
+  return ServerConnector.createSession().then(function () {
+    return ServerConnector.getConfiguration();
+  }).then(function (configuration) {
+    params.setConfiguration(configuration);
+    result = new Admin(params);
+    return createFooter();
+  }).then(function (footer) {
+    params.getElement().appendChild(footer);
+    return result.init();
+  }).then(function () {
+    return result;
+  });
+}
+
+var minerva = {
+  create: create,
+  createLogin: createLogin,
+  createExport: createExport,
+  createAdmin: createAdmin,
+  ServerConnector: ServerConnector,
+  GuiConnector: GuiConnector
+};
+
+module.exports = minerva;
diff --git a/frontend-js/src/main/js/plugin/MinervaPluginProxy.js b/frontend-js/src/main/js/plugin/MinervaPluginProxy.js
index 3675b654a26f5b9c20f46fed88277bc5de95a6ab..4116d900b1e145cc06b4963a4202a730399c56eb 100644
--- a/frontend-js/src/main/js/plugin/MinervaPluginProxy.js
+++ b/frontend-js/src/main/js/plugin/MinervaPluginProxy.js
@@ -1,500 +1,500 @@
-"use strict";
-
-var Annotation = require('../map/data/Annotation');
-var IdentifiedElement = require('../map/data/IdentifiedElement');
-var UserDbOverlay = require('../map/overlay/UserDbOverlay');
-var Configuration = require('../Configuration');
-
-var Bounds = require('../map/canvas/Bounds');
-var Point = require('../map/canvas/Point');
-
-var logger = require('../logger');
-
-var Promise = require("bluebird");
-
-function getOverlayByName(customMap, dbOverlayName) {
-  var dbOverlay = customMap.getOverlayByName(dbOverlayName);
-  if (dbOverlay === null) {
-    var validOverlays = "";
-    var overlays = customMap.getDbOverlays();
-    for (var overlay in overlays) {
-      if (overlays.hasOwnProperty(overlay)) {
-        validOverlays += overlay.getName() + ", ";
-      }
-    }
-    throw new Error("Invalid DbOverlay: " + dbOverlayName + ". Valid DbOverlays: " + validOverlays);
-  } else {
-    return dbOverlay;
-  }
-}
-
-function getFullElements(customMap, identifiedElements) {
-  var result = [];
-  return Promise.each(
-    identifiedElements,
-    function (item) {
-      if (item.length === undefined) {
-        return customMap.getSubmapById(item.getModelId()).getModel().getByIdentifiedElement(item, true).then(
-          function (fullElement) {
-            result.push(fullElement);
-          });
-      } else {
-        return getFullElements(customMap, item).then(function (resultRow) {
-          result.push(resultRow);
-        });
-      }
-    }).then(function () {
-    return result;
-  });
-}
-
-function getElements(elementIdentifiers, customMap) {
-  var identifiedElements = [];
-
-  var elementsByModelId = [];
-  for (var i = 0; i < elementIdentifiers.length; i++) {
-    var identifiedElement = new IdentifiedElement(elementIdentifiers[i]);
-    if (elementsByModelId[identifiedElement.getModelId()] === undefined) {
-      elementsByModelId[identifiedElement.getModelId()] = [];
-    }
-    elementsByModelId[identifiedElement.getModelId()].push(identifiedElement);
-    identifiedElements.push(identifiedElement);
-  }
-
-  var modelScopePromises = [];
-  for (var key in elementsByModelId) {
-    if (elementsByModelId.hasOwnProperty(key)) {
-      var model = customMap.getProject().getModelById(parseInt(key));
-      modelScopePromises.push(model.getByIdentifiedElements(elementsByModelId[key], true));
-    }
-  }
-  // first promise fetch all data
-  return Promise.all(modelScopePromises).then(function () {
-    // this promise return result in the right order
-    var elementPromises = [];
-    for (var i = 0; i < identifiedElements.length; i++) {
-      var element = identifiedElements[i];
-      var model = customMap.getProject().getModelById(element.getModelId());
-      var promise = model.getByIdentifiedElement(element, true);
-      elementPromises.push(promise);
-    }
-    return Promise.all(elementPromises);
-  });
-}
-
-
-function createProjectData(options) {
-  var map = options.map;
-  return {
-    getBioEntityById: function (param) {
-      var isArray = true;
-      if (param.length === undefined) {
-        param = [param];
-        isArray = false;
-      }
-      return getElements(param, map).then(function (result) {
-        if (!isArray) {
-          return result[0];
-        } else {
-          return result;
-        }
-      });
-    },
-    getAllBioEntities: function () {
-      var models = map.getProject().getModels();
-      var result = [];
-      var promises = [];
-      for (var i = 0; i < models.length; i++) {
-        promises.push(models[i].getAliases({
-          type: map.getConfiguration().getSimpleElementTypeNames(),
-          complete: true
-        }));
-      }
-      return Promise.all(promises).then(function (aliasesByModel) {
-        var promises = [];
-        for (var i = 0; i < models.length; i++) {
-          promises.push(models[i].getReactionsForElements(aliasesByModel[i], true));
-          for (var j = 0; j < aliasesByModel[i].length; j++) {
-            result.push(aliasesByModel[i][j]);
-          }
-        }
-        return Promise.all(promises);
-      }).then(function (reactionsByModel) {
-        for (var i = 0; i < models.length; i++) {
-          for (var j = 0; j < reactionsByModel[i].length; j++) {
-            result.push(reactionsByModel[i][j]);
-          }
-        }
-        return result;
-      });
-    },
-    getReactionsWithElement: function (param) {
-      if (param.length === undefined) {
-        param = [param];
-      }
-      return getReactionsForElements(param, map);
-    },
-    getProjectId: function () {
-      return map.getProject().getProjectId();
-    },
-    getName: function () {
-      return map.getProject().getName();
-    },
-    getVersion: function () {
-      return map.getProject().getVersion();
-    },
-    getDisease: function () {
-      if (map.getProject().getDisease() !== undefined) {
-        return new Annotation(map.getProject().getDisease());
-      } else {
-        return null;
-      }
-    },
-    getOrganism: function () {
-      if (map.getProject().getOrganism() !== undefined) {
-        return new Annotation(map.getProject().getOrganism());
-      } else {
-        return null;
-      }
-    },
-    getModels: function () {
-      var result = [{modelId: map.getId()}];
-      for (var i = 0; i < map.getSubmaps().length; i++) {
-        var subModel = map.getSubmaps()[i].getModel();
-        result.push({
-          modelId: subModel.getId(),
-          name: subModel.getName(),
-          width: subModel.getWidth(),
-          height: subModel.getHeight()
-        });
-      }
-      return result;
-    }
-  };
-}
-
-function getReactionsForElements(elementIdentifiers, customMap) {
-  var elementsByModelId = [];
-  for (var i = 0; i < elementIdentifiers.length; i++) {
-    var identifiedElement = new IdentifiedElement(elementIdentifiers[i]);
-    if (elementsByModelId[identifiedElement.getModelId()] === undefined) {
-      elementsByModelId[identifiedElement.getModelId()] = [];
-    }
-    elementsByModelId[identifiedElement.getModelId()].push(identifiedElement);
-  }
-
-  var modelScopePromises = [];
-  for (var key in elementsByModelId) {
-    if (elementsByModelId.hasOwnProperty(key)) {
-      var model = customMap.getProject().getModelById(parseInt(key));
-      var promise = model.getReactionsForElements(elementsByModelId[key], true);
-      modelScopePromises.push(promise);
-    }
-  }
-
-  // first promise fetch all data
-  return Promise.all(modelScopePromises).then(function (reactionResult) {
-    var result = [];
-    for (var i = 0; i < reactionResult.length; i++) {
-      result = result.concat(reactionResult[i]);
-    }
-    return result;
-  });
-}
-
-
-function createMarkerElements(options) {
-  var params = options.params;
-  var filteredType = options.filteredType;
-  var isDefault = options.isDefault;
-
-  var markerElements = [];
-  if (params.length === undefined) {
-    params = [params];
-  }
-  for (var i = 0; i < params.length; i++) {
-    var elementParam = params[i];
-    if (elementParam.type === undefined && isDefault) {
-      markerElements.push({
-        element: elementParam.element
-      });
-    } else if (elementParam.type === filteredType) {
-      markerElements.push({
-        element: elementParam.element,
-        options: elementParam.options
-      });
-    } else if (elementParam.type !== "ICON" && elementParam.type !== "SURFACE") {
-      throw new Error("Unknown type:" + elementParam.type);
-    }
-  }
-  return markerElements;
-}
-
-function createProjectMap(options) {
-  var map = options.map;
-  var pluginId = options.pluginId;
-
-  map.registerDbOverlay(new UserDbOverlay({name: pluginId, map: map}));
-
-  var listenersData = [];
-
-  return {
-    getVisibleDataOverlays: function () {
-      return map.getVisibleDataOverlays();
-    },
-    addListener: function (param) {
-      var objects = [];
-      var listenerWrapper = null;
-      var listenerType = param.type;
-      if (param.dbOverlayName !== undefined) {
-        objects.push(getOverlayByName(map, param.dbOverlayName));
-        listenerWrapper = function (e) {
-          return getFullElements(map, e.arg.identifiedElements).then(function (result) {
-            return param.callback(result);
-          });
-        };
-      } else if (param.object === "plugin") {
-        objects.push(options.plugin);
-        listenerWrapper = function () {
-          return param.callback();
-        };
-      } else if (param.object === "overlay") {
-        objects.push(map);
-        if (param.type === "onShow") {
-          listenerType = "onShowOverlay";
-        } else if (param.type === "onHide") {
-          listenerType = "onHideOverlay";
-        } else {
-          throw new Error("Unknown listener type: " + param.type);
-        }
-        listenerWrapper = function (e) {
-          return param.callback(e.arg);
-        };
-      } else if (param.object === "map") {
-        objects.push(map);
-        if (param.type === "onZoomChanged") {
-          listenerWrapper = function (e) {
-            return param.callback({modelId: e.object.getId(), zoom: e.arg});
-          };
-        } else if (param.type === "onCenterChanged") {
-          listenerWrapper = function (e) {
-            return param.callback({modelId: e.object.getId(), center: e.arg});
-          };
-        } else {
-          throw new Error("Unknown listener type: " + param.type);
-        }
-        objects = objects.concat(map.getSubmaps());
-      } else {
-        throw new Error("Invalid argument");
-      }
-
-      for (var i = 0; i < objects.length; i++) {
-        var object = objects[i];
-        object.addListener(listenerType, listenerWrapper);
-        listenersData.push({listener: param.callback, wrapper: listenerWrapper, object: object, type: listenerType});
-      }
-    },
-    removeListener: function (param) {
-      var dbOverlay = getOverlayByName(map, param.dbOverlayName);
-      var indexToBeRemoved = -1;
-
-      for (var i = 0; i < listenersData.length; i++) {
-        var listenerData = listenersData[i];
-        if (listenerData.listener === param.callback &&
-          listenerData.object === dbOverlay &&
-          listenerData.type === param.type) {
-          indexToBeRemoved = i;
-        }
-      }
-      if (indexToBeRemoved === -1) {
-        throw new Error("Listener doesn't exist");
-      }
-      var listenerWrapper = listenersData[indexToBeRemoved].wrapper;
-
-      dbOverlay.removeListener(param.type, listenerWrapper);
-
-      listenersData.splice(indexToBeRemoved, 1);
-    },
-    removeAllListeners: function () {
-      var removedListeners = [];
-      for (var i = 0; i < listenersData.length; i++) {
-        var listenerData = listenersData[i];
-        var listenerWrapper = listenersData[i].wrapper;
-        listenerData.object.removeListener(listenerData.type, listenerWrapper);
-        removedListeners.push(listenerData.listener);
-      }
-      return removedListeners;
-    },
-    getHighlightedBioEntities: function (dbOverlayName) {
-      if (dbOverlayName === undefined) {
-        dbOverlayName = pluginId;
-      }
-      var dbOverlay = getOverlayByName(map, dbOverlayName);
-      var identifiedElements;
-      return dbOverlay.getIdentifiedElements().then(function (result) {
-        identifiedElements = result;
-        return getFullElements(map, identifiedElements);
-      }).then(function (fullElements) {
-        var result = [];
-        for (var i = 0; i < identifiedElements.length; i++) {
-          var type;
-          if (identifiedElements[i].getIcon() !== undefined) {
-            type = "ICON";
-          } else {
-            type = "SURFACE";
-          }
-          var row = {
-            element: fullElements[i],
-            type: type,
-            options: {
-              icon: identifiedElements[i].getIcon(),
-              color: identifiedElements[i].getColor(),
-              opacity: identifiedElements[i].getOpacity()
-            }
-          };
-          result.push(row);
-        }
-        return result;
-      });
-    },
-    showBioEntity: function (params) {
-      var iconElements = createMarkerElements({
-        params: params,
-        filteredType: "ICON",
-        isDefault: true
-      });
-      var surfaceElements = createMarkerElements({
-        params: params,
-        filteredType: "SURFACE",
-        isDefault: false
-      });
-      var promise = Promise.resolve();
-      if (iconElements.length > 0) {
-        promise = map.getOverlayByName(pluginId).addMarker(iconElements);
-      }
-      return promise.then(function () {
-        if (surfaceElements.length > 0) {
-          return map.getOverlayByName(pluginId).addSurface(surfaceElements);
-        } else {
-          return Promise.resolve();
-        }
-      });
-    },
-    hideBioEntity: function (params) {
-      var iconElements = createMarkerElements({
-        params: params,
-        filteredType: "ICON",
-        isDefault: true
-      });
-      var surfaceElements = createMarkerElements({
-        params: params,
-        filteredType: "SURFACE",
-        isDefault: false
-      });
-      return map.getOverlayByName(pluginId).removeMarker(iconElements).then(function () {
-        return map.getOverlayByName(pluginId).removeSurface(surfaceElements);
-      });
-    },
-    setCenter: function (params) {
-      var submap = map.getSubmapById(params.modelId);
-      if (submap === null) {
-        throw new Error("Unknown modelId: " + params.modelId);
-      }
-      return submap.setCenter(new Point(params.x, params.y));
-    },
-    getCenter: function (params) {
-      var submap = map.getSubmapById(params.modelId);
-      if (submap === null) {
-        throw new Error("Unknown modelId: " + params.modelId);
-      }
-      return submap.getCenter();
-    },
-    getBounds: function (params) {
-      var submap = map.getSubmapById(params.modelId);
-      if (submap === null) {
-        throw new Error("Unknown modelId: " + params.modelId);
-      }
-      return submap.getBounds();
-    },
-    fitBounds: function (params) {
-      var submap = map.getSubmapById(params.modelId);
-      if (submap === null) {
-        throw new Error("Unknown modelId: " + params.modelId);
-      }
-      var p1 = new Point(params.x1, params.y1);
-      var p2 = new Point(params.x2, params.y2);
-      return submap.getMapCanvas().fitBounds(new Bounds(p1, p2));
-    },
-    setZoom: function (params) {
-      var submap = map.getSubmapById(params.modelId);
-      if (submap === null) {
-        throw new Error("Unknown modelId: " + params.modelId);
-      }
-      return submap.setZoom(params.zoom);
-    },
-    getZoom: function (params) {
-      var submap = map.getSubmapById(params.modelId);
-      if (submap === null) {
-        throw new Error("Unknown modelId: " + params.modelId);
-      }
-      return submap.getZoom();
-    },
-    openMap: function (params) {
-      return map.openSubmap(params.id);
-    }
-  }
-}
-
-function createProject(options) {
-  return {
-    data: createProjectData(options),
-    map: createProjectMap(options)
-  };
-}
-
-function createConfiguration(options) {
-  var configuration = new Configuration(options.configuration);
-  return {
-    options: configuration.getOptions(),
-    overlayTypes: configuration.getOverlayTypes(),
-    imageConverters: configuration.getImageConverters(),
-    modelConverters: configuration.getModelConverters(),
-    elementTypes: configuration.getElementTypes(),
-    reactionTypes: configuration.getReactionTypes(),
-    miriamTypes: configuration.getMiriamTypes(),
-    mapTypes: configuration.getMapTypes(),
-    modificationStateTypes: configuration.getModificationStateTypes(),
-    privilegeTypes: configuration.getPrivilegeTypes(),
-    annotators: configuration.getAnnotators()
-  };
-}
-
-function createPluginData(options) {
-  return {
-    setGlobalParam: function (key, value) {
-      return ServerConnector.setPluginGlobalParam({hash: options.hash, key: key, value: value});
-    },
-    getGlobalParam: function (key) {
-      return ServerConnector.getPluginGlobalParam({hash: options.hash, key: key});
-    },
-    setUserParam: function (key, value) {
-      return ServerConnector.setPluginUserParam({hash: options.hash, key: key, value: value});
-    },
-    getUserParam: function (key) {
-      return ServerConnector.getPluginUserParam({hash: options.hash, key: key});
-    }
-  };
-}
-
-
-function MinervaPluginProxy(options) {
-  return {
-    pluginId: options.pluginId,
-    element: options.element,
-    project: createProject(options),
-    configuration: createConfiguration(options),
-    pluginData: createPluginData(options)
-  };
-}
-
-module.exports = MinervaPluginProxy;
+"use strict";
+
+var Annotation = require('../map/data/Annotation');
+var IdentifiedElement = require('../map/data/IdentifiedElement');
+var UserDbOverlay = require('../map/overlay/UserDbOverlay');
+var Configuration = require('../Configuration');
+
+var Bounds = require('../map/canvas/Bounds');
+var Point = require('../map/canvas/Point');
+
+var logger = require('../logger');
+
+var Promise = require("bluebird");
+
+function getOverlayByName(customMap, dbOverlayName) {
+  var dbOverlay = customMap.getOverlayByName(dbOverlayName);
+  if (dbOverlay === null) {
+    var validOverlays = "";
+    var overlays = customMap.getDbOverlays();
+    for (var overlay in overlays) {
+      if (overlays.hasOwnProperty(overlay)) {
+        validOverlays += overlay.getName() + ", ";
+      }
+    }
+    throw new Error("Invalid DbOverlay: " + dbOverlayName + ". Valid DbOverlays: " + validOverlays);
+  } else {
+    return dbOverlay;
+  }
+}
+
+function getFullElements(customMap, identifiedElements) {
+  var result = [];
+  return Promise.each(
+    identifiedElements,
+    function (item) {
+      if (item.length === undefined) {
+        return customMap.getSubmapById(item.getModelId()).getModel().getByIdentifiedElement(item, true).then(
+          function (fullElement) {
+            result.push(fullElement);
+          });
+      } else {
+        return getFullElements(customMap, item).then(function (resultRow) {
+          result.push(resultRow);
+        });
+      }
+    }).then(function () {
+    return result;
+  });
+}
+
+function getElements(elementIdentifiers, customMap) {
+  var identifiedElements = [];
+
+  var elementsByModelId = [];
+  for (var i = 0; i < elementIdentifiers.length; i++) {
+    var identifiedElement = new IdentifiedElement(elementIdentifiers[i]);
+    if (elementsByModelId[identifiedElement.getModelId()] === undefined) {
+      elementsByModelId[identifiedElement.getModelId()] = [];
+    }
+    elementsByModelId[identifiedElement.getModelId()].push(identifiedElement);
+    identifiedElements.push(identifiedElement);
+  }
+
+  var modelScopePromises = [];
+  for (var key in elementsByModelId) {
+    if (elementsByModelId.hasOwnProperty(key)) {
+      var model = customMap.getProject().getModelById(parseInt(key));
+      modelScopePromises.push(model.getByIdentifiedElements(elementsByModelId[key], true));
+    }
+  }
+  // first promise fetch all data
+  return Promise.all(modelScopePromises).then(function () {
+    // this promise return result in the right order
+    var elementPromises = [];
+    for (var i = 0; i < identifiedElements.length; i++) {
+      var element = identifiedElements[i];
+      var model = customMap.getProject().getModelById(element.getModelId());
+      var promise = model.getByIdentifiedElement(element, true);
+      elementPromises.push(promise);
+    }
+    return Promise.all(elementPromises);
+  });
+}
+
+
+function createProjectData(options) {
+  var map = options.map;
+  return {
+    getBioEntityById: function (param) {
+      var isArray = true;
+      if (param.length === undefined) {
+        param = [param];
+        isArray = false;
+      }
+      return getElements(param, map).then(function (result) {
+        if (!isArray) {
+          return result[0];
+        } else {
+          return result;
+        }
+      });
+    },
+    getAllBioEntities: function () {
+      var models = map.getProject().getModels();
+      var result = [];
+      var promises = [];
+      for (var i = 0; i < models.length; i++) {
+        promises.push(models[i].getAliases({
+          type: map.getConfiguration().getSimpleElementTypeNames(),
+          complete: true
+        }));
+      }
+      return Promise.all(promises).then(function (aliasesByModel) {
+        var promises = [];
+        for (var i = 0; i < models.length; i++) {
+          promises.push(models[i].getReactionsForElements(aliasesByModel[i], true));
+          for (var j = 0; j < aliasesByModel[i].length; j++) {
+            result.push(aliasesByModel[i][j]);
+          }
+        }
+        return Promise.all(promises);
+      }).then(function (reactionsByModel) {
+        for (var i = 0; i < models.length; i++) {
+          for (var j = 0; j < reactionsByModel[i].length; j++) {
+            result.push(reactionsByModel[i][j]);
+          }
+        }
+        return result;
+      });
+    },
+    getReactionsWithElement: function (param) {
+      if (param.length === undefined) {
+        param = [param];
+      }
+      return getReactionsForElements(param, map);
+    },
+    getProjectId: function () {
+      return map.getProject().getProjectId();
+    },
+    getName: function () {
+      return map.getProject().getName();
+    },
+    getVersion: function () {
+      return map.getProject().getVersion();
+    },
+    getDisease: function () {
+      if (map.getProject().getDisease() !== undefined) {
+        return new Annotation(map.getProject().getDisease());
+      } else {
+        return null;
+      }
+    },
+    getOrganism: function () {
+      if (map.getProject().getOrganism() !== undefined) {
+        return new Annotation(map.getProject().getOrganism());
+      } else {
+        return null;
+      }
+    },
+    getModels: function () {
+      var result = [{modelId: map.getId()}];
+      for (var i = 0; i < map.getSubmaps().length; i++) {
+        var subModel = map.getSubmaps()[i].getModel();
+        result.push({
+          modelId: subModel.getId(),
+          name: subModel.getName(),
+          width: subModel.getWidth(),
+          height: subModel.getHeight()
+        });
+      }
+      return result;
+    }
+  };
+}
+
+function getReactionsForElements(elementIdentifiers, customMap) {
+  var elementsByModelId = [];
+  for (var i = 0; i < elementIdentifiers.length; i++) {
+    var identifiedElement = new IdentifiedElement(elementIdentifiers[i]);
+    if (elementsByModelId[identifiedElement.getModelId()] === undefined) {
+      elementsByModelId[identifiedElement.getModelId()] = [];
+    }
+    elementsByModelId[identifiedElement.getModelId()].push(identifiedElement);
+  }
+
+  var modelScopePromises = [];
+  for (var key in elementsByModelId) {
+    if (elementsByModelId.hasOwnProperty(key)) {
+      var model = customMap.getProject().getModelById(parseInt(key));
+      var promise = model.getReactionsForElements(elementsByModelId[key], true);
+      modelScopePromises.push(promise);
+    }
+  }
+
+  // first promise fetch all data
+  return Promise.all(modelScopePromises).then(function (reactionResult) {
+    var result = [];
+    for (var i = 0; i < reactionResult.length; i++) {
+      result = result.concat(reactionResult[i]);
+    }
+    return result;
+  });
+}
+
+
+function createMarkerElements(options) {
+  var params = options.params;
+  var filteredType = options.filteredType;
+  var isDefault = options.isDefault;
+
+  var markerElements = [];
+  if (params.length === undefined) {
+    params = [params];
+  }
+  for (var i = 0; i < params.length; i++) {
+    var elementParam = params[i];
+    if (elementParam.type === undefined && isDefault) {
+      markerElements.push({
+        element: elementParam.element
+      });
+    } else if (elementParam.type === filteredType) {
+      markerElements.push({
+        element: elementParam.element,
+        options: elementParam.options
+      });
+    } else if (elementParam.type !== "ICON" && elementParam.type !== "SURFACE") {
+      throw new Error("Unknown type:" + elementParam.type);
+    }
+  }
+  return markerElements;
+}
+
+function createProjectMap(options) {
+  var map = options.map;
+  var pluginId = options.pluginId;
+
+  map.registerDbOverlay(new UserDbOverlay({name: pluginId, map: map}));
+
+  var listenersData = [];
+
+  return {
+    getVisibleDataOverlays: function () {
+      return map.getVisibleDataOverlays();
+    },
+    addListener: function (param) {
+      var objects = [];
+      var listenerWrapper = null;
+      var listenerType = param.type;
+      if (param.dbOverlayName !== undefined) {
+        objects.push(getOverlayByName(map, param.dbOverlayName));
+        listenerWrapper = function (e) {
+          return getFullElements(map, e.arg.identifiedElements).then(function (result) {
+            return param.callback(result);
+          });
+        };
+      } else if (param.object === "plugin") {
+        objects.push(options.plugin);
+        listenerWrapper = function () {
+          return param.callback();
+        };
+      } else if (param.object === "overlay") {
+        objects.push(map);
+        if (param.type === "onShow") {
+          listenerType = "onShowOverlay";
+        } else if (param.type === "onHide") {
+          listenerType = "onHideOverlay";
+        } else {
+          throw new Error("Unknown listener type: " + param.type);
+        }
+        listenerWrapper = function (e) {
+          return param.callback(e.arg);
+        };
+      } else if (param.object === "map") {
+        objects.push(map);
+        if (param.type === "onZoomChanged") {
+          listenerWrapper = function (e) {
+            return param.callback({modelId: e.object.getId(), zoom: e.arg});
+          };
+        } else if (param.type === "onCenterChanged") {
+          listenerWrapper = function (e) {
+            return param.callback({modelId: e.object.getId(), center: e.arg});
+          };
+        } else {
+          throw new Error("Unknown listener type: " + param.type);
+        }
+        objects = objects.concat(map.getSubmaps());
+      } else {
+        throw new Error("Invalid argument");
+      }
+
+      for (var i = 0; i < objects.length; i++) {
+        var object = objects[i];
+        object.addListener(listenerType, listenerWrapper);
+        listenersData.push({listener: param.callback, wrapper: listenerWrapper, object: object, type: listenerType});
+      }
+    },
+    removeListener: function (param) {
+      var dbOverlay = getOverlayByName(map, param.dbOverlayName);
+      var indexToBeRemoved = -1;
+
+      for (var i = 0; i < listenersData.length; i++) {
+        var listenerData = listenersData[i];
+        if (listenerData.listener === param.callback &&
+          listenerData.object === dbOverlay &&
+          listenerData.type === param.type) {
+          indexToBeRemoved = i;
+        }
+      }
+      if (indexToBeRemoved === -1) {
+        throw new Error("Listener doesn't exist");
+      }
+      var listenerWrapper = listenersData[indexToBeRemoved].wrapper;
+
+      dbOverlay.removeListener(param.type, listenerWrapper);
+
+      listenersData.splice(indexToBeRemoved, 1);
+    },
+    removeAllListeners: function () {
+      var removedListeners = [];
+      for (var i = 0; i < listenersData.length; i++) {
+        var listenerData = listenersData[i];
+        var listenerWrapper = listenersData[i].wrapper;
+        listenerData.object.removeListener(listenerData.type, listenerWrapper);
+        removedListeners.push(listenerData.listener);
+      }
+      return removedListeners;
+    },
+    getHighlightedBioEntities: function (dbOverlayName) {
+      if (dbOverlayName === undefined) {
+        dbOverlayName = pluginId;
+      }
+      var dbOverlay = getOverlayByName(map, dbOverlayName);
+      var identifiedElements;
+      return dbOverlay.getIdentifiedElements().then(function (result) {
+        identifiedElements = result;
+        return getFullElements(map, identifiedElements);
+      }).then(function (fullElements) {
+        var result = [];
+        for (var i = 0; i < identifiedElements.length; i++) {
+          var type;
+          if (identifiedElements[i].getIcon() !== undefined) {
+            type = "ICON";
+          } else {
+            type = "SURFACE";
+          }
+          var row = {
+            element: fullElements[i],
+            type: type,
+            options: {
+              icon: identifiedElements[i].getIcon(),
+              color: identifiedElements[i].getColor(),
+              opacity: identifiedElements[i].getOpacity()
+            }
+          };
+          result.push(row);
+        }
+        return result;
+      });
+    },
+    showBioEntity: function (params) {
+      var iconElements = createMarkerElements({
+        params: params,
+        filteredType: "ICON",
+        isDefault: true
+      });
+      var surfaceElements = createMarkerElements({
+        params: params,
+        filteredType: "SURFACE",
+        isDefault: false
+      });
+      var promise = Promise.resolve();
+      if (iconElements.length > 0) {
+        promise = map.getOverlayByName(pluginId).addMarker(iconElements);
+      }
+      return promise.then(function () {
+        if (surfaceElements.length > 0) {
+          return map.getOverlayByName(pluginId).addSurface(surfaceElements);
+        } else {
+          return Promise.resolve();
+        }
+      });
+    },
+    hideBioEntity: function (params) {
+      var iconElements = createMarkerElements({
+        params: params,
+        filteredType: "ICON",
+        isDefault: true
+      });
+      var surfaceElements = createMarkerElements({
+        params: params,
+        filteredType: "SURFACE",
+        isDefault: false
+      });
+      return map.getOverlayByName(pluginId).removeMarker(iconElements).then(function () {
+        return map.getOverlayByName(pluginId).removeSurface(surfaceElements);
+      });
+    },
+    setCenter: function (params) {
+      var submap = map.getSubmapById(params.modelId);
+      if (submap === null) {
+        throw new Error("Unknown modelId: " + params.modelId);
+      }
+      return submap.setCenter(new Point(params.x, params.y));
+    },
+    getCenter: function (params) {
+      var submap = map.getSubmapById(params.modelId);
+      if (submap === null) {
+        throw new Error("Unknown modelId: " + params.modelId);
+      }
+      return submap.getCenter();
+    },
+    getBounds: function (params) {
+      var submap = map.getSubmapById(params.modelId);
+      if (submap === null) {
+        throw new Error("Unknown modelId: " + params.modelId);
+      }
+      return submap.getBounds();
+    },
+    fitBounds: function (params) {
+      var submap = map.getSubmapById(params.modelId);
+      if (submap === null) {
+        throw new Error("Unknown modelId: " + params.modelId);
+      }
+      var p1 = new Point(params.x1, params.y1);
+      var p2 = new Point(params.x2, params.y2);
+      return submap.getMapCanvas().fitBounds(new Bounds(p1, p2));
+    },
+    setZoom: function (params) {
+      var submap = map.getSubmapById(params.modelId);
+      if (submap === null) {
+        throw new Error("Unknown modelId: " + params.modelId);
+      }
+      return submap.setZoom(params.zoom);
+    },
+    getZoom: function (params) {
+      var submap = map.getSubmapById(params.modelId);
+      if (submap === null) {
+        throw new Error("Unknown modelId: " + params.modelId);
+      }
+      return submap.getZoom();
+    },
+    openMap: function (params) {
+      return map.openSubmap(params.id);
+    }
+  }
+}
+
+function createProject(options) {
+  return {
+    data: createProjectData(options),
+    map: createProjectMap(options)
+  };
+}
+
+function createConfiguration(options) {
+  var configuration = new Configuration(options.configuration);
+  return {
+    options: configuration.getOptions(),
+    overlayTypes: configuration.getOverlayTypes(),
+    imageConverters: configuration.getImageConverters(),
+    modelConverters: configuration.getModelConverters(),
+    elementTypes: configuration.getElementTypes(),
+    reactionTypes: configuration.getReactionTypes(),
+    miriamTypes: configuration.getMiriamTypes(),
+    mapTypes: configuration.getMapTypes(),
+    modificationStateTypes: configuration.getModificationStateTypes(),
+    privilegeTypes: configuration.getPrivilegeTypes(),
+    annotators: configuration.getAnnotators()
+  };
+}
+
+function createPluginData(options) {
+  return {
+    setGlobalParam: function (key, value) {
+      return ServerConnector.setPluginGlobalParam({hash: options.hash, key: key, value: value});
+    },
+    getGlobalParam: function (key) {
+      return ServerConnector.getPluginGlobalParam({hash: options.hash, key: key});
+    },
+    setUserParam: function (key, value) {
+      return ServerConnector.setPluginUserParam({hash: options.hash, key: key, value: value});
+    },
+    getUserParam: function (key) {
+      return ServerConnector.getPluginUserParam({hash: options.hash, key: key});
+    }
+  };
+}
+
+
+function MinervaPluginProxy(options) {
+  return {
+    pluginId: options.pluginId,
+    element: options.element,
+    project: createProject(options),
+    configuration: createConfiguration(options),
+    pluginData: createPluginData(options)
+  };
+}
+
+module.exports = MinervaPluginProxy;
diff --git a/frontend-js/src/main/js/plugin/Plugin.js b/frontend-js/src/main/js/plugin/Plugin.js
index 9ae61f686353d96d29afe0324ba92b0f6b9828a1..60b5df465ec4277cf9a1f439f5d44a7c7217a207 100644
--- a/frontend-js/src/main/js/plugin/Plugin.js
+++ b/frontend-js/src/main/js/plugin/Plugin.js
@@ -1,161 +1,161 @@
-"use strict";
-
-var MinervaPluginProxy = require('./MinervaPluginProxy');
-var ObjectWithListeners = require('../ObjectWithListeners');
-
-var Promise = require("bluebird");
-
-var logger = require('../logger');
-var Functions = require('../Functions');
-
-var pluginId = 0;
-
-function Plugin(options) {
-  ObjectWithListeners.call(this);
-  var self = this;
-  self.setOptions(options);
-  self.registerListenerType("onUnload");
-  self.registerListenerType("onResize");
-}
-
-Plugin.prototype = Object.create(ObjectWithListeners.prototype);
-Plugin.prototype.constructor = ObjectWithListeners;
-
-Plugin.prototype.setOptions = function (options) {
-  this._options = options;
-};
-
-Plugin.prototype.getOptions = function () {
-  return this._options;
-};
-
-Plugin.prototype.setLoadedPluginData = function (loadedPluginData) {
-  this._loadedPluginData = loadedPluginData;
-};
-Plugin.prototype.getLoadedPluginData = function () {
-  return this._loadedPluginData;
-};
-
-Plugin.prototype.setMinervaPluginProxy = function (minervaPluginProxy) {
-  this._minervaPluginProxy = minervaPluginProxy;
-};
-Plugin.prototype.getMinervaPluginProxy = function () {
-  return this._minervaPluginProxy;
-};
-Plugin.prototype.getPluginId = function () {
-  return this.getMinervaPluginProxy().pluginId;
-};
-
-Plugin.prototype.load = function () {
-  var self = this;
-  var options = self.getOptions();
-
-  var hash;
-  var error = false;
-  var registerPromise = null;
-
-  return ServerConnector.sendRequest({
-    url: options.url,
-    description: "Loading plugin: " + options.url,
-    method: "GET"
-  }).then(function (content) {
-    hash = Functions.computeMD5(content);
-    var pluginData = undefined;
-    try {
-      // noinspection JSUnusedLocalSymbols
-      var minervaDefine = function (pluginFunction) {
-        try {
-          if (typeof pluginFunction === "function") {
-            pluginData = pluginFunction();
-          } else {
-            pluginData = pluginFunction;
-          }
-
-          var minervaPluginProxy = new MinervaPluginProxy({
-            hash: hash,
-            map: options.map,
-            configuration: options.configuration,
-            element: options.element,
-            plugin: self,
-            pluginId: "plugin" + (pluginId++)
-          });
-          self.setLoadedPluginData(pluginData);
-          self.setMinervaPluginProxy(minervaPluginProxy);
-          registerPromise = new Promise(function (resolve) {
-            resolve(pluginData.register(minervaPluginProxy));
-          });
-        } catch (e) {
-          error = e;
-        }
-      };
-      content += "//# sourceURL=" + options.url;
-      eval(content);
-    } catch (e) {
-      error = e;
-    }
-    return ServerConnector.registerPlugin({
-      hash: hash,
-      url: options.url,
-      name: self.getName(),
-      version: self.getVersion()
-    });
-  }).then(function () {
-    if (error) {
-      return Promise.reject(error);
-    }
-    return registerPromise;
-  });
-
-};
-
-Plugin.prototype.getMinWidth = function () {
-  var value;
-  var data = this.getLoadedPluginData();
-  if (data.minWidth !== undefined) {
-    if (typeof data.minWidth === "function") {
-      value = parseInt(data.minWidth());
-    } else {
-      value = parseInt(data.minWidth);
-    }
-  }
-  return value;
-};
-
-Plugin.prototype.unload = function () {
-  var self = this;
-  return Promise.resolve().then(function () {
-    return self.getLoadedPluginData().unregister();
-  }).then(function () {
-    var removedListeners = self.getMinervaPluginProxy().project.map.removeAllListeners();
-    if (removedListeners.length > 0) {
-      logger.warn("'" + self.getLoadedPluginData().getName() + "' plugin didn't remove all registered listeners");
-    }
-    return self.callListeners("onUnload");
-  }).then(function () {
-    return self.destroy();
-  });
-};
-
-Plugin.prototype.getName = function () {
-  if (this.getLoadedPluginData() === undefined) {
-    return "";
-  }
-  return this.getLoadedPluginData().getName();
-};
-
-Plugin.prototype.getVersion = function () {
-  if (this.getLoadedPluginData() === undefined) {
-    return "";
-  }
-  return this.getLoadedPluginData().getVersion();
-};
-
-Plugin.prototype.destroy = function () {
-  return Promise.resolve();
-};
-
-Plugin.prototype.setHash = function (hash) {
-  this.getMinervaPluginProxy().hash = hash;
-};
-
-module.exports = Plugin;
+"use strict";
+
+var MinervaPluginProxy = require('./MinervaPluginProxy');
+var ObjectWithListeners = require('../ObjectWithListeners');
+
+var Promise = require("bluebird");
+
+var logger = require('../logger');
+var Functions = require('../Functions');
+
+var pluginId = 0;
+
+function Plugin(options) {
+  ObjectWithListeners.call(this);
+  var self = this;
+  self.setOptions(options);
+  self.registerListenerType("onUnload");
+  self.registerListenerType("onResize");
+}
+
+Plugin.prototype = Object.create(ObjectWithListeners.prototype);
+Plugin.prototype.constructor = ObjectWithListeners;
+
+Plugin.prototype.setOptions = function (options) {
+  this._options = options;
+};
+
+Plugin.prototype.getOptions = function () {
+  return this._options;
+};
+
+Plugin.prototype.setLoadedPluginData = function (loadedPluginData) {
+  this._loadedPluginData = loadedPluginData;
+};
+Plugin.prototype.getLoadedPluginData = function () {
+  return this._loadedPluginData;
+};
+
+Plugin.prototype.setMinervaPluginProxy = function (minervaPluginProxy) {
+  this._minervaPluginProxy = minervaPluginProxy;
+};
+Plugin.prototype.getMinervaPluginProxy = function () {
+  return this._minervaPluginProxy;
+};
+Plugin.prototype.getPluginId = function () {
+  return this.getMinervaPluginProxy().pluginId;
+};
+
+Plugin.prototype.load = function () {
+  var self = this;
+  var options = self.getOptions();
+
+  var hash;
+  var error = false;
+  var registerPromise = null;
+
+  return ServerConnector.sendRequest({
+    url: options.url,
+    description: "Loading plugin: " + options.url,
+    method: "GET"
+  }).then(function (content) {
+    hash = Functions.computeMD5(content);
+    var pluginData = undefined;
+    try {
+      // noinspection JSUnusedLocalSymbols
+      var minervaDefine = function (pluginFunction) {
+        try {
+          if (typeof pluginFunction === "function") {
+            pluginData = pluginFunction();
+          } else {
+            pluginData = pluginFunction;
+          }
+
+          var minervaPluginProxy = new MinervaPluginProxy({
+            hash: hash,
+            map: options.map,
+            configuration: options.configuration,
+            element: options.element,
+            plugin: self,
+            pluginId: "plugin" + (pluginId++)
+          });
+          self.setLoadedPluginData(pluginData);
+          self.setMinervaPluginProxy(minervaPluginProxy);
+          registerPromise = new Promise(function (resolve) {
+            resolve(pluginData.register(minervaPluginProxy));
+          });
+        } catch (e) {
+          error = e;
+        }
+      };
+      content += "//# sourceURL=" + options.url;
+      eval(content);
+    } catch (e) {
+      error = e;
+    }
+    return ServerConnector.registerPlugin({
+      hash: hash,
+      url: options.url,
+      name: self.getName(),
+      version: self.getVersion()
+    });
+  }).then(function () {
+    if (error) {
+      return Promise.reject(error);
+    }
+    return registerPromise;
+  });
+
+};
+
+Plugin.prototype.getMinWidth = function () {
+  var value;
+  var data = this.getLoadedPluginData();
+  if (data.minWidth !== undefined) {
+    if (typeof data.minWidth === "function") {
+      value = parseInt(data.minWidth());
+    } else {
+      value = parseInt(data.minWidth);
+    }
+  }
+  return value;
+};
+
+Plugin.prototype.unload = function () {
+  var self = this;
+  return Promise.resolve().then(function () {
+    return self.getLoadedPluginData().unregister();
+  }).then(function () {
+    var removedListeners = self.getMinervaPluginProxy().project.map.removeAllListeners();
+    if (removedListeners.length > 0) {
+      logger.warn("'" + self.getLoadedPluginData().getName() + "' plugin didn't remove all registered listeners");
+    }
+    return self.callListeners("onUnload");
+  }).then(function () {
+    return self.destroy();
+  });
+};
+
+Plugin.prototype.getName = function () {
+  if (this.getLoadedPluginData() === undefined) {
+    return "";
+  }
+  return this.getLoadedPluginData().getName();
+};
+
+Plugin.prototype.getVersion = function () {
+  if (this.getLoadedPluginData() === undefined) {
+    return "";
+  }
+  return this.getLoadedPluginData().getVersion();
+};
+
+Plugin.prototype.destroy = function () {
+  return Promise.resolve();
+};
+
+Plugin.prototype.setHash = function (hash) {
+  this.getMinervaPluginProxy().hash = hash;
+};
+
+module.exports = Plugin;