diff --git a/frontend-js/src/main/js/GuiConnector.js b/frontend-js/src/main/js/GuiConnector.js
index 5596e0d97ba7a114b7c2ab3178e54d71eb10e3b9..87070fd26cebaef9099722450ab23ae2554bffc8 100644
--- a/frontend-js/src/main/js/GuiConnector.js
+++ b/frontend-js/src/main/js/GuiConnector.js
@@ -49,6 +49,12 @@ GuiConnector.getCustomMap = function() {
 };
 
 GuiConnector.init = function() {
+  // bootstrap tab initialization
+  $("ul.nav-tabs a").click(function(e) {
+    e.preventDefault();
+    $(this).tab('show');
+  });
+
   // find GuiConnector.getParams
   document.location.search.replace(/\??(?:([^=]+)=([^&]*)&?)/g, function() {
     function decode(s) {
@@ -67,11 +73,6 @@ GuiConnector.init = function() {
   GuiConnector.leftPanelTabNavi = new TabNavi("tabView", {
     top : "17px"
   });
-  GuiConnector.searchTabNavi = new TabNavi("tabView:mainForm:dTable", {
-    hideRemaining : false,
-    tabSize : 1,
-    top : "5px"
-  });
   GuiConnector.drugTabNavi = new TabNavi("tabView:drugForm:drugResults", {
     hideRemaining : false,
     tabSize : 1,
diff --git a/frontend-js/src/main/js/ObjectWithListeners.js b/frontend-js/src/main/js/ObjectWithListeners.js
index 2b326294519fec3be0c04cb3889aab30b3c77d18..11c7eaf4bce4cda627f874042a2e2507a615bce6 100644
--- a/frontend-js/src/main/js/ObjectWithListeners.js
+++ b/frontend-js/src/main/js/ObjectWithListeners.js
@@ -143,15 +143,17 @@ ObjectWithListeners.prototype.callListeners = function(type) {
     throw new Error("Unknown listener type: " + type);
   }
   var listenerList = this._validListeners[type];
+  var promises = [];
   if (listenerList.length > 0) {
     for ( var i in listenerList) {
       var e = {
         type : type,
         object : this,
       };
-      listenerList[i](e);
+      promises.push(listenerList[i](e));
     }
   }
+  return Promise.all(promises);
 };
 
 /**
diff --git a/frontend-js/src/main/js/ServerConnector.js b/frontend-js/src/main/js/ServerConnector.js
index 1de30ae567a450ccb17a107e40b9a214e3950b58..8b1dc799ef11312a5bf6dff0947efdd916d9dcfe 100644
--- a/frontend-js/src/main/js/ServerConnector.js
+++ b/frontend-js/src/main/js/ServerConnector.js
@@ -906,7 +906,7 @@ ServerConnector.getReactions = function(reactionIds, projectId, columns) {
 ServerConnector.getAliases = function(aliasIds, projectId, columns) {
   var self = this;
   return new Promise(function(resolve, reject) {
-    self.getProjectId(projectId).then(function(result) {
+    return self.getProjectId(projectId).then(function(result) {
       projectId = result;
       return self.getToken();
     }).then(function(token) {
@@ -918,9 +918,7 @@ ServerConnector.getAliases = function(aliasIds, projectId, columns) {
         result.push(new Alias(array[i]));
       }
       resolve(result);
-    }).catch(function(exception){
-      reject(exception);
-    });
+    }).catch(reject);
   });
 };
 
diff --git a/frontend-js/src/main/js/gui/SearchPanel.js b/frontend-js/src/main/js/gui/SearchPanel.js
new file mode 100644
index 0000000000000000000000000000000000000000..f46d2ff97c50130feb31c8e0834c40fc940e6edf
--- /dev/null
+++ b/frontend-js/src/main/js/gui/SearchPanel.js
@@ -0,0 +1,355 @@
+"use strict";
+
+var Promise = require("bluebird");
+
+var Alias = require('../map/data/Alias');
+var Reaction = require('../map/data/Reaction');
+var logger = require('../logger');
+var Functions = require('../Functions');
+
+function SearchPanel(params) {
+  var self = this;
+
+  this.setElement(params.element);
+  this.setMap(params.customMap);
+
+  var searchDb = self.getMap().getOverlayByName('search');
+  if (searchDb === undefined) {
+    throw new Error("Cannot find search db overlay");
+  }
+  searchDb.addListener("onSearch", function() {
+    return self.refreshSearchResults();
+  });
+
+  this._tabIdCount = 0;
+}
+
+SearchPanel.prototype.setMap = function(map) {
+  this._map = map;
+};
+
+SearchPanel.prototype.getMap = function() {
+  return this._map;
+};
+
+SearchPanel.prototype.setElement = function(element) {
+  if (element === undefined) {
+    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");
+  }
+};
+
+SearchPanel.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;
+    }
+  }
+};
+
+SearchPanel.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;
+    }
+  }
+};
+
+SearchPanel.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;
+      }
+    }
+  }
+};
+
+SearchPanel.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;
+      }
+    }
+  }
+};
+
+SearchPanel.prototype.getElement = function() {
+  return this._element;
+};
+
+SearchPanel.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);
+  }
+};
+
+SearchPanel.prototype.refreshSearchResults = function() {
+  var self = this;
+  self.clearResults();
+  var searchDb = self.getMap().getOverlayByName('search');
+  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) {
+    for (var i = 0; i < queries.length; i++) {
+      self.addResultTab(queries[i], results[i]);
+    }
+  });
+};
+
+SearchPanel.prototype.addResultTab = function(query, elements) {
+  var tabId = "searchTab_" + 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;
+  navLi.appendChild(navLink);
+  if (query.name !== undefined) {
+    navLink.innerHTML = query.name;
+  }
+  navElement.appendChild(navLi);
+
+  var contentDiv = document.createElement("div");
+  contentDiv.className = contentClass;
+  contentDiv.id = tabId;
+
+  contentElement.appendChild(contentDiv);
+
+  var tableDiv = document.createElement("table");
+  tableDiv.className = "result-table";
+  contentDiv.appendChild(tableDiv);
+
+  for (var i = 0; i < elements.length; i++) {
+    var element = elements[i];
+    if (element instanceof Alias) {
+      tableDiv.appendChild(this.createAliasElement(element));
+    } else if (element instanceof Reaction) {
+      tableDiv.appendChild(this.createReactionElement(element));
+    } else {
+      throw new Error("Unknown element type: " + element.constructor.name);
+    }
+  }
+};
+
+SearchPanel.prototype.createReactionElement = function(reaction) {
+  var self = this;
+  var result = document.createElement("tr");
+  var td = document.createElement("td");
+  result.appendChild(td);
+  var div = document.createElement("div");
+  td.appendChild(div);
+
+  div.appendChild(createLabel("Reaction: " + reaction.getReactionId()));
+  var lineBreak = document.createElement("hr");
+  div.appendChild(lineBreak);
+
+  if (reaction.getModelId() != self.getMap().getId()) {
+    div.appendChild(createSubMapLink(reaction));
+  }
+  div.appendChild(createNewLine(3));
+
+  div.appendChild(createParamLine("Symbol: ", reaction.getSymbol()));
+  div.appendChild(createParamLine("Abbreviation: ", reaction.getAbbreviation()));
+  div.appendChild(createParamLine("Formula: ", reaction.getFormula()));
+  div.appendChild(createParamLine("Mechanical Confidence Score: ", reaction.getMechanicalConfidenceScore()));
+  div.appendChild(createParamLine("Lower Bound: ", reaction.getLowerBound()));
+  div.appendChild(createParamLine("Upper Bound: ", reaction.getUpperBound()));
+  div.appendChild(createParamLine("Gene Protein Reaction: ", reaction.getGeneProteinReaction()));
+  div.appendChild(createParamLine("Subsystem: ", reaction.getSubsystem()));
+  div.appendChild(createArrayParamLine("Synonyms: ", reaction.getSynonyms()));
+  div.appendChild(createParamLine("Description: ", reaction.getDescription()));
+  div.appendChild(createReactantsLine(reaction.getReactants()));
+  div.appendChild(createProductsLine(reaction.getProducts()));
+  div.appendChild(createModifiersLine(reaction.getModifiers()));
+  div.appendChild(createCandidates("Candidates: ", reaction.getOther('dataMining')));
+  div.appendChild(createAnnotations("Annotations: ", reaction.getReferences()));
+
+  return result;
+};
+
+function createLabel(value) {
+  var result = document.createElement("span");
+  result.innerHTML = value;
+  result.className = "searchDescriptionLabel";
+  return result;
+};
+
+function createLabelText(value) {
+  var result = document.createElement("span");
+  result.innerHTML = value;
+  return result;
+};
+
+function createSeparator() {
+  var result = document.createElement("hr");
+  return result;
+};
+
+function createNewLine(count) {
+  var result = document.createElement("p");
+  result.style.width = "10px";
+  if (count > 0) {
+    result.style.width = (count * 10) + "px";
+  }
+  return result;
+};
+
+function createParamLine(label, value) {
+  var result = document.createElement("div");
+  if (value !== undefined) {
+    result.appendChild(createLabel(label));
+    result.appendChild(createLabelText(value));
+    result.appendChild(createNewLine());
+  }
+  return result;
+};
+
+function createArrayParamLine(label, value) {
+  var result = document.createElement("div");
+  if (value !== undefined && value.length > 0) {
+    result.appendChild(createLabel(label));
+    result.appendChild(createLabelText(value.join(",")));
+    result.appendChild(createNewLine());
+  }
+  return result;
+};
+
+function createReactantsLine(label, value) {
+  var result = document.createElement("div");
+  if (value !== undefined && value.length > 0) {
+    for (var i = 0; i < value.length; i++) {
+      result.appendChild(createParamLine("Reactant: ", value[i]));
+    }
+  }
+  return result;
+};
+
+function createProductsLine(label, value) {
+  var result = document.createElement("div");
+  if (value !== undefined && value.length > 0) {
+    for (var i = 0; i < value.length; i++) {
+      result.appendChild(createParamLine("Product: ", value[i]));
+    }
+  }
+  return result;
+};
+
+function createModifiersLine(label, value) {
+  var result = document.createElement("div");
+  if (value !== undefined && value.length > 0) {
+    for (var i = 0; i < value.length; i++) {
+      result.appendChild(createParamLine("Modifier: ", value[i]));
+    }
+  }
+  return result;
+};
+
+function createPostTranslationalModifications(label, value) {
+  var result = document.createElement("div");
+  if (value !== undefined) {
+    throw new Error("Not implemented");
+  }
+  return result;
+};
+
+function createCandidates(label, value) {
+  var result = document.createElement("div");
+  if (value !== undefined) {
+    throw new Error("Not implemented");
+  }
+  return result;
+};
+
+function createChebiTree(label, value) {
+  var result = document.createElement("div");
+  if (value !== undefined) {
+    throw new Error("Not implemented");
+  }
+  return result;
+};
+
+function createAnnotations(label, value) {
+  var result = document.createElement("div");
+  if (value !== undefined && value.length > 0) {
+    throw new Error("Not implemented");
+  }
+  return result;
+};
+
+SearchPanel.prototype.createAliasElement = function(alias) {
+  var self = this;
+
+  var result = document.createElement("tr");
+  var td = document.createElement("td");
+  result.appendChild(td);
+  var div = document.createElement("div");
+  td.appendChild(div);
+
+  div.appendChild(createParamLine(alias.getType() + ": ", alias.getName()));
+
+  if (alias.getModelId() != self.getMap().getId()) {
+    div.appendChild(createSubMapLink(alias));
+  }
+  div.appendChild(createNewLine(3));
+
+  div.appendChild(createParamLine("Full name: ", alias.getFullName()));
+  div.appendChild(createParamLine("Symbol: ", alias.getSymbol()));
+  div.appendChild(createParamLine("Abbreviation: ", alias.getAbbreviation()));
+  div.appendChild(createParamLine("Formula: ", alias.getFormula()));
+  div.appendChild(createArrayParamLine("Former symbols: ", alias.getFormerSymbols()));
+  div.appendChild(createPostTranslationalModifications("Posttranslational modifications: ", alias
+      .getOther('posttranslationalModifications')));
+  div.appendChild(createParamLine("Charge: ", alias.getCharge()));
+  div.appendChild(createParamLine("Synonyms: ", alias.getSynonyms()));
+  div.appendChild(createLabelText(alias.getDescription()));
+  div.appendChild(createCandidates("Candidates: ", alias.getOther('dataMining')));
+  div.appendChild(createChebiTree("Chebi ontology: ", alias.getOther('chebiTree')));
+  div.appendChild(createAnnotations("Annotations: ", alias.getReferences()));
+
+  div.appendChild(createSeparator());
+
+  return result;
+};
+
+module.exports = SearchPanel;
diff --git a/frontend-js/src/main/js/map/data/Alias.js b/frontend-js/src/main/js/map/data/Alias.js
index 7b426ecc9bb3a51b205af31c8b770dd76dcff05c..595f683ddd23866ede0a3433aea2c6e2c453c81e 100644
--- a/frontend-js/src/main/js/map/data/Alias.js
+++ b/frontend-js/src/main/js/map/data/Alias.js
@@ -42,17 +42,18 @@ Alias.prototype.update = function(javaObject) {
   if (javaObject.name === undefined) {
     return;
   }
-  this.description = javaObject.notes;
-  this.type = javaObject.type;
-  this.symbol = javaObject.symbol;
-  this.fullName = javaObject.fullName;
-  this.abbreviation = javaObject.abbreviation;
-  this.formula = javaObject.formula;
-  this.name = javaObject.name;
-  this.synonyms = javaObject.synonyms;
-  this.formerSymbols = javaObject.formerSymbols;
-  this.references = javaObject.references;
-  this.other = javaObject.other;
+  this.setDescription(javaObject.notes);
+  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.setIsComplete(true);
 };
 
@@ -69,6 +70,48 @@ Alias.prototype.setId = function(id) {
   this.id = id;
 };
 
+Alias.prototype.getFormula = function() {
+  return this.formula;
+};
+
+Alias.prototype.setFormula = function(formula) {
+  this.formula = formula;
+};
+
+Alias.prototype.getDescription = function() {
+  return this.description;
+};
+
+Alias.prototype.setDescription = function(description) {
+  this.description = description;
+};
+
+Alias.prototype.getCharge = function() {
+  return this.charge;
+};
+
+Alias.prototype.setCharge = function(charge) {
+  this.charge = charge;
+};
+
+Alias.prototype.getFormerSymbols = function() {
+  return this.formerSymbols;
+};
+
+Alias.prototype.setFormerSymbols = function(formerSymbols) {
+  this.formerSymbols = formerSymbols;
+};
+
+Alias.prototype.getOther = function(type) {
+  if (this.other !== undefined) {
+    return this.other[type];
+  }
+};
+
+Alias.prototype.setOther = function(other) {
+  this.other = other;
+};
+
 /**
  * Returns model identifier where {@link Alias} is located.
  * 
@@ -110,10 +153,50 @@ Alias.prototype.getName = function() {
   return this.name;
 };
 
+Alias.prototype.setName = function(name) {
+  this.name = name;
+};
+
+Alias.prototype.getSynonyms = function() {
+  return this.synonyms;
+};
+
+Alias.prototype.setSynonyms = function(synonyms) {
+  this.synonyms = synonyms;
+};
+
+Alias.prototype.getReferences = function() {
+  return this.references;
+};
+
+Alias.prototype.setReferences = function(references) {
+  this.references = references;
+};
+
 Alias.prototype.getFullName = function() {
   return this.fullName;
 };
 
+Alias.prototype.setFullName = function(fullName) {
+  this.fullName = fullName;
+};
+
+Alias.prototype.getSymbol = function() {
+  return this.symbol;
+};
+
+Alias.prototype.setSymbol = function(symbol) {
+  this.symbol = symbol;
+};
+
+Alias.prototype.getAbbreviation = function() {
+  return this.abbreviation;
+};
+
+Alias.prototype.setAbbreviation = function(abbreviation) {
+  this.abbreviation = abbreviation;
+};
+
 Alias.prototype.setType = function(type) {
   this.type = type;
 };
diff --git a/frontend-js/src/main/js/map/data/MapModel.js b/frontend-js/src/main/js/map/data/MapModel.js
index c7370e29731556cb820e9eabfe38dca853eef454..5e1b1862397fd24fcc39d0dd4bdab93022547656 100644
--- a/frontend-js/src/main/js/map/data/MapModel.js
+++ b/frontend-js/src/main/js/map/data/MapModel.js
@@ -176,12 +176,12 @@ MapModel.prototype.getReactionById = function(id, complete) {
 
 MapModel.prototype.getCompleteReactionById = function(id) {
   var self = this;
-  return new Promise(function(resolve) {
+  return new Promise(function(resolve, reject) {
     if (self._reactions[id] instanceof Reaction && self._reactions[id].isComplete()) {
       resolve(self._reactions[id]);
     } else {
       var result;
-      ServerConnector.getReactions([id]).then(function(reactions){
+      return ServerConnector.getReactions([id]).then(function(reactions){
         if (self._reactions[id] === undefined) {
           self._reactions[id] = reactions[0];
         } else {
@@ -231,7 +231,7 @@ MapModel.prototype.getCompleteReactionById = function(id) {
           }
         }
         resolve(result);
-      });
+      }).catch(reject);
     }
   });
 };
@@ -601,4 +601,14 @@ MapModel.prototype._getLayouts = function() {
   return result;
 };
 
+MapModel.prototype.getByIdentifiedElement = function(ie, complete) {
+  if (ie.getType()==="ALIAS") {
+    return this.getAliasById(ie.getId(), complete);
+  } else if (ie.getType()==="REACTION") {
+    return this.getReactionById(ie.getId());
+  } else {
+    throw new Error("Unknown type: "+ie.getType(), complete);
+  }
+};
+
 module.exports = MapModel;
diff --git a/frontend-js/src/main/js/map/data/Reaction.js b/frontend-js/src/main/js/map/data/Reaction.js
index 395353c8195aec8a1a3d3b27ae97b9d89dc6a2c3..66a318fe0a32ebf25bf61d115148e81e16daf4ad 100644
--- a/frontend-js/src/main/js/map/data/Reaction.js
+++ b/frontend-js/src/main/js/map/data/Reaction.js
@@ -94,7 +94,19 @@ Reaction.prototype.update = function(javaObject) {
     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);
+  
   if (javaObject.reactants !== "") {
     this.setReactants(javaObject.reactants.split(","));
   } else {
@@ -128,6 +140,86 @@ Reaction.prototype.setReactionId = function(reactionId) {
   this._reactionId = reactionId;
 };
 
+Reaction.prototype.getSymbol = function() {
+  return this._symbol;
+};
+
+Reaction.prototype.setSymbol = function(symbol) {
+  this._symbol = symbol;
+};
+
+Reaction.prototype.getAbbreviation= function() {
+  return this._abbreviation;
+};
+
+Reaction.prototype.setAbbreviation= function(abbreviation) {
+  this._abbreviation = abbreviation;
+};
+
+Reaction.prototype.getFormula= function() {
+  return this._formula;
+};
+
+Reaction.prototype.setFormula = function(formula) {
+  this._formula = formula;
+};
+
+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.setSynonyms = function(synonyms) {
+  this._synonyms = synonyms;
+};
+
+Reaction.prototype.getSynonyms= function() {
+  return this._synonyms;
+};
+
+Reaction.prototype.setDescription = function(description) {
+  this._description = description;
+};
+
+Reaction.prototype.getDescription= function() {
+  return this._description;
+};
+
 Reaction.prototype.getReactants = function() {
   return this._reactants;
 };
@@ -160,4 +252,22 @@ Reaction.prototype.getModifiers = function() {
   return this._modifiers;
 };
 
+Reaction.prototype.getOther = function(type) {
+  if (this._other !== undefined) {
+    return this._other[type];
+  }
+};
+
+Reaction.prototype.setOther = function(other) {
+  this._other = other;
+};
+
+Reaction.prototype.getReferences = function() {
+  return this.references;
+};
+
+Reaction.prototype.setReferences = function(references) {
+  this.references = references;
+};
+
 module.exports = Reaction;
diff --git a/frontend-js/src/main/js/map/overlay/OverlayCollection.js b/frontend-js/src/main/js/map/overlay/OverlayCollection.js
index 0679d6731848bf35bceb7d69a7edc2864d4ccb99..91961f1123913f9cc7d27a75da4019b4d12123de 100644
--- a/frontend-js/src/main/js/map/overlay/OverlayCollection.js
+++ b/frontend-js/src/main/js/map/overlay/OverlayCollection.js
@@ -2,7 +2,9 @@
 
 var logger = require('../../logger');
 
+
 var IdentifiedElement = require('../data/IdentifiedElement');
+var ObjectWithListeners = require('../../ObjectWithListeners');
 
 /**
  * This class is responsible for collecting and updating markers found by
@@ -19,6 +21,8 @@ function OverlayCollection(params) {
   // map, name, allowSearchById, allowGeneralSearch
   var self = this;
 
+  ObjectWithListeners.call(this);
+
   if (params.map === undefined) {
     throw new Error("map param must be defined");
   }
@@ -38,6 +42,9 @@ function OverlayCollection(params) {
   this.getMap().registerSource(self);
 }
 
+OverlayCollection.prototype = Object.create(ObjectWithListeners.prototype);
+OverlayCollection.prototype.constructor = OverlayCollection;
+
 /**
  * Returns true if overlay allows to get general data for element.
  */
diff --git a/frontend-js/src/main/js/map/overlay/SearchDbOverlay.js b/frontend-js/src/main/js/map/overlay/SearchDbOverlay.js
index be7537e82691c7fe266dba0fd12823abe2526df3..d74644d48b3cc3e0c3296c65e936b856b97a149c 100644
--- a/frontend-js/src/main/js/map/overlay/SearchDbOverlay.js
+++ b/frontend-js/src/main/js/map/overlay/SearchDbOverlay.js
@@ -15,6 +15,7 @@ function SearchDbOverlay(params) {
   this.setIconType("marker");
   this.setIconStart(0);
   this._elementsByQuery = [];
+  this.registerListenerType('onSearch');
 }
 
 SearchDbOverlay.prototype = Object.create(OverlayCollection.prototype);
@@ -33,6 +34,17 @@ function encodeQuery(type, model, arg){
   }
 }
 
+SearchDbOverlay.prototype.getElementsByQuery = function(query) {
+  var self = this;
+  var elements = this._elementsByQuery[query];
+  var promises = [];
+  for (var i=0;i<elements.length;i++) {
+    var model = self.getMap().getSubmodelById(elements[0].getModelId()).getModel(); 
+    promises.push(model.getByIdentifiedElement(elements[i], true));
+  }
+  return Promise.all(promises);
+};
+
 SearchDbOverlay.prototype.searchByCoordinates = function(model, coordinates) {
   var self = this;
   return new Promise(function(resolve, reject) {
@@ -40,7 +52,9 @@ SearchDbOverlay.prototype.searchByCoordinates = function(model, coordinates) {
     self.setQueries([query]);
     
     if (self._elementsByQuery[query] !== undefined) {
-      resolve(self._elementsByQuery[query]);
+      return self.callListeners('onSearch').then(function(){
+        resolve(self._elementsByQuery[query]);
+      });
     } else {
       return ServerConnector.getClosestElementsByCoordinates({
         modelId:model.getId(), coordinates: coordinates, count: 1
@@ -54,11 +68,14 @@ SearchDbOverlay.prototype.searchByCoordinates = function(model, coordinates) {
             for (i=0;i<reactionElements.length;i++) {
               self._elementsByQuery[query].push(new IdentifiedElement(reactionElements[i]));
             }
-            resolve(self._elementsByQuery[query]);
-          }).catch(reject);
+          });
         } else {
-          resolve(self._elementsByQuery[query]);
+          return null;
         }
+      }).then(function(){
+        return self.callListeners('onSearch');
+      }).then(function(){
+        resolve(self._elementsByQuery[query]);
       }).catch(reject);
     }
   });
diff --git a/frontend-js/src/main/js/minerva.js b/frontend-js/src/main/js/minerva.js
index daf8c324d7ead1b1125344f751a08c11249dc0e0..e8b3f09083fca84b4227ed433d464cc517096183 100644
--- a/frontend-js/src/main/js/minerva.js
+++ b/frontend-js/src/main/js/minerva.js
@@ -6,6 +6,7 @@ var CommentDbOverlay = require('./map/overlay/CommentDbOverlay');
 var CustomMap = require('./map/CustomMap');
 var OverlayCollection = require('./map/overlay/OverlayCollection');
 var SearchDbOverlay = require('./map/overlay/SearchDbOverlay');
+var SearchPanel = require('./gui/SearchPanel');
 
 var OriginalGuiConnector = require('./GuiConnector');
 var OriginalServerConnector = require('./ServerConnector');
@@ -78,6 +79,12 @@ function create(params) {
         collection = new CommentDbOverlay(collectionParams);
       } else if (collectionParams.name === "search") {
         collection = new SearchDbOverlay(collectionParams);
+        
+        new SearchPanel({
+          element : document.getElementById("searchTab"),
+          customMap : result
+        });
+        
       } else {
         collection = new OverlayCollection(collectionParams);
       }
diff --git a/frontend-js/src/test/js/gui/SearchPanel-test.js b/frontend-js/src/test/js/gui/SearchPanel-test.js
new file mode 100644
index 0000000000000000000000000000000000000000..01299134c92c6dd43793cd241c689fcb802ecc52
--- /dev/null
+++ b/frontend-js/src/test/js/gui/SearchPanel-test.js
@@ -0,0 +1,52 @@
+"use strict";
+
+var Helper = require('../helper');
+
+require("../mocha-config.js");
+
+var SearchPanel = require('../../../main/js/gui/SearchPanel');
+
+var chai = require('chai');
+var assert = chai.assert;
+var logger = require('../logger');
+
+describe('SearchPanel', function() {
+
+
+  var helper;
+  before(function() {
+    helper = new Helper();
+  });
+
+  it('contructor', function() {
+    var div = helper.createSearchTab();
+    
+    var map = helper.createCustomMap();
+    var searchDbOverlay = helper.createSearchDbOverlay(map);
+
+    new SearchPanel({
+      element : div,
+      customMap : map
+    });
+    assert.equal(logger.getWarnings().length, 0);
+  });
+
+  it('on searchResults changed', function() {
+    var div = helper.createSearchTab();
+    var map = helper.createCustomMap();
+    map.getModel().setId(15781);
+    var searchDbOverlay = helper.createSearchDbOverlay(map);
+
+    new SearchPanel({
+      element : div,
+      customMap : map
+    });
+
+    return searchDbOverlay.searchByCoordinates(map.getModel(), new google.maps.Point(26547.33, 39419.29)).then(
+        function(results) {
+          assert.equal(logger.getWarnings().length, 0);
+          assert.ok(div.innerHTML.indexOf("Reaction") >= 0);
+        });
+  });
+
+});
diff --git a/frontend-js/src/test/js/helper.js b/frontend-js/src/test/js/helper.js
index b7001fdb649f1efc8c68648f3bc41556c887e091..d5ff0f4ca182520a168347d18cd543cc7a7b7670 100644
--- a/frontend-js/src/test/js/helper.js
+++ b/frontend-js/src/test/js/helper.js
@@ -22,6 +22,31 @@ function Helper() {
   this.idCounter = 1000000;
 }
 
+Helper.prototype.createSearchTab = function() {
+  var result = document.createElement("div");
+  result.id = "searchTab";
+  var searchQueryDiv = document.createElement("div");
+  searchQueryDiv.setAttribute("name", "searchQuery");
+  result.appendChild(searchQueryDiv);
+
+  var searchResultsDiv = document.createElement("div");
+  searchResultsDiv.setAttribute("name", "searchResults");
+  result.appendChild(searchResultsDiv);
+
+  var navDiv = document.createElement("ul");
+  navDiv.className = "nav nav-tabs";
+  navDiv.innerHTML = '<li class="active"><a href="#set1"/></li>';
+
+  var contentDiv = document.createElement("div");
+  contentDiv.className = "tab-content";
+  contentDiv.innerHTML = '<div class="tab-pane fade active in" id="set1"/>';
+
+  searchResultsDiv.appendChild(navDiv);
+  searchResultsDiv.appendChild(contentDiv);
+
+  return result;
+};
+
 Helper.prototype.createCommentDbOverlay = function(map) {
   var result = new CommentDbOverlay({
     map : map,
@@ -39,8 +64,6 @@ Helper.prototype.createSearchDbOverlay = function(map) {
   return result;
 };
 
-
-
 Helper.prototype.createDrugDbOverlay = function(map) {
   var result = this.createDbOverlay(map);
   result.setName('drug');
diff --git a/frontend-js/src/test/js/minerva-test.js b/frontend-js/src/test/js/minerva-test.js
index 7dc361355f18700a932a4c0c87d6b5b210d94436..9a9d865224b98f3d7c0b7a663167687bb97c1b45 100644
--- a/frontend-js/src/test/js/minerva-test.js
+++ b/frontend-js/src/test/js/minerva-test.js
@@ -17,6 +17,15 @@ describe('minerva global', function() {
     helper = new Helper();
   });
 
+  beforeEach(function() {
+    global.searchTab = helper.createSearchTab();
+    document.body.appendChild(global.searchTab);
+  });
+
+  afterEach(function() {
+    document.body.removeChild(global.searchTab);
+  });
+
   it('create', function() {
     var options = helper.createOptions();
 
@@ -29,9 +38,11 @@ describe('minerva global', function() {
   it("contructor with GET zoom param", function() {
     var options = helper.createCustomMapOptions();
     GuiConnector.getParams["zoom"] = "5";
-    return minerva.create(options).then(function() {
-      assert.equal(ServerConnector.getSessionData(options.getProject()).getZoomLevel(options.getProject().getModel()), 5);
-    });
+    return minerva.create(options).then(
+        function() {
+          assert.equal(ServerConnector.getSessionData(options.getProject()).getZoomLevel(
+              options.getProject().getModel()), 5);
+        });
   });
 
   it("contructor with GET coord param", function() {
@@ -46,7 +57,6 @@ describe('minerva global', function() {
     });
   });
 
-
   it('create with layout', function() {
 
     var project = helper.createProject();
@@ -82,7 +92,6 @@ describe('minerva global', function() {
     var project = helper.createProject();
     var map = helper.createGoogleMap();
 
-    
     var layout = helper.createLayout();
     layout.setInputDataAvailable(true);
     // disable upload of the data from server
@@ -126,7 +135,7 @@ describe('minerva global', function() {
       assert.ok(result);
     });
   });
-  
+
   it('create with search overlay', function() {
     var project = helper.createProject();
     project.getModel().setId(15781);
diff --git a/web/src/main/webapp/WEB-INF/components/map/map.xhtml b/web/src/main/webapp/WEB-INF/components/map/map.xhtml
index 5e386d8e3db0fb6432ab462fb28c38f15b1f131b..c5923d23abedf32f9ede94e41e5fab66b70c13c9 100644
--- a/web/src/main/webapp/WEB-INF/components/map/map.xhtml
+++ b/web/src/main/webapp/WEB-INF/components/map/map.xhtml
@@ -62,10 +62,6 @@
 		<h:inputHidden id="systemMaxColor" value="#{configurationMB.maxColor}"/>
 	</h:form>
 
- 	<h:form id="searchForm">
-			<p:remoteCommand name="_searchByCoord" actionListener="#{searchMB.mapClicked}" update=":tabView:mainForm:dTable :tabView:mainForm:searchText"/>
-	</h:form>
-
 	<h:form id="accessLightAliasForm">
 		<p:remoteCommand name="_retreiveLightAliases" actionListener="#{mapMB.retreiveLightAliases}" />
 	</h:form>
diff --git a/web/src/main/webapp/WEB-INF/components/map/missingConnectionDialog.xhtml b/web/src/main/webapp/WEB-INF/components/map/missingConnectionDialog.xhtml
index e07331ffac9846c89d56111fa733983202f2bbe9..051413b2b9f3a17b6f2af621c4f5e50360b60049 100644
--- a/web/src/main/webapp/WEB-INF/components/map/missingConnectionDialog.xhtml
+++ b/web/src/main/webapp/WEB-INF/components/map/missingConnectionDialog.xhtml
@@ -11,7 +11,7 @@
 			<h:panelGrid columns="1" cellpadding="5">	
 				<p:inputTextarea	id="removeContent"	label="content" />	
 				<f:facet name="footer">	
-					<p:commandButton id="removeConnectionButton" value="Remove" actionListener="#{searchMB.removeConnection}"	onsuccess="dlg4.hide()" update=":tabView:mainForm:dTable"/>	
+					<p:commandButton id="removeConnectionButton" value="Remove" actionListener="#{searchMB.removeConnection}"	onsuccess="dlg4.hide()"/>	
 					<p:commandButton id="cancelRemoveButton" value="Cancel" onclick="dlg4.hide()" />	
 				</f:facet>	
 			</h:panelGrid>	
@@ -21,7 +21,7 @@
 			<h:panelGrid columns="1" cellpadding="5">	
 				<p:inputTextarea	id="removeCommentContent"	label="content" />	
 				<f:facet name="footer">	
-					<p:commandButton id="removeCommentButton" value="Remove" actionListener="#{feedbackMB.removeComment}"	onsuccess="dlg5.hide()" update=":tabView:mainForm:dTable"/>	
+					<p:commandButton id="removeCommentButton" value="Remove" actionListener="#{feedbackMB.removeComment}"	onsuccess="dlg5.hide()"/>	
 					<p:commandButton id="cancelRemoveCommentButton" value="Cancel" onclick="dlg5.hide()" />	
 				</f:facet>	
 			</h:panelGrid>	
diff --git a/web/src/main/webapp/WEB-INF/components/map/searchPanel.xhtml b/web/src/main/webapp/WEB-INF/components/map/searchPanel.xhtml
index 7c0373385a87e05158cbb3a2062e932d6fc90906..6260990e38ebb114d5a873a520234a80b2744712 100644
--- a/web/src/main/webapp/WEB-INF/components/map/searchPanel.xhtml
+++ b/web/src/main/webapp/WEB-INF/components/map/searchPanel.xhtml
@@ -6,11 +6,49 @@
 	xmlns:cc="http://java.sun.com/jsf/composite/pfcomp"
 	xmlns:p="http://primefaces.org/ui">
 
+<h:outputStylesheet library="css" name="global.css"	/>
 <h:outputStylesheet library="css" name="search.css"	/>
-	
-<h:form id="mainForm" class="searchPanel" >
+				
+<div id="searchTab">
+	<div name="searchQuery" class="searchPanel">	
+				<table cellpadding="4" style="width:100%">
+								<tbody>
+												<tr>
+																<td>SEARCH:</td>
+												</tr>
+												<tr>
+																<td>
+																		<input id="searchTextInput" class="input-field"/>
+																</td>
+																<td>
+																		<a id="searchButton" href="#">
+																						<img src="resources/images/icons/search.png"/>
+																		</a>
+																</td>
+												</tr>
+												<tr>
+																<td>
+																		<input id="perfectMatchInput" type="checkbox"/>
+																		<span>PERFECT MATCH</span>
+																</td>
+												</tr>
+								</tbody>
+				</table>
+	</div>
+
+	<div name="searchResults" class="tabbable boxed parentTabs">
+    <ul class="nav nav-tabs">
+        <li class="active"><a href="#set1"/></li>
+    </ul>
+    <div class="tab-content">
+        <div class="tab-pane fade active in" id="set1">
+				</div>
+    </div>
+	</div>
+</div>
 
-<!-- Search text box -->
+<!--
+	
 	<h:panelGrid columns="2" cellpadding="4" style="width:100%">	
 		<h:outputText value="SEARCH: "/>
 		<cc:helpButton helpText="search tab allows to search for particular elements or interactions in the map&lt;p&gt;perfect match tick box active: only terms with an exact match to the query will be returned&lt;p&gt;separate multiple search by semicolon" style="float:right;margin-top:-26px;margin-right:-20px;"/> 
@@ -29,7 +67,7 @@
 	<h:outputText value="PERFECT MATCH" style="font-size:13px; vertical-align:top; line-height:24px; padding-left:8px;"/>	
 		
 		
-<!-- results left panel -->
+<! - - results left panel - - >
 	<div class="searchResultsDivClass">
 		<p:tabView id="dTable" styleClass="searchResultsDivClass2" value="#{searchMB.results}" var="result" > 
 			<p:tab >
@@ -42,14 +80,14 @@
   	  		  <p:column >
               <cc:aliasSearchElement element="#{element}" elementRendered="#{(element['class'].simpleName == 'FullAliasView')}"/>
               <cc:reactionSearchElement element="#{element}" elementRendered="#{(element['class'].simpleName == 'FullReactionView')}"/>
-<!--						<div style="float:right;">
+<! - -						<div style="float:right;">
 							<p:commandLink actionListener="#{feedbackMB.updateCommentList}" oncomplete="commentDialog.show();" id="commentResultButton" ajax="true" update=":feedbackForm:feedbackDialog">
 								<h:graphicImage library="images" name="icons/comment.png" id="commentResultIcon" styleClass="imageButton"/>
 								<f:param name="submodelId" value="#{searchRow.modelId}"/>
 								<f:param name="latCoord" value="#{searchRow.latlng.lat}"/>
 								<f:param name="lngCoord" value="#{searchRow.latlng.lng}"/>
 							</p:commandLink>
-            </div> -->
+            </div> - - >
 		    	  </p:column>
           </p:dataTable>
 			  </p:scrollPanel>
@@ -57,11 +95,7 @@
 		</p:tabView> 
 	</div>
 </h:form>
-<h:form id="_searchConnector">
-  <p:remoteCommand name="_refreshSearchOverlayCollection" actionListener="#{searchMB.refreshOverlayCollection}"/>
-	<p:remoteCommand name="_registerSearchOverlayCollection" actionListener="#{searchMB.registerOverlayCollection}"/>
-	<p:remoteCommand name="_clearSearchOverlayCollection" actionListener="#{searchMB.clear}" update=":tabView:mainForm:dTable :tabView:mainForm:searchText"/>
-</h:form>
 
+-->
 </html>
 
diff --git a/web/src/main/webapp/index.xhtml b/web/src/main/webapp/index.xhtml
index 7fe48e61ff52797e584c043a40a4a0d8cf8d7993..6431b0ebb5875907e84a860890c0bb099104d159 100644
--- a/web/src/main/webapp/index.xhtml
+++ b/web/src/main/webapp/index.xhtml
@@ -17,6 +17,9 @@
 	
 	<!-- Google Maps API version 3.20	-->
 	<script src="https://maps.google.com/maps/api/js?libraries=drawing&amp;v=3.22" type="text/javascript"/>
+
+	<script src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js" type="text/javascript"/>
+
 	
 	<link rel="shortcut icon" href="./resources/images/favicon.png" type="image/png" />
 
@@ -63,6 +66,7 @@ function initMap(){
 </h:head>
 <h:body onload="initMap();" >
 <h:outputStylesheet library="css" name="style.css"/>
+<h:outputStylesheet library="css" name="global.css"	/>
 <h:outputStylesheet library="css" name="pileup.css"/>
 <h:outputStylesheet library="css" name="bootstrap.min.css"/>
 
diff --git a/web/src/main/webapp/resources/css/global.css b/web/src/main/webapp/resources/css/global.css
new file mode 100644
index 0000000000000000000000000000000000000000..00c008f0697f6fa47befc8fc418f9d42d60f4175
--- /dev/null
+++ b/web/src/main/webapp/resources/css/global.css
@@ -0,0 +1,30 @@
+.input-field {
+	background-color: #21BDF1;
+	color: #ffffff;
+	width: 210px;
+	box-shadow: none;
+	-moz-box-shadow: none;
+	-webkit-box-shadow: none;
+	font-size: 14px;
+	font-weight: 900;
+	padding: 8px;
+	font-family: Lato;
+	margin: 0;
+	border: none
+}
+
+.chkbox {
+	width: 16px;
+	height: 16px;
+	display: inline-block;
+	-moz-border-radius: 0px;
+	-webkit-border-radius: 0px;
+	border-radius: 0px;
+}
+
+.result-table {
+	width: 100%;
+	border-spacing: 2px;
+	-webkit-border-horizontal-spacing: 2px;
+	-webkit-border-vertical-spacing: 2px;
+}
\ No newline at end of file