diff --git a/frontend-js/src/main/js/gui/AbstractDbPanel.js b/frontend-js/src/main/js/gui/AbstractDbPanel.js
new file mode 100644
index 0000000000000000000000000000000000000000..87a957301fef08173ada87cc037606ea0617dd8f
--- /dev/null
+++ b/frontend-js/src/main/js/gui/AbstractDbPanel.js
@@ -0,0 +1,268 @@
+"use strict";
+
+/* exported logger */
+
+var Promise = require("bluebird");
+
+var Panel = require('./Panel');
+
+var logger = require('../logger');
+
+
+function AbstractPanel(params) {
+  Panel.call(this, params);
+
+  var self = this;
+
+  if (this.getNavElement() === undefined) {
+    throw new Error("No nav-tabs div found in the search panel element");
+  }
+  if (this.getContentElement() === undefined) {
+    throw new Error("No tab-content div found in the search panel element");
+  }
+  if (this.getSearchButton() === undefined) {
+    throw new Error("No searchButton found in the search panel element");
+  }
+  if (this.getSearchInput() === undefined) {
+    throw new Error("No searchInput found in the search panel element");
+  }
+
+  this.setOverlayDb (self.getMap().getOverlayByName(params.panelName));
+
+  var searchByQuery = function(){
+    return self.searchByQuery();
+  };
+  
+  self.getSearchButton().onclick = searchByQuery;
+  self.getSearchInput().onkeypress = function(event){
+    if (event.keyCode === 13) {
+      searchByQuery();  
+    }
+  };
+  
+  
+  $(self.getSearchInput()).typeahead({
+    minLength: 1,
+  },{
+    source: function(query, callback){
+      callback(self.getAutocomplete(query));
+    }
+  });
+
+  $(self.getSearchInput()).on('typeahead:select', function() {
+    searchByQuery();  
+  });
+
+
+  self.getOverlayDb().addListener("onSearch", function() {
+    return self.refreshSearchResults();
+  });
+
+  this._tabIdCount = 0;
+}
+
+AbstractPanel.prototype = Object.create(Panel.prototype);
+AbstractPanel.prototype.constructor = AbstractPanel;
+
+AbstractPanel.prototype.setOverlayDb = function(overlayDb){
+  if (overlayDb === undefined) {
+    throw new Error("Undefined overlayDb");
+  }
+  this._overlayDb = overlayDb;
+};
+
+AbstractPanel.prototype.getOverlayDb = function(){
+  return this._overlayDb;
+};
+
+AbstractPanel.prototype.getSearchQueryElement = function() {
+  var children = this.getElement().children;
+  for (var i = 0; i < children.length; i++) {
+    var child = children[i];
+    if (child.getAttribute("name") === "searchQuery") {
+      return child;
+    }
+  }
+};
+
+AbstractPanel.prototype.getSearchResultsElement = function() {
+  var children = this.getElement().children;
+  for (var i = 0; i < children.length; i++) {
+    var child = children[i];
+    if (child.getAttribute("name") === "searchResults") {
+      return child;
+    }
+  }
+};
+
+AbstractPanel.prototype.getNavElement = function() {
+  var searchResultsElement = this.getSearchResultsElement();
+
+  if (searchResultsElement) {
+    var children = searchResultsElement.children;
+    for (var i = 0; i < children.length; i++) {
+      var child = children[i];
+      if (child.className.indexOf("nav-tabs") !== -1) {
+        return child;
+      }
+    }
+  }
+};
+
+AbstractPanel.prototype.getSearchButton = function() {
+  return this.getElementByName(this.getSearchQueryElement(),"searchButton");
+};
+
+AbstractPanel.prototype.getSearchInput = function() {
+  return this.getElementByName(this.getSearchQueryElement(),"searchInput");
+};
+
+AbstractPanel.prototype.getContentElement = function() {
+  var searchResultsElement = this.getSearchResultsElement();
+
+  if (searchResultsElement) {
+    var children = searchResultsElement.children;
+    for (var i = 0; i < children.length; i++) {
+      var child = children[i];
+      if (child.className.indexOf("tab-content") !== -1) {
+        return child;
+      }
+    }
+  }
+};
+
+AbstractPanel.prototype.clearResults = function() {
+  var navElement = this.getNavElement();
+  while (navElement.firstChild) {
+    navElement.removeChild(navElement.firstChild);
+  }
+
+  var contentElement = this.getContentElement();
+  while (contentElement.firstChild) {
+    contentElement.removeChild(contentElement.firstChild);
+  }
+};
+
+AbstractPanel.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 new Promise(function(resolve, reject){
+    return Promise.all(promises).then(function(results) {
+      for (var i = 0; i < queries.length; i++) {
+        self.addResultTab(queries[i], results[i]);
+      }
+      resolve();
+    }).catch(reject);
+  });
+
+};
+
+
+AbstractPanel.prototype.getAutocomplete = function() {
+  logger.warn("Get autocomplete not implemented");
+};
+
+AbstractPanel.prototype.searchByQuery = function() {
+  throw new Error("searchByQuery is not implemnted");
+};
+
+AbstractPanel.prototype.addResultTab = function(query, elements) {
+  var name = JSON.parse(query).query;
+
+  var tabId = this.getPanelName() + "Tab_" + this._tabIdCount;
+  this._tabIdCount++;
+
+  var navElement = this.getNavElement();
+  var contentElement = this.getContentElement();
+  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 (query.name !== undefined) {
+    navLink.innerHTML = query.name;
+  }
+  navElement.appendChild(navLi);
+
+  var contentDiv = document.createElement("div");
+  contentDiv.className = "pre-scrollable " + contentClass;
+  contentDiv.style.height = "100%";
+  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);
+
+  for (var i = 0; i < elements.length; i++) {
+    var element = elements[i].element;
+    var icon = elements[i].icon;
+    tableBody.appendChild(this.createTableElement(element, icon));
+  }
+};
+
+AbstractPanel.prototype.createTargetRow = function(target, icon) {
+  var self = this;
+  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);
+  if (target.getTargetElements().length > 0) {
+    iconColumn.appendChild(self.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 descColumn = document.createElement("td");
+  result.appendChild(descColumn);
+
+  descColumn.appendChild(self.createParamLine("Name: ", target.getName()));
+  descColumn.appendChild(self.createAnnotations("Elements: ", target.getTargetParticipants(), {
+    showType : false,
+    inline : true
+  }));
+  descColumn.appendChild(self.createAnnotations("References: ", target.getReferences(), {
+    showType : false,
+  }));
+  return result;
+};
+
+module.exports = AbstractPanel;
diff --git a/frontend-js/src/main/js/gui/AbstractPanel.js b/frontend-js/src/main/js/gui/AbstractPanel.js
deleted file mode 100644
index 920d564a6fc34fe5c260621cfc26f11b72327e8f..0000000000000000000000000000000000000000
--- a/frontend-js/src/main/js/gui/AbstractPanel.js
+++ /dev/null
@@ -1,522 +0,0 @@
-"use strict";
-
-/* exported logger */
-
-var Promise = require("bluebird");
-
-var GuiConnector= require('../GuiConnector');
-var ObjectWithListeners = require('../ObjectWithListeners');
-
-var logger = require('../logger');
-
-
-function AbstractPanel(params) {
-  ObjectWithListeners.call(this, params);
-
-  var self = this;
-
-  this.setPanelName(params.panelName);
-  this.setElement(params.element);
-  this.setMap(params.customMap);
-
-  this.setOverlayDb (self.getMap().getOverlayByName(params.panelName));
-
-  var searchByQuery = function(){
-    return self.searchByQuery();
-  };
-  
-  self.getSearchButton().onclick = searchByQuery;
-  self.getSearchInput().onkeypress = function(event){
-    if (event.keyCode === 13) {
-      searchByQuery();  
-    }
-  };
-  
-  
-  $(self.getSearchInput()).typeahead({
-    minLength: 1,
-  },{
-    source: function(query, callback){
-      callback(self.getAutocomplete(query));
-    }
-  });
-
-  $(self.getSearchInput()).on('typeahead:select', function() {
-    searchByQuery();  
-  });
-
-
-  self.getOverlayDb().addListener("onSearch", function() {
-    return self.refreshSearchResults();
-  });
-
-  this._tabIdCount = 0;
-}
-
-AbstractPanel.prototype = Object.create(ObjectWithListeners.prototype);
-AbstractPanel.prototype.constructor = AbstractPanel;
-
-AbstractPanel.prototype.disablePanel = function(message){
-  this.getSearchQueryElement().style.visibility ="hidden";
-  this.getSearchResultsElement().style.visibility ="hidden";
-  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);
-  
-  this.getElement().insertBefore(hideReasonDiv, this.getSearchQueryElement());
-};
-
-AbstractPanel.prototype.setOverlayDb = function(overlayDb){
-  if (overlayDb === undefined) {
-    throw new Error("Undefined overlayDb");
-  }
-  this._overlayDb = overlayDb;
-};
-
-AbstractPanel.prototype.getOverlayDb = function(){
-  return this._overlayDb;
-};
-
-AbstractPanel.prototype. createLabel=function(value) {
-  var result = document.createElement("span");
-  result.innerHTML = value;
-  result.className = "searchDescriptionLabel";
-  return result;
-};
-AbstractPanel.prototype.createPostTranslationalModifications = function(label, value) {
-  var result = document.createElement("div");
-  if (value !== undefined) {
-    throw new Error("Not implemented");
-  }
-  return result;
-};
-
-AbstractPanel.prototype.createCandidates=function(label, value) {
-  var result = document.createElement("div");
-  if (value !== undefined) {
-    throw new Error("Not implemented");
-  }
-  return result;
-};
-
-AbstractPanel.prototype.createChebiTree=function(label, value) {
-  var result = document.createElement("div");
-  if (value !== undefined) {
-    throw new Error("Not implemented");
-  }
-  return result;
-};
-AbstractPanel.prototype.createSeparator=function() {
-  var result = document.createElement("hr");
-  return result;
-};
-
-AbstractPanel.prototype.createNewLine=function(count) {
-  var result = document.createElement("p");
-  if (count > 0) {
-    result.style.height = ((count-1) * 10) + "px";
-  }
-  return result;
-};
-
-
-AbstractPanel.prototype.createLink=function(url, name) {
-  var link = document.createElement("a");
-  link.href = url;
-  link.innerHTML = name;
-  link.style.textDecoration = "underline";
-  return link;
-};
-
-AbstractPanel.prototype.createAnnotationLink=function(element, showType) {
-  var name, type, hint;
-  if (element.title!==undefined) {
-    hint = element.title+" "+element.authors.join(", ")+", "+element.year+", "+ element.journal;
-    type = "PUBMED";
-    name = element.id;
-  } else {
-    name = element.name;
-    type = element.type;
-  }
-  var link;
-  if (showType) {
-    link = this.createLink(element.link, type + " (" + name + ")");
-  } else {
-    link = this.createLink(element.link, name);
-  }
-  if (hint!==undefined) {
-    var div = document.createElement("div");
-    div.title = hint;
-    div.appendChild(link);
-    return div;
-  } else {
-    return link;
-  }
-};
-
-AbstractPanel.prototype.createAnnotations=function(label, value, options) {
-  var showType = true;
-  var inline = false;
-  if (options!== undefined) {
-    if (options.showType!==undefined) {
-      showType = options.showType;
-    }
-    if (options.inline!==undefined) {
-      inline = options.inline;
-    }
-  }
-  var result = document.createElement("div");
-  if (value !== undefined && value.length > 0) {
-    var self = this;
-    result.appendChild(self.createLabel(label));
-    if (!inline) {
-      result.appendChild(self.createNewLine());
-    }
-    for (var i = 0; i < value.length; i++) {
-      var element = value[i];
-      var link = this.createAnnotationLink(element, showType);
-      if (inline) {
-        if (i>0){
-          var coma = document.createElement("span");
-          coma.innerHTML = ", ";
-          result.appendChild(coma);
-        }
-        result.appendChild(link);
-      } else {
-
-        var row = document.createElement("div");
-        row.style.height = "26px";
-        if (i % 2 === 0) {
-          row.className = "annotationRowOdd";
-        } else {
-          row.className = "annotationRowEven";
-        }
-        var header = document.createElement("div");
-        header.style.width = "24px";
-        header.style.float = "left";
-        header.innerHTML = "[" + (i + 1) + "]";
-        row.appendChild(header);
-
-        var body = document.createElement("div");
-        body.style.float = "left";
-        body.appendChild(link);
-        row.appendChild(body);
-        result.appendChild(row);
-      }
-    }
-  }
-  return result;
-};
-
-AbstractPanel.prototype.setMap = function(map) {
-  this._map = map;
-};
-
-AbstractPanel.prototype.getMap = function() {
-  return this._map;
-};
-
-AbstractPanel.prototype.setPanelName = function(panelName) {
-  this._panelName = panelName;
-};
-
-AbstractPanel.prototype.getPanelName = function() {
-  return this._panelName;
-};
-
-AbstractPanel.prototype.setElement = function(element) {
-  if (element === undefined || element === null) {
-    throw new Error("DOM Element must be defined");
-  }
-  this._element = element;
-
-  if (this.getNavElement() === undefined) {
-    throw new Error("No nav-tabs div found in the search panel element");
-  }
-  if (this.getContentElement() === undefined) {
-    throw new Error("No tab-content div found in the search panel element");
-  }
-  if (this.getSearchButton() === undefined) {
-    throw new Error("No searchButton found in the search panel element");
-  }
-  if (this.getSearchInput() === undefined) {
-    throw new Error("No searchInput found in the search panel element");
-  }
-};
-
-AbstractPanel.prototype.getSearchQueryElement = function() {
-  var children = this.getElement().children;
-  for (var i = 0; i < children.length; i++) {
-    var child = children[i];
-    if (child.getAttribute("name") === "searchQuery") {
-      return child;
-    }
-  }
-};
-
-AbstractPanel.prototype.getSearchResultsElement = function() {
-  var children = this.getElement().children;
-  for (var i = 0; i < children.length; i++) {
-    var child = children[i];
-    if (child.getAttribute("name") === "searchResults") {
-      return child;
-    }
-  }
-};
-
-AbstractPanel.prototype.getNavElement = function() {
-  var searchResultsElement = this.getSearchResultsElement();
-
-  if (searchResultsElement) {
-    var children = searchResultsElement.children;
-    for (var i = 0; i < children.length; i++) {
-      var child = children[i];
-      if (child.className.indexOf("nav-tabs") !== -1) {
-        return child;
-      }
-    }
-  }
-};
-
-AbstractPanel.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;
-};
-
-AbstractPanel.prototype.getSearchButton = function() {
-  return this.getElementByName(this.getSearchQueryElement(),"searchButton");
-};
-
-AbstractPanel.prototype.getSearchInput = function() {
-  return this.getElementByName(this.getSearchQueryElement(),"searchInput");
-};
-
-AbstractPanel.prototype.getContentElement = function() {
-  var searchResultsElement = this.getSearchResultsElement();
-
-  if (searchResultsElement) {
-    var children = searchResultsElement.children;
-    for (var i = 0; i < children.length; i++) {
-      var child = children[i];
-      if (child.className.indexOf("tab-content") !== -1) {
-        return child;
-      }
-    }
-  }
-};
-
-AbstractPanel.prototype.getElement = function() {
-  return this._element;
-};
-
-AbstractPanel.prototype.clearResults = function() {
-  var navElement = this.getNavElement();
-  while (navElement.firstChild) {
-    navElement.removeChild(navElement.firstChild);
-  }
-
-  var contentElement = this.getContentElement();
-  while (contentElement.firstChild) {
-    contentElement.removeChild(contentElement.firstChild);
-  }
-};
-
-AbstractPanel.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 new Promise(function(resolve, reject){
-    return Promise.all(promises).then(function(results) {
-      for (var i = 0; i < queries.length; i++) {
-        self.addResultTab(queries[i], results[i]);
-      }
-      resolve();
-    }).catch(reject);
-  });
-
-};
-
-
-AbstractPanel.prototype.createLabelText = function(value) {
-  var result = document.createElement("span");
-  if (value !== undefined) {
-    result.innerHTML = value;
-  }
-  return result;
-};
-
-
-AbstractPanel.prototype.createParamLine = function(label, value) {
-  var result = document.createElement("div");
-  if (value !== undefined) {
-    var self = this;
-    result.appendChild(self.createLabel(label));
-    result.appendChild(self.createLabelText(value));
-    result.appendChild(self.createNewLine());
-  }
-  return result;
-};
-
-AbstractPanel.prototype.createIcon = function(icon) {
-  var result = document.createElement("div");
-  if (icon !== undefined && icon !== null) {
-    var img = document.createElement("img");
-    img.src=GuiConnector.getImgPrefix()+icon;
-    img.style.float="left";
-    img.hspace="5";
-    result.appendChild(img);
-  }
-  return result;
-};
-
-AbstractPanel.prototype.createArrayParamLine = function(label, value) {
-  var result = document.createElement("div");
-  if (value !== undefined && value.length > 0) {
-    var self = this;
-    result.appendChild(self.createLabel(label));
-    result.appendChild(self.createLabelText(value.join(",")));
-    result.appendChild(self.createNewLine());
-  }
-  return result;
-};
-
-AbstractPanel.prototype.createSubMapLink = function(label, element) {
-  var self = this;
-  var result = document.createElement("div");
-  if (element !== undefined) {
-    var button = document.createElement("button");
-    button.text = element.getModelId();
-    button.onclick = function() {
-      return self.getMap().openSubmodel(element.getModelId());
-    };
-    result.appendChild(this.createLabel("Submodel: "));
-    result.appendChild(button);
-  }
-  return result;
-};
-
-AbstractPanel.prototype.getAutocomplete = function() {
-  logger.warn("Get autocomplete not implemented");
-};
-
-AbstractPanel.prototype.searchByQuery = function() {
-  throw new Error("searchByQuery is not implemnted");
-};
-
-AbstractPanel.prototype.addResultTab = function(query, elements) {
-  var name = JSON.parse(query).query;
-
-  var tabId = this.getPanelName() + "Tab_" + this._tabIdCount;
-  this._tabIdCount++;
-
-  var navElement = this.getNavElement();
-  var contentElement = this.getContentElement();
-  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 (query.name !== undefined) {
-    navLink.innerHTML = query.name;
-  }
-  navElement.appendChild(navLi);
-
-  var contentDiv = document.createElement("div");
-  contentDiv.className = "pre-scrollable " + contentClass;
-  contentDiv.style.height = "100%";
-  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);
-
-  for (var i = 0; i < elements.length; i++) {
-    var element = elements[i].element;
-    var icon = elements[i].icon;
-    tableBody.appendChild(this.createTableElement(element, icon));
-  }
-};
-
-AbstractPanel.prototype.createTargetRow = function(target, icon) {
-  var self = this;
-  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);
-  if (target.getTargetElements().length > 0) {
-    iconColumn.appendChild(self.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 descColumn = document.createElement("td");
-  result.appendChild(descColumn);
-
-  descColumn.appendChild(self.createParamLine("Name: ", target.getName()));
-  descColumn.appendChild(self.createAnnotations("Elements: ", target.getTargetParticipants(), {
-    showType : false,
-    inline : true
-  }));
-  descColumn.appendChild(self.createAnnotations("References: ", target.getReferences(), {
-    showType : false,
-  }));
-  return result;
-};
-
-
-module.exports = AbstractPanel;
diff --git a/frontend-js/src/main/js/gui/ChemicalPanel.js b/frontend-js/src/main/js/gui/ChemicalPanel.js
index 28f21f359e5c0e98465fe8d8c18160c4ca1008b8..ef4f0c0c3a299ae6e60a84ff7db518eddb3cafa6 100644
--- a/frontend-js/src/main/js/gui/ChemicalPanel.js
+++ b/frontend-js/src/main/js/gui/ChemicalPanel.js
@@ -3,17 +3,17 @@
 /* exported logger */
 var logger = require('../logger');
 
-var AbstractPanel = require('./AbstractPanel');
+var AbstractDbPanel = require('./AbstractDbPanel');
 
 function ChemicalPanel(params) {
   params.panelName = "chemical";
-  AbstractPanel.call(this, params);
+  AbstractDbPanel.call(this, params);
 
   if (params.disease===undefined) {
     this.disablePanel("DISEASE NOT DEFINED FOR PROJECT. PLEASE, DEFINE IT IN THE ADMIN SECTION.");
   }
 }
-ChemicalPanel.prototype = Object.create(AbstractPanel.prototype);
+ChemicalPanel.prototype = Object.create(AbstractDbPanel.prototype);
 ChemicalPanel.prototype.constructor = ChemicalPanel;
 
 ChemicalPanel.prototype.createPreamble = function(chemical) {
diff --git a/frontend-js/src/main/js/gui/DrugPanel.js b/frontend-js/src/main/js/gui/DrugPanel.js
index 0a4f04859f3555c7a0b741c763ea4b1d1925bde0..241bc725840893a2fea0069af78de85da744fe97 100644
--- a/frontend-js/src/main/js/gui/DrugPanel.js
+++ b/frontend-js/src/main/js/gui/DrugPanel.js
@@ -3,13 +3,13 @@
 /* exported logger */
 var logger = require('../logger');
 
-var AbstractPanel = require('./AbstractPanel');
+var AbstractDbPanel = require('./AbstractDbPanel');
 
 function DrugPanel(params) {
   params.panelName = "drug";
-  AbstractPanel.call(this, params);
+  AbstractDbPanel.call(this, params);
 }
-DrugPanel.prototype = Object.create(AbstractPanel.prototype);
+DrugPanel.prototype = Object.create(AbstractDbPanel.prototype);
 DrugPanel.prototype.constructor = DrugPanel;
 
 DrugPanel.prototype.createPreamble = function(drug) {
diff --git a/frontend-js/src/main/js/gui/MiRnaPanel.js b/frontend-js/src/main/js/gui/MiRnaPanel.js
index 656084a767acb44dd2f6b02e47d6d76bb3589368..b32b1793808773759a3594a5dd52d0536b07b11a 100644
--- a/frontend-js/src/main/js/gui/MiRnaPanel.js
+++ b/frontend-js/src/main/js/gui/MiRnaPanel.js
@@ -3,13 +3,13 @@
 /* exported logger */
 var logger = require('../logger');
 
-var AbstractPanel = require('./AbstractPanel');
+var AbstractDbPanel = require('./AbstractDbPanel');
 
 function MiRnaPanel(params) {
   params.panelName = "mirna";
-  AbstractPanel.call(this, params);
+  AbstractDbPanel.call(this, params);
 }
-MiRnaPanel.prototype = Object.create(AbstractPanel.prototype);
+MiRnaPanel.prototype = Object.create(AbstractDbPanel.prototype);
 MiRnaPanel.prototype.constructor = MiRnaPanel;
 
 MiRnaPanel.prototype.createPreamble = function(miRna) {
diff --git a/frontend-js/src/main/js/gui/OverlayPanel.js b/frontend-js/src/main/js/gui/OverlayPanel.js
new file mode 100644
index 0000000000000000000000000000000000000000..32a408aacf04c588f7562c224c0c126942e1917f
--- /dev/null
+++ b/frontend-js/src/main/js/gui/OverlayPanel.js
@@ -0,0 +1,189 @@
+"use strict";
+
+/* exported logger */
+
+var Panel = require('./Panel');
+
+var logger = require('../logger');
+
+function OverlayPanel(params) {
+  params.panelName = "overlays";
+  Panel.call(this, params);
+
+  var self = this;
+
+  self.setPanelName(params.panelName);
+  self.setElement(params.element);
+  self.setMap(params.customMap);
+
+  self.refresh();
+}
+
+OverlayPanel.prototype = Object.create(Panel.prototype);
+OverlayPanel.prototype.constructor = OverlayPanel;
+
+OverlayPanel.prototype.clear = function() {
+  var table = this.getGeneralOverlaysTabElement();
+  while (table.firstChild) {
+    table.removeChild(table.firstChild);
+  }
+
+  table = this.getCustomOverlaysTabElement();
+  while (table.firstChild) {
+    table.removeChild(table.firstChild);
+  }
+
+};
+
+OverlayPanel.prototype.createTableHeader = function(edit) {
+  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;
+};
+
+OverlayPanel.prototype.createOverlayRow = function(overlay, checked) {
+  var self = this;
+  var result = document.createElement("tr");
+
+  if (checked) {
+    result.className = "active";
+  }
+
+  var nameTd = document.createElement("td");
+  nameTd.innerHTML = overlay.getName();
+  result.appendChild(nameTd);
+
+  var viewTd = document.createElement("td");
+  if (overlay.getInputDataAvailable()) {
+    var checkbox = document.createElement("input");
+    checkbox.type = "checkbox";
+    checkbox.checked = checked;
+    checkbox.onclick = function() {
+      if (this.checked) {
+        self.getMap().addSelectedLayout(overlay.getId());
+      } else {
+        self.getMap().removeSelectedLayout(overlay.getId());
+      }
+    };
+    viewTd.appendChild(checkbox);
+  } else {
+    var img = this.createIcon("icons/search.png");
+    var link = document.createElement("a");
+    link.href = "#";
+    link.onclick = function() {
+      self.getMap().openLayoutById(overlay.getId());
+      $(result).addClass('active').siblings().removeClass('active');
+    };
+    link.appendChild(img);
+    viewTd.appendChild(link);
+  }
+  result.appendChild(viewTd);
+
+  var dataTd = document.createElement("td");
+  if (overlay.getInputDataAvailable()) {
+    var button = document.createElement("button");
+    button.onclick = function() {
+      throw new Error("Not implemented");
+    };
+    dataTd.appendChild(button);
+  }
+
+  result.appendChild(dataTd);
+
+  if (overlay.getCreator() !== "" && overlay.getCreator() !== undefined) {
+    var editTd = document.createElement("td");
+    var editButton = document.createElement("button");
+    editButton.onclick = function() {
+      throw new Error("Not implemented");
+    };
+    editTd.appendChild(editButton);
+    result.appendChild(editTd);
+  }
+  return result;
+};
+
+OverlayPanel.prototype.refresh = function() {
+  var self = this;
+  return ServerConnector.getOverlays().then(function(customOverlays) {
+    var selectedOverlayIds = self.getMap().getSelectedLayouts();
+    var selectedOverlay = [];
+
+    for (var j = 0; j < selectedOverlayIds.length; j++) {
+      selectedOverlay[selectedOverlayIds[j]] = true;
+    }
+
+    var id = self.getMap().getGoogleMap().getMapTypeId().substring(2);
+    selectedOverlay[id] = true;
+
+    self.clear();
+
+    var generalOverlays = [];
+    var overlay;
+
+    var overlays = self.getMap().getLayouts();
+    for (var i = 0; i < overlays.length; i++) {
+      overlay = overlays[i];
+      if (overlay.getCreator() === undefined || overlay.getCreator() === "") {
+        generalOverlays.push(overlay);
+      }
+    }
+
+    var table = self.getGeneralOverlaysTabElement();
+    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()]));
+    }
+
+    table = self.getCustomOverlaysTabElement();
+    table.appendChild(self.createTableHeader(true));
+
+    body = document.createElement("tbody");
+    table.appendChild(body);
+    for (i = 0; i < customOverlays.length; i++) {
+      overlay = customOverlays[i];
+      body.appendChild(self.createOverlayRow(overlay, selectedOverlay[overlay.getId()]));
+    }
+    return null;
+  });
+};
+
+OverlayPanel.prototype.getGeneralOverlaysElement = function() {
+  return this.getElementByName(this.getElement(), "generalOverlays");
+};
+
+OverlayPanel.prototype.getGeneralOverlaysTabElement = function() {
+  return this.getElementByName(this.getElement(), "generalOverlaysTab");
+};
+
+OverlayPanel.prototype.getCustomOverlaysElement = function() {
+  return this.getElementByName(this.getElement(), "customOverlays");
+};
+OverlayPanel.prototype.getCustomOverlaysTabElement = function() {
+  return this.getElementByName(this.getElement(), "customOverlaysTab");
+};
+module.exports = OverlayPanel;
diff --git a/frontend-js/src/main/js/gui/Panel.js b/frontend-js/src/main/js/gui/Panel.js
new file mode 100644
index 0000000000000000000000000000000000000000..9ea2f4937fb2dcb7127223d7a8dc39cf43dca7e9
--- /dev/null
+++ b/frontend-js/src/main/js/gui/Panel.js
@@ -0,0 +1,270 @@
+"use strict";
+
+/* exported logger */
+
+var GuiConnector = require('../GuiConnector');
+var ObjectWithListeners = require('../ObjectWithListeners');
+
+var logger = require('../logger');
+
+function Panel(params) {
+  ObjectWithListeners.call(this, params);
+
+  var self = this;
+
+  self.setPanelName(params.panelName);
+  self.setElement(params.element);
+  self.setMap(params.customMap);
+}
+
+Panel.prototype = Object.create(ObjectWithListeners.prototype);
+Panel.prototype.constructor = Panel;
+
+Panel.prototype.disablePanel = function(message) {
+  this.getSearchQueryElement().style.visibility = "hidden";
+  this.getSearchResultsElement().style.visibility = "hidden";
+  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);
+
+  this.getElement().insertBefore(hideReasonDiv, this.getSearchQueryElement());
+};
+
+Panel.prototype.createLabel = function(value) {
+  var result = document.createElement("span");
+  result.innerHTML = value;
+  result.className = "searchDescriptionLabel";
+  return result;
+};
+Panel.prototype.createPostTranslationalModifications = function(label, value) {
+  var result = document.createElement("div");
+  if (value !== undefined) {
+    throw new Error("Not implemented");
+  }
+  return result;
+};
+
+Panel.prototype.createCandidates = function(label, value) {
+  var result = document.createElement("div");
+  if (value !== undefined) {
+    throw new Error("Not implemented");
+  }
+  return result;
+};
+
+Panel.prototype.createChebiTree = function(label, value) {
+  var result = document.createElement("div");
+  if (value !== undefined) {
+    throw new Error("Not implemented");
+  }
+  return result;
+};
+Panel.prototype.createSeparator = function() {
+  var result = document.createElement("hr");
+  return result;
+};
+
+Panel.prototype.createNewLine = function(count) {
+  var result = document.createElement("p");
+  if (count > 0) {
+    result.style.height = ((count - 1) * 10) + "px";
+  }
+  return result;
+};
+
+Panel.prototype.createLink = function(url, name) {
+  var link = document.createElement("a");
+  link.href = url;
+  link.innerHTML = name;
+  link.style.textDecoration = "underline";
+  return link;
+};
+
+Panel.prototype.createAnnotationLink = function(element, showType) {
+  var name, type, hint;
+  if (element.title !== undefined) {
+    hint = element.title + " " + element.authors.join(", ") + ", " + element.year + ", " + element.journal;
+    type = "PUBMED";
+    name = element.id;
+  } else {
+    name = element.name;
+    type = element.type;
+  }
+  var link;
+  if (showType) {
+    link = this.createLink(element.link, type + " (" + name + ")");
+  } else {
+    link = this.createLink(element.link, name);
+  }
+  if (hint !== undefined) {
+    var div = document.createElement("div");
+    div.title = hint;
+    div.appendChild(link);
+    return div;
+  } else {
+    return link;
+  }
+};
+
+Panel.prototype.createAnnotations = function(label, value, options) {
+  var showType = true;
+  var inline = false;
+  if (options !== undefined) {
+    if (options.showType !== undefined) {
+      showType = options.showType;
+    }
+    if (options.inline !== undefined) {
+      inline = options.inline;
+    }
+  }
+  var result = document.createElement("div");
+  if (value !== undefined && value.length > 0) {
+    var self = this;
+    result.appendChild(self.createLabel(label));
+    if (!inline) {
+      result.appendChild(self.createNewLine());
+    }
+    for (var i = 0; i < value.length; i++) {
+      var element = value[i];
+      var link = this.createAnnotationLink(element, showType);
+      if (inline) {
+        if (i > 0) {
+          var coma = document.createElement("span");
+          coma.innerHTML = ", ";
+          result.appendChild(coma);
+        }
+        result.appendChild(link);
+      } else {
+
+        var row = document.createElement("div");
+        row.style.height = "26px";
+        if (i % 2 === 0) {
+          row.className = "annotationRowOdd";
+        } else {
+          row.className = "annotationRowEven";
+        }
+        var header = document.createElement("div");
+        header.style.width = "24px";
+        header.style.float = "left";
+        header.innerHTML = "[" + (i + 1) + "]";
+        row.appendChild(header);
+
+        var body = document.createElement("div");
+        body.style.float = "left";
+        body.appendChild(link);
+        row.appendChild(body);
+        result.appendChild(row);
+      }
+    }
+  }
+  return result;
+};
+
+Panel.prototype.setMap = function(map) {
+  this._map = map;
+};
+
+Panel.prototype.getMap = function() {
+  return this._map;
+};
+
+Panel.prototype.setPanelName = function(panelName) {
+  this._panelName = panelName;
+};
+
+Panel.prototype.getPanelName = function() {
+  return this._panelName;
+};
+
+Panel.prototype.setElement = function(element) {
+  if (element === undefined || element === null) {
+    throw new Error("DOM Element must be defined");
+  }
+  this._element = element;
+};
+
+Panel.prototype.getElement = function() {
+  return this._element;
+};
+
+Panel.prototype.createLabelText = function(value) {
+  var result = document.createElement("span");
+  if (value !== undefined) {
+    result.innerHTML = value;
+  }
+  return result;
+};
+
+Panel.prototype.createParamLine = function(label, value) {
+  var result = document.createElement("div");
+  if (value !== undefined) {
+    var self = this;
+    result.appendChild(self.createLabel(label));
+    result.appendChild(self.createLabelText(value));
+    result.appendChild(self.createNewLine());
+  }
+  return result;
+};
+
+Panel.prototype.createIcon = function(icon) {
+  var result = document.createElement("div");
+  if (icon !== undefined && icon !== null) {
+    var img = document.createElement("img");
+    img.src = GuiConnector.getImgPrefix() + icon;
+    img.style.float = "left";
+    img.hspace = "5";
+    result.appendChild(img);
+  }
+  return result;
+};
+
+Panel.prototype.createArrayParamLine = function(label, value) {
+  var result = document.createElement("div");
+  if (value !== undefined && value.length > 0) {
+    var self = this;
+    result.appendChild(self.createLabel(label));
+    result.appendChild(self.createLabelText(value.join(",")));
+    result.appendChild(self.createNewLine());
+  }
+  return result;
+};
+
+Panel.prototype.createSubMapLink = function(label, element) {
+  var self = this;
+  var result = document.createElement("div");
+  if (element !== undefined) {
+    var button = document.createElement("button");
+    button.text = element.getModelId();
+    button.onclick = function() {
+      return self.getMap().openSubmodel(element.getModelId());
+    };
+    result.appendChild(this.createLabel("Submodel: "));
+    result.appendChild(button);
+  }
+  return result;
+};
+
+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;
+};
+
+
+module.exports = Panel;
diff --git a/frontend-js/src/main/js/gui/SearchPanel.js b/frontend-js/src/main/js/gui/SearchPanel.js
index 32db73606c9811d727892524b03e1cd975ede8b5..d6de27b1baea98705d8d21bc5660e90be0998120 100644
--- a/frontend-js/src/main/js/gui/SearchPanel.js
+++ b/frontend-js/src/main/js/gui/SearchPanel.js
@@ -2,21 +2,21 @@
 
 /* exported logger */
 
-var AbstractPanel = require('./AbstractPanel');
+var AbstractDbPanel = require('./AbstractDbPanel');
 var Alias = require('../map/data/Alias');
 var Reaction = require('../map/data/Reaction');
 var logger = require('../logger');
 
 function SearchPanel(params) {
   params.panelName = "search";
-  AbstractPanel.call(this, params);
+  AbstractDbPanel.call(this, params);
 
   if (this.getSearchPerfectMatch() === undefined) {
     throw new Error("No searchPerfectMatch found in the search panel element");
   }
 }
 
-SearchPanel.prototype = Object.create(AbstractPanel.prototype);
+SearchPanel.prototype = Object.create(AbstractDbPanel.prototype);
 SearchPanel.prototype.constructor = SearchPanel;
 
 SearchPanel.prototype.getSearchPerfectMatch = function() {
diff --git a/frontend-js/src/main/js/map/data/LayoutData.js b/frontend-js/src/main/js/map/data/LayoutData.js
index 132d1867c60542dc60637dbc7f1f36ae7204d79f..a2256996827d90a56b0cb7814d37d8fd1dc789db 100644
--- a/frontend-js/src/main/js/map/data/LayoutData.js
+++ b/frontend-js/src/main/js/map/data/LayoutData.js
@@ -20,6 +20,7 @@ function LayoutData(layoutId, name) {
     this.setId(object.idObject);
     this.setName(object.name);
     this.setDirectory(object.directory);
+    this.setCreator(object.creator);
     this.setInputDataAvailable(object.inputDataAvailable);
   } else {
     // default two param call
@@ -60,6 +61,14 @@ LayoutData.prototype.setId = function(id) {
   this.id = parseInt(id);
 };
 
+LayoutData.prototype.getCreator = function() {
+  return this._creator;
+};
+
+LayoutData.prototype.setCreator = function(creator) {
+  this._creator = creator;
+};
+
 LayoutData.prototype.getInputDataAvailable = function() {
   return this._inputDataAvailable;
 };
diff --git a/frontend-js/src/main/js/minerva.js b/frontend-js/src/main/js/minerva.js
index 08cc8fd33649d7a1353bad344df5f3058f02c58a..9543aebb6ec75dd72f57714429f6cfbb3d10dd9c 100644
--- a/frontend-js/src/main/js/minerva.js
+++ b/frontend-js/src/main/js/minerva.js
@@ -12,6 +12,7 @@ var DrugDbOverlay = require('./map/overlay/DrugDbOverlay');
 var DrugPanel = require('./gui/DrugPanel');
 var MiRnaDbOverlay = require('./map/overlay/MiRnaDbOverlay');
 var MiRnaPanel = require('./gui/MiRnaPanel');
+var OverlayPanel = require('./gui/OverlayPanel');
 var SearchDbOverlay = require('./map/overlay/SearchDbOverlay');
 var SearchPanel = require('./gui/SearchPanel');
 
@@ -169,6 +170,11 @@ function create(params) {
     logger.warn("No overlay collection defined");
   }
 
+  new OverlayPanel({
+    element : document.getElementById("overlayTab"),
+    customMap : result
+  });
+
 
   return new Promise(function(resolve, reject) {
     restoreSearchQuery(result).then(function(){
diff --git a/frontend-js/src/test/js/gui/OverlayPanel-test.js b/frontend-js/src/test/js/gui/OverlayPanel-test.js
new file mode 100644
index 0000000000000000000000000000000000000000..d9522ddad49e6b3d5aac0b6061ea00342d15b04f
--- /dev/null
+++ b/frontend-js/src/test/js/gui/OverlayPanel-test.js
@@ -0,0 +1,48 @@
+"use strict";
+
+var Helper = require('../helper');
+
+require("../mocha-config.js");
+
+var OverlayPanel = require('../../../main/js/gui/OverlayPanel');
+
+
+var chai = require('chai');
+var assert = chai.assert;
+var logger = require('../logger');
+
+describe('OverlayPanel', function() {
+
+  var helper;
+  before(function() {
+    helper = new Helper();
+  });
+
+  it('contructor', function() {
+    var div = helper.createOverlayTab();
+
+    var map = helper.createCustomMap();
+
+    new OverlayPanel({
+      element : div,
+      customMap : map
+    });
+    assert.equal(logger.getWarnings().length, 0);
+  });
+
+  it('refresh', function() {
+    var div = helper.createOverlayTab();
+
+    var map = helper.createCustomMap();
+
+    var panel = new OverlayPanel({
+      element : div,
+      customMap : map
+    });
+    
+    return panel.refresh().then(function(){
+      assert.ok(panel.getElement().innerHTML.indexOf("testLayout")>=0);
+    });
+  });
+
+});
diff --git a/frontend-js/src/test/js/helper.js b/frontend-js/src/test/js/helper.js
index d9d487f6580ed420fdeec18c7df0ad34e4472786..c01426ee7a3a868affd2db3a475e171761f9ce00 100644
--- a/frontend-js/src/test/js/helper.js
+++ b/frontend-js/src/test/js/helper.js
@@ -79,6 +79,28 @@ Helper.prototype.createPanelTab = function(id) {
   return result;
 };
 
+Helper.prototype.createOverlayTab = function() {
+  var result = document.createElement("div");
+  result.id = "overlayTab";
+  var generalOverlaysDiv = document.createElement("div");
+  generalOverlaysDiv.setAttribute("name", "generalOverlays");
+  result.appendChild(generalOverlaysDiv);
+  
+  var generalOverlaysTabDiv = document.createElement("table");
+  generalOverlaysTabDiv.setAttribute("name", "generalOverlaysTab");
+  generalOverlaysDiv.appendChild(generalOverlaysTabDiv);
+  
+  var customOverlaysDiv = document.createElement("div");
+  customOverlaysDiv.setAttribute("name", "customOverlays");
+  result.appendChild(customOverlaysDiv);
+  
+  var customOverlaysTabDiv = document.createElement("table");
+  customOverlaysTabDiv.setAttribute("name", "customOverlaysTab");
+  customOverlaysDiv.appendChild(customOverlaysTabDiv);
+  
+  return result;
+};
+
 Helper.prototype.createCommentDbOverlay = function(map) {
   var result = new CommentDbOverlay({
     map : map,
diff --git a/frontend-js/src/test/js/minerva-test.js b/frontend-js/src/test/js/minerva-test.js
index cafc1f16ffe73876133cdff806e030bb7caa765b..8641ddf4cc618d6b3105dd84c1d75cab262e76e2 100644
--- a/frontend-js/src/test/js/minerva-test.js
+++ b/frontend-js/src/test/js/minerva-test.js
@@ -29,6 +29,9 @@ describe('minerva global', function() {
 
     global.mirnaTab = helper.createMiRnaTab();
     document.body.appendChild(global.mirnaTab);
+
+    global.overlayTab = helper.createOverlayTab();
+    document.body.appendChild(global.overlayTab);
   });
 
   afterEach(function() {
@@ -36,6 +39,7 @@ describe('minerva global', function() {
     document.body.removeChild(global.drugTab);
     document.body.removeChild(global.chemicalTab);
     document.body.removeChild(global.mirnaTab);
+    document.body.removeChild(global.overlayTab);
   });
 
   it('create', function() {
diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/controller/UserController.java b/rest-api/src/main/java/lcsb/mapviewer/api/controller/UserController.java
index 1313da0dc02deb9c5c2faaced33df1b7a2348903..c6634fb1ca46674e1742efbe7d3bd963d6c31172 100644
--- a/rest-api/src/main/java/lcsb/mapviewer/api/controller/UserController.java
+++ b/rest-api/src/main/java/lcsb/mapviewer/api/controller/UserController.java
@@ -25,6 +25,9 @@ public class UserController extends BaseController {
 	@Autowired
 	private IUserService userService;
 
+	@Autowired
+	private UserRestImpl userRest;
+
 	@RequestMapping(value = "/login", method = { RequestMethod.GET, RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE })
 	public AuthenticationToken login(@RequestParam(value = "login", defaultValue = Configuration.ANONYMOUS_LOGIN) String login,
 			@RequestParam(value = "password", required = false) String password) {
@@ -37,6 +40,13 @@ public class UserController extends BaseController {
 		return userService.getToken(token);
 	}
 
+	@RequestMapping(value = "/getUser", method = { RequestMethod.GET, RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE })
+	public Map<String, Object> getUser(@RequestParam(value = "token", required = false) String token,
+			@RequestParam(value = "userId", defaultValue = "") String userId,
+			@RequestParam(value = "columns", defaultValue = "") String columns) throws SecurityException {
+		return userRest.getUser(token, userId, columns);
+	}
+
 	@RequestMapping(value = "/logout", method = { RequestMethod.GET, RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE })
 	public Map<String, String> logout(@RequestParam(value = "token", required = false) String token) throws SecurityException {
 		userService.logout(token);
@@ -61,4 +71,21 @@ public class UserController extends BaseController {
 	public void setUserService(IUserService userService) {
 		this.userService = userService;
 	}
+
+	/**
+	 * @return the userRest
+	 * @see #userRest
+	 */
+	public UserRestImpl getUserRest() {
+		return userRest;
+	}
+
+	/**
+	 * @param userRest
+	 *          the userRest to set
+	 * @see #userRest
+	 */
+	public void setUserRest(UserRestImpl userRest) {
+		this.userRest = userRest;
+	}
 }
\ No newline at end of file
diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/controller/UserRestImpl.java b/rest-api/src/main/java/lcsb/mapviewer/api/controller/UserRestImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..a6de82a583a845dce5a03f606753925d123b6a25
--- /dev/null
+++ b/rest-api/src/main/java/lcsb/mapviewer/api/controller/UserRestImpl.java
@@ -0,0 +1,177 @@
+package lcsb.mapviewer.api.controller;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+import lcsb.mapviewer.common.exception.InvalidArgumentException;
+import lcsb.mapviewer.model.user.BasicPrivilege;
+import lcsb.mapviewer.model.user.ObjectPrivilege;
+import lcsb.mapviewer.model.user.PrivilegeType;
+import lcsb.mapviewer.model.user.User;
+import lcsb.mapviewer.services.SecurityException;
+import lcsb.mapviewer.services.interfaces.ILayoutService;
+import lcsb.mapviewer.services.interfaces.IUserService;
+
+@Transactional(value = "txManager")
+public class UserRestImpl {
+
+	@Autowired
+	private IUserService	 userService;
+
+	@Autowired
+	private ILayoutService layoutService;
+
+	/**
+	 * @return the userService
+	 * @see #userService
+	 */
+	public IUserService getUserService() {
+		return userService;
+	}
+
+	/**
+	 * @param userService
+	 *          the userService to set
+	 * @see #userService
+	 */
+	public void setUserService(IUserService userService) {
+		this.userService = userService;
+	}
+
+	public Map<String, Object> getUser(String token, String userId, String columns) throws SecurityException {
+		User ownUserData = userService.getUserByToken(token);
+		Integer id = null;
+		if (userId != null && !userId.isEmpty()) {
+			id = Integer.valueOf(userId);
+		} else {
+			id = ownUserData.getId();
+		}
+
+		Set<String> columnSet = createUserColumnSet(columns);
+
+		boolean isAdmin = userService.userHasPrivilege(ownUserData, PrivilegeType.USER_MANAGEMENT);
+
+		if (ownUserData.getId().equals(id)) {
+			return prepareUse(ownUserData, columnSet, true);
+		} else if (isAdmin) {
+			User user = userService.getUserById(id);
+			if (user == null) {
+				throw new SecurityException("You cannot access data of the user with given id");
+			}
+			return prepareUse(user, columnSet, isAdmin);
+		} else {
+			throw new SecurityException("You cannot access data of the user with given id");
+		}
+	}
+
+	private Set<String> createUserColumnSet(String columns) {
+		Set<String> columnsSet = new HashSet<>();
+		if (columns.equals("")) {
+			columnsSet.add("id");
+			columnsSet.add("login");
+			columnsSet.add("name");
+			columnsSet.add("surname");
+			columnsSet.add("email");
+			columnsSet.add("minColor");
+			columnsSet.add("maxColor");
+			columnsSet.add("removed");
+			columnsSet.add("privileges");
+		} else {
+			for (String str : columns.split(",")) {
+				columnsSet.add(str);
+			}
+		}
+		return columnsSet;
+	}
+
+	private Map<String, Object> prepareUse(User user, Set<String> columnsSet, boolean admin) {
+		Map<String, Object> result = new HashMap<>();
+		for (String string : columnsSet) {
+			String column = string.toLowerCase();
+			Object value = null;
+			if (column.equals("id") || column.equals("idobject")) {
+				value = user.getId();
+			} else if (column.equals("name")) {
+				value = user.getName();
+			} else if (column.equals("surname")) {
+				value = user.getSurname();
+			} else if (column.equals("login")) {
+				value = user.getLogin();
+			} else if (column.equals("email")) {
+				value = user.getEmail();
+			} else if (column.equals("mincolor")) {
+				value = user.getMinColor();
+			} else if (column.equals("maxcolor")) {
+				value = user.getMaxColor();
+			} else if (column.equals("removed")) {
+				value = user.isRemoved();
+			} else if (column.equals("privileges") && admin) {
+				value = preparePrivileges(user);
+			} else {
+				value = "Unknown column";
+			}
+			result.put(string, value);
+		}
+		return result;
+	}
+
+	private List<Map<String, Object>> preparePrivileges(User user) {
+		List<Map<String, Object>> result = new ArrayList<>();
+		for (BasicPrivilege privilege : user.getPrivileges()) {
+			if (privilege instanceof ObjectPrivilege) {
+				result.add(prepareObjectPrivilege((ObjectPrivilege) privilege));
+			} else {
+				result.add(prepareBasicPrivilege(privilege));
+			}
+		}
+		Map<String, Object> customLayouts = new HashMap<>();
+		customLayouts.put("type", "CUSTOM_LAYOUTS_AVAILABLE");
+		customLayouts.put("value", layoutService.getAvailableCustomLayoutsNumber(user));
+		result.add(customLayouts);
+		return result;
+	}
+
+	private Map<String, Object> prepareObjectPrivilege(ObjectPrivilege privilege) {
+		Map<String, Object> result = new HashMap<>();
+		result.put("type", privilege.getType());
+		result.put("value", privilege.getLevel());
+		result.put("objectId", privilege.getIdObject());
+		return result;
+	}
+
+	private Map<String, Object> prepareBasicPrivilege(BasicPrivilege privilege) {
+		Map<String, Object> result = new HashMap<>();
+		if (privilege.getClass().equals(BasicPrivilege.class)) {
+			result.put("type", privilege.getType());
+			result.put("value", privilege.getLevel());
+			return result;
+		} else {
+			throw new InvalidArgumentException("Don't know how to handle class: " + privilege.getClass());
+		}
+	}
+
+	/**
+	 * @return the layoutService
+	 * @see #layoutService
+	 */
+	public ILayoutService getLayoutService() {
+		return layoutService;
+	}
+
+	/**
+	 * @param layoutService
+	 *          the layoutService to set
+	 * @see #layoutService
+	 */
+	public void setLayoutService(ILayoutService layoutService) {
+		this.layoutService = layoutService;
+	}
+
+}
diff --git a/rest-api/src/main/resources/applicationContext-rest.xml b/rest-api/src/main/resources/applicationContext-rest.xml
index d86f6e3c69935779077ebde665e150c6d2b6cae5..279ea1582a1281a7c4d9f3af82f2b00c1f8e0399 100644
--- a/rest-api/src/main/resources/applicationContext-rest.xml
+++ b/rest-api/src/main/resources/applicationContext-rest.xml
@@ -18,5 +18,6 @@
 	<bean id="MiRnaRestImpl" class="lcsb.mapviewer.api.mirna.MiRnaRestImpl"/>
 	<bean id="OverlayRestImpl" class="lcsb.mapviewer.api.overlay.OverlayRestImpl"/>
 	<bean id="ProjectRestImpl" class="lcsb.mapviewer.api.project.ProjectRestImpl"/>
+	<bean id="UserRestImpl" class="lcsb.mapviewer.api.controller.UserRestImpl"/>
 	
 </beans>
\ No newline at end of file
diff --git a/rest-api/src/test/java/lcsb/mapviewer/api/AllRestTests.java b/rest-api/src/test/java/lcsb/mapviewer/api/AllRestTests.java
index 92d55361808963d9fd2869f1f94978f55d4df700..d80c3d11d7252f56d727920b65864cb8b806cf13 100644
--- a/rest-api/src/test/java/lcsb/mapviewer/api/AllRestTests.java
+++ b/rest-api/src/test/java/lcsb/mapviewer/api/AllRestTests.java
@@ -5,11 +5,13 @@ import org.junit.runners.Suite;
 import org.junit.runners.Suite.SuiteClasses;
 
 import lcsb.mapviewer.api.comment.AllCommentTests;
+import lcsb.mapviewer.api.controller.AllUserTests;
 import lcsb.mapviewer.api.project.AllProjectTests;
 
 @RunWith(Suite.class)
 @SuiteClasses({ AllCommentTests.class, //
-		AllProjectTests.class,//
+		AllProjectTests.class, //
+		AllUserTests.class,//
 })
 public class AllRestTests {
 
diff --git a/rest-api/src/test/java/lcsb/mapviewer/api/controller/AllUserTests.java b/rest-api/src/test/java/lcsb/mapviewer/api/controller/AllUserTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..85b6fdea54c67a4c7bf35cedc4a52e7fecfd05db
--- /dev/null
+++ b/rest-api/src/test/java/lcsb/mapviewer/api/controller/AllUserTests.java
@@ -0,0 +1,11 @@
+package lcsb.mapviewer.api.controller;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@RunWith(Suite.class)
+@SuiteClasses({ UserRestImplTest.class })
+public class AllUserTests {
+
+}
diff --git a/rest-api/src/test/java/lcsb/mapviewer/api/controller/UserRestImplTest.java b/rest-api/src/test/java/lcsb/mapviewer/api/controller/UserRestImplTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..4d4096cdf350aa5271c800cc40a3a84c201eb2d9
--- /dev/null
+++ b/rest-api/src/test/java/lcsb/mapviewer/api/controller/UserRestImplTest.java
@@ -0,0 +1,43 @@
+package lcsb.mapviewer.api.controller;
+
+import static org.junit.Assert.assertNotNull;
+
+import org.apache.log4j.Logger;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import lcsb.mapviewer.api.RestTestFunctions;
+
+public class UserRestImplTest extends RestTestFunctions {
+	Logger logger = Logger.getLogger(UserRestImplTest.class);
+
+	@Autowired
+	UserRestImpl userRestImpl;
+
+	@AfterClass
+	public static void tearDownAfterClass() throws Exception {
+	}
+
+	@Before
+	public void setUp() throws Exception {
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+
+	@Test
+	public void test() throws Exception {
+		try {
+			Object response = userRestImpl.getUser(token.getId(), "", "");
+			assertNotNull(response);
+		} catch (Exception e) {
+			e.printStackTrace();
+			throw e;
+		}
+	}
+
+}
diff --git a/web/src/main/webapp/index.xhtml b/web/src/main/webapp/index.xhtml
index 57c7c3c03a17f062031b67a5dc695bfc84af5672..ea90c402fa889aad228b856c37bf40aa61c2c326 100644
--- a/web/src/main/webapp/index.xhtml
+++ b/web/src/main/webapp/index.xhtml
@@ -50,7 +50,6 @@ function initMap(){
 
 				dataCollections: [
 								{name: "search"},
-								{name: "missingConnection"},
 								{name: "drug", allowSearchById:true, allowGeneralSearch: true},
 								{name: "chemical", allowSearchById:#{chemicalMB.linkedToDisease()}, allowGeneralSearch: #{chemicalMB.linkedToDisease() == true}},
 								{name: "mirna", allowSearchById:true, allowGeneralSearch: true},