diff --git a/frontend-js/src/main/js/gui/ContextMenu.js b/frontend-js/src/main/js/gui/ContextMenu.js
index aa908487f6fdfe82678c2d5ec2d8d282821af027..018f787d2a4dfce5475dd3937cf28e96e340e59a 100644
--- a/frontend-js/src/main/js/gui/ContextMenu.js
+++ b/frontend-js/src/main/js/gui/ContextMenu.js
@@ -17,28 +17,30 @@ function ContextMenu(params) {
   var element = self.getElement();
   element.className = "dropdown-menu";
   element.setAttribute("role", "menu");
-  element.style.display = "none";
+  $(element).hide();
 
-  $('body').click(function() {
-    self.hide();
+  self._handledTimeStamp = undefined;
+
+  $('body').click(function (e) {
+    self.hide(e.timeStamp);
   });
 }
 
 ContextMenu.prototype = Object.create(AbstractGuiElement.prototype);
 ContextMenu.prototype.constructor = ContextMenu;
 
-ContextMenu.prototype.addOption = function(name, handler) {
+ContextMenu.prototype.addOption = function (name, handler) {
   var self = this;
   if (name instanceof SubMenu) {
     self.getElement().appendChild(name.getElement());
   } else {
     var option = Functions.createElement({
-      type : "li",
+      type: "li"
     });
     var link = Functions.createElement({
-      type : "a",
-      href : "#",
-      content : name,
+      type: "a",
+      href: "#",
+      content: name
     });
     $(link).data("handler", handler);
     option.appendChild(link);
@@ -46,14 +48,15 @@ ContextMenu.prototype.addOption = function(name, handler) {
   }
 };
 
-ContextMenu.prototype.open = function(x, y) {
+ContextMenu.prototype.open = function (x, y, timestamp) {
   var self = this;
-  var $menu = $(self.getElement()).show().css({
-    position : "absolute",
-    left : x,
-    top : y
-  }).off('click').on('click', 'a', function() {
-    $menu.hide();
+  self._handledTimeStamp = timestamp;
+  $(self.getElement()).show().css({
+    position: "absolute",
+    left: x,
+    top: y
+  }).off('click').on('click', 'a', function (e) {
+    self.hide(e.timeStamp);
     if ($(this).data("handler") !== undefined) {
       $(this).data("handler")();
     } else {
@@ -62,22 +65,12 @@ ContextMenu.prototype.open = function(x, y) {
   });
 };
 
-ContextMenu.prototype.getMenuPosition = function(mouse, direction, scrollDir) {
-  var win = $(window)[direction]();
-  var scroll = $(window)[scrollDir]();
-  var menu = $(this.getElement())[direction]();
-  var position = mouse + scroll;
-
-  // opening menu would pass the side of the page
-  if (mouse + menu > win && menu < mouse) {
-    position -= menu;
+ContextMenu.prototype.hide = function (timestamp) {
+  var self = this;
+  if (self._handledTimeStamp !== timestamp) {
+    self._handledTimeStamp = timestamp;
+    $(this.getElement()).hide();
   }
-
-  return position;
-};
-
-ContextMenu.prototype.hide = function() {
-  $(this.getElement()).hide();
 };
 
 function extractDataOverlayIds(dataOverlays) {
@@ -88,32 +81,32 @@ function extractDataOverlayIds(dataOverlays) {
   return ids;
 }
 
-ContextMenu.prototype.createExportAsImageSubmenu = function() {
+ContextMenu.prototype.createExportAsImageSubmenu = function () {
   var self = this;
-  return ServerConnector.getImageConverters().then(function(converters) {
+  return ServerConnector.getImageConverters().then(function (converters) {
     var li = Functions.createElement({
-      type : "li"
+      type: "li"
     });
     var submenu = new SubMenu({
-      element : li,
-      name : "Export as image",
-      customMap : self.getMap()
+      element: li,
+      name: "Export as image",
+      customMap: self.getMap()
     });
 
     var map = self.getMap();
-    converters.forEach(function(converter) {
-      submenu.addOption(converter.name, function() {
-        return map.getVisibleDataOverlays().then(function(visibleDataOverlays) {
+    converters.forEach(function (converter) {
+      submenu.addOption(converter.name, function () {
+        return map.getVisibleDataOverlays().then(function (visibleDataOverlays) {
 
           return ServerConnector.getImageDownloadUrl({
-            polygonString : map.getSelectedPolygon(),
-            modelId : map.getActiveSubmapId(),
-            handlerClass : converter.handler,
-            backgroundOverlayId : map.getGoogleMap().getMapTypeId(),
-            zoomLevel : map.getGoogleMap().getZoom(),
-            overlayIds : extractDataOverlayIds(visibleDataOverlays),
+            polygonString: map.getSelectedPolygon(),
+            modelId: map.getActiveSubmapId(),
+            handlerClass: converter.handler,
+            backgroundOverlayId: map.getGoogleMap().getMapTypeId(),
+            zoomLevel: map.getGoogleMap().getZoom(),
+            overlayIds: extractDataOverlayIds(visibleDataOverlays)
           });
-        }).then(function(url) {
+        }).then(function (url) {
           return self.downloadFile(url);
         }).then(null, GuiConnector.alert);
       });
@@ -122,31 +115,31 @@ ContextMenu.prototype.createExportAsImageSubmenu = function() {
   });
 };
 
-ContextMenu.prototype.createExportAsModelSubmenu = function() {
+ContextMenu.prototype.createExportAsModelSubmenu = function () {
   var self = this;
-  return ServerConnector.getModelConverters().then(function(converters) {
+  return ServerConnector.getModelConverters().then(function (converters) {
     var li = Functions.createElement({
-      type : "li"
+      type: "li"
     });
     var submenu = new SubMenu({
-      element : li,
-      name : "Export as map",
-      customMap : self.getMap()
+      element: li,
+      name: "Export as map",
+      customMap: self.getMap()
     });
 
     var map = self.getMap();
-    converters.forEach(function(converter) {
-      submenu.addOption(converter.name, function() {
-        return map.getVisibleDataOverlays().then(function(visibleDataOverlays) {
+    converters.forEach(function (converter) {
+      submenu.addOption(converter.name, function () {
+        return map.getVisibleDataOverlays().then(function (visibleDataOverlays) {
           return ServerConnector.getModelDownloadUrl({
-            polygonString : map.getSelectedPolygon(),
-            modelId : map.getActiveSubmapId(),
-            handlerClass : converter.handler,
-            backgroundOverlayId : map.getGoogleMap().getMapTypeId(),
-            zoomLevel : map.getGoogleMap().getZoom(),
-            overlayIds : extractDataOverlayIds(visibleDataOverlays),
+            polygonString: map.getSelectedPolygon(),
+            modelId: map.getActiveSubmapId(),
+            handlerClass: converter.handler,
+            backgroundOverlayId: map.getGoogleMap().getMapTypeId(),
+            zoomLevel: map.getGoogleMap().getZoom(),
+            overlayIds: extractDataOverlayIds(visibleDataOverlays)
           });
-        }).then(function(url) {
+        }).then(function (url) {
           return self.downloadFile(url);
         }).then(null, GuiConnector.alert);
       });
diff --git a/frontend-js/src/main/js/gui/Header.js b/frontend-js/src/main/js/gui/Header.js
index 318906298f5171774729c02346907b46399f45b4..d93dfccabe8c9b3d76ccf3c26c7f0fe251897ea5 100644
--- a/frontend-js/src/main/js/gui/Header.js
+++ b/frontend-js/src/main/js/gui/Header.js
@@ -3,117 +3,163 @@
 /* exported logger */
 
 var AbstractGuiElement = require('./AbstractGuiElement');
+var GuiConnector = require('../GuiConnector');
 var PanelControlElementType = require('./PanelControlElementType');
 var Functions = require('../Functions');
+var OptionsMenu = require('./OptionsMenu');
 
 var Promise = require("bluebird");
 
 var logger = require('../logger');
 
 function Header(params) {
-    AbstractGuiElement.call(this, params);
-    var self = this;
-
-    var guiParams = {
-        adminLink: true,
-    };
-    if (params.adminLink !== undefined) {
-        guiParams.adminLink = params.adminLink;
-    }
-
-    self._createHeaderGui(guiParams);
+  AbstractGuiElement.call(this, params);
+  var self = this;
+
+  var guiParams = {
+    adminLink: true,
+    optionsMenu: params.optionsMenu
+  };
+  if (params.adminLink !== undefined) {
+    guiParams.adminLink = params.adminLink;
+  }
+
+  self._createHeaderGui(guiParams);
 }
 
 Header.prototype = Object.create(AbstractGuiElement.prototype);
 Header.prototype.constructor = Header;
 
 Header.prototype._createHeaderGui = function (guiParams) {
-    var self = this;
-    self.getElement().className = "minerva-header";
+  var self = this;
+  self.getElement().className = "minerva-header";
+
+  var projectId = self.getProject().getProjectId();
+  var projectName = self.getProject().getName();
+
+  var loadingDiv = Functions.createElement({
+    type: "div",
+    style: "display:none; "
+  });
+  loadingDiv.style.float = "right";
+
+  var loadingImg = Functions.createElement({
+    type: "img",
+    src: 'resources/images/icons/ajax-loader.gif'
+  });
+  loadingImg.style.height = "35px";
+  loadingDiv.appendChild(loadingImg);
+  this.setControlElement(PanelControlElementType.FOOTER_LOADING_DIV, loadingDiv);
+
+  if (guiParams.adminLink) {
+    var link = Functions.createElement({
+      type: "a",
+      style: "padding-right:15px; float:right",
+      content: '<i class="fa fa-lock" style="font-size:17px"></i>&nbsp;'
+    });
+    link.href = ServerConnector.getServerBaseUrl() + "admin.xhtml?id=" + projectId;
+    self.getElement().appendChild(link);
+  }
+
+  if (guiParams.optionsMenu) {
+    var optionsElement = Functions.createElement({type: "ul"});
+    document.body.appendChild(optionsElement);
+    self._optionsMenu = new OptionsMenu({
+      customMap: self.getMap(),
+      element: optionsElement
+    });
 
-    var projectId = self.getProject().getProjectId();
-    var projectName = self.getProject().getName();
+    var menuLink = Functions.createElement({
+      type: "a",
+      style: "padding-right:5px; float:right",
+      content: '<i class="fa fa-bars" style="font-size:17px"></i>&nbsp;',
+      href: "#",
+      onclick: function (e) {
+        var link = $(menuLink);
+        var offset = link.offset();
 
-    var loadingDiv = Functions.createElement({
-        type: "div",
-        style: "display:none; ",
-    });
-    loadingDiv.style.float = "right";
+        var top = offset.top;
+        var left = offset.left;
 
-    var loadingImg = Functions.createElement({
-        type: "img",
-        src: 'resources/images/icons/ajax-loader.gif',
-    });
-    loadingImg.style.height = "35px";
-    loadingDiv.appendChild(loadingImg);
-    this.setControlElement(PanelControlElementType.FOOTER_LOADING_DIV, loadingDiv);
-
-    if (guiParams.adminLink) {
-        var link = Functions.createElement({
-            type: "a",
-            style: "padding-right:15px; float:right",
-            content: '<i class="fa fa-lock" style="font-size:17px"></i>&nbsp;',
-        });
-        link.href = ServerConnector.getServerBaseUrl() + "admin.xhtml?id=" + projectId;
-        self.getElement().appendChild(link);
-    }
-
-    self.getElement().appendChild(loadingDiv);
-
-    var homeLink = Functions.createElement({
-        type: "a",
-        content: '<i class="fa fa-home" style="font-size:17px"></i> ' + projectName,
+        var bottom = top + link.outerHeight();
+
+        return self._optionsMenu.open(left, bottom, e.timeStamp);
+      }
     });
-    homeLink.href = ServerConnector.getServerBaseUrl() + "?id=" + projectId;
-    self.getElement().appendChild(homeLink);
+    self.getElement().appendChild(menuLink);
+  }
+
+  self.getElement().appendChild(loadingDiv);
+
+  var homeLink = Functions.createElement({
+    type: "a",
+    content: '<i class="fa fa-home" style="font-size:17px"></i> ' + projectName
+  });
+  homeLink.href = ServerConnector.getServerBaseUrl() + "?id=" + projectId;
+  self.getElement().appendChild(homeLink);
 };
 
 Header.prototype.addLoadMessage = function (message) {
-    var self = this;
-    self._loadMessages.push(message);
+  var self = this;
+  self._loadMessages.push(message);
 };
 Header.prototype.removeLoadMessage = function (message) {
-    var self = this;
-    var index = self._loadMessages.indexOf(message);
-    if (index > -1) {
-        self._loadMessages.splice(index, 1);
-    } else {
-        logger.debug("Removing message that is not there: " + message);
-    }
+  var self = this;
+  var index = self._loadMessages.indexOf(message);
+  if (index > -1) {
+    self._loadMessages.splice(index, 1);
+  } else {
+    logger.debug("Removing message that is not there: " + message);
+  }
 };
 
 Header.prototype.init = function () {
-    var self = this;
-    return new Promise(function (resolve) {
-        var div = self.getControlElement(PanelControlElementType.FOOTER_LOADING_DIV);
-
-        self._loadMessages = [];
-        self._onDataLoadStart = function (e) {
-            self.addLoadMessage(e.arg);
-            div.style.display = "block";
-            div.title = e.arg;
-        };
-
-        self._onDataLoadStop = function (e) {
-            self.removeLoadMessage(e.arg);
-            if (self._loadMessages.length > 0) {
-                div.title = self._loadMessages[0];
-            } else {
-                div.style.display = "none";
-            }
-        };
-        ServerConnector.addListener("onDataLoadStart", self._onDataLoadStart);
-        ServerConnector.addListener("onDataLoadStop", self._onDataLoadStop);
-        resolve();
-    });
+  var self = this;
+  return new Promise(function (resolve) {
+    var div = self.getControlElement(PanelControlElementType.FOOTER_LOADING_DIV);
+
+    self._loadMessages = [];
+    self._onDataLoadStart = function (e) {
+      self.addLoadMessage(e.arg);
+      div.style.display = "block";
+      div.title = e.arg;
+    };
+
+    self._onDataLoadStop = function (e) {
+      self.removeLoadMessage(e.arg);
+      if (self._loadMessages.length > 0) {
+        div.title = self._loadMessages[0];
+      } else {
+        div.style.display = "none";
+      }
+    };
+    ServerConnector.addListener("onDataLoadStart", self._onDataLoadStart);
+    ServerConnector.addListener("onDataLoadStop", self._onDataLoadStop);
+    resolve();
+  });
 };
 
 Header.prototype.destroy = function () {
-    var self = this;
-    if (self._onDataLoadStart) {
-        ServerConnector.removeListener("onDataLoadStart", self._onDataLoadStart);
-        ServerConnector.removeListener("onDataLoadStop", self._onDataLoadStop);
-    }
+  var self = this;
+  if (self._onDataLoadStart) {
+    ServerConnector.removeListener("onDataLoadStart", self._onDataLoadStart);
+    ServerConnector.removeListener("onDataLoadStop", self._onDataLoadStop);
+  }
+  if (self._optionsMenu !== undefined) {
+    document.body.removeChild(self._optionsMenu.getElement());
+  }
+};
+
+Header.prototype.setPluginManager = function (pluginManager) {
+  var self = this;
+  self._pluginManager = pluginManager;
+  if (self._optionsMenu !== undefined) {
+    self._optionsMenu.setPluginManager(pluginManager);
+  }
+};
+
+Header.prototype.getPluginManager = function () {
+  return this._pluginManager;
 };
 
 module.exports = Header;
diff --git a/frontend-js/src/main/js/gui/LoginDialog.js b/frontend-js/src/main/js/gui/LoginDialog.js
index 428c527e41331879bbb6d13b95d65b2bfa9c7b62..7a652643d9157fc10d709381730bf9c0c7989d75 100644
--- a/frontend-js/src/main/js/gui/LoginDialog.js
+++ b/frontend-js/src/main/js/gui/LoginDialog.js
@@ -109,7 +109,7 @@ LoginDialog.prototype._createLoginTab = function () {
     type: "a",
     name: "requestAccount",
     content: "Request an account",
-    href: "#",
+    href: "#"
   }));
 
 };
@@ -128,7 +128,7 @@ LoginDialog.prototype.open = function () {
   if (!$(div).hasClass("ui-dialog-content")) {
     $(div).dialog({
       autoOpen: false,
-      resizable: false,
+      resizable: false
     });
   }
 
diff --git a/frontend-js/src/main/js/gui/OptionsMenu.js b/frontend-js/src/main/js/gui/OptionsMenu.js
new file mode 100644
index 0000000000000000000000000000000000000000..8302a9c5fe8c7be5e2e3f27077f1b56fe987c0b4
--- /dev/null
+++ b/frontend-js/src/main/js/gui/OptionsMenu.js
@@ -0,0 +1,56 @@
+"use strict";
+
+var ContextMenu = require('./ContextMenu');
+var PluginDialog = require('./PluginDialog');
+var Promise = require('bluebird');
+
+function OptionsMenu(params) {
+  ContextMenu.call(this, params);
+  var self = this;
+
+  self._createMenuGui();
+}
+
+OptionsMenu.prototype = Object.create(ContextMenu.prototype);
+OptionsMenu.prototype.constructor = OptionsMenu;
+
+
+OptionsMenu.prototype._createMenuGui = function () {
+  var self = this;
+  self.addOption("Plugins", function () {
+    var initPromise = Promise.resolve;
+    if (self._pluginDialog === undefined) {
+      self._pluginDialog = new PluginDialog({
+        element: document.createElement("div"),
+        customMap: self.getMap(),
+        pluginManager: self.getPluginManager()
+      });
+      initPromise = self._pluginDialog.init();
+    }
+    return initPromise.then(function () {
+      self._pluginDialog.open();
+    })
+  });
+};
+
+OptionsMenu.prototype.init = function () {
+  return Promise.resolve();
+};
+OptionsMenu.prototype.destroy = function () {
+  var self = this;
+  var promises = [];
+  if (self._pluginDialog !== undefined) {
+    promises.push(self._pluginDialog.destroy());
+  }
+  return Promise.all(promises);
+};
+
+OptionsMenu.prototype.setPluginManager = function (pluginManager) {
+  this._pluginManager = pluginManager;
+};
+
+OptionsMenu.prototype.getPluginManager = function () {
+  return this._pluginManager;
+};
+
+module.exports = OptionsMenu;
diff --git a/frontend-js/src/main/js/gui/PluginDialog.js b/frontend-js/src/main/js/gui/PluginDialog.js
new file mode 100644
index 0000000000000000000000000000000000000000..18ef1aba1f2b2f34eecc39f293e28d8706503d62
--- /dev/null
+++ b/frontend-js/src/main/js/gui/PluginDialog.js
@@ -0,0 +1,99 @@
+"use strict";
+var Promise = require('bluebird');
+
+
+var AbstractGuiElement = require('./AbstractGuiElement');
+var GuiConnector = require('../GuiConnector');
+var GuiUtils = require('./leftPanel/GuiUtils');
+
+var Functions = require('../Functions');
+
+function PluginDialog(params) {
+  AbstractGuiElement.call(this, params);
+  var self = this;
+  self._createPluginGui();
+  self.setPluginManager(params.pluginManager);
+
+}
+
+PluginDialog.prototype = Object.create(AbstractGuiElement.prototype);
+PluginDialog.prototype.constructor = PluginDialog;
+
+PluginDialog.prototype._createPluginGui = function () {
+  var self = this;
+  var guiUtils = new GuiUtils();
+
+  var pluginFormTab = Functions.createElement({
+    type: "div",
+    style: "width:100%;display: table;border-spacing: 10px;"
+  });
+  self.getElement().appendChild(pluginFormTab);
+
+  var pluginUrlLabel = Functions.createElement({
+    type: "span",
+    content: "URL:",
+    style: "color:#999999"
+  });
+  var pluginUrlInput = Functions.createElement({
+    type: "input",
+    name: "pluginUrlValue"
+  });
+  pluginFormTab.appendChild(guiUtils.createTableRow([pluginUrlLabel, pluginUrlInput]));
+
+  var centerTag = Functions.createElement({
+    type: "center"
+  });
+  self.getElement().appendChild(centerTag);
+
+  var loadPluginButton = Functions.createElement({
+    type: "button",
+    name: "loadPluginButton",
+    content: "LOAD PLUGIN"
+  });
+  centerTag.appendChild(loadPluginButton);
+  loadPluginButton.onclick = function () {
+    return self.getPluginManager().addPlugin({url: pluginUrlInput.value}).then(function () {
+      self.close();
+    }).then(null, GuiConnector.alert);
+  }
+
+};
+
+PluginDialog.prototype.init = function () {
+  return Promise.resolve();
+};
+
+PluginDialog.prototype.open = function () {
+  var self = this;
+  var div = self.getElement();
+  if (!$(div).hasClass("ui-dialog-content")) {
+    $(div).dialog({
+      autoOpen: false,
+      resizable: false
+    });
+  }
+
+  $(div).dialog('option', 'title', 'PLUGINS');
+  $(div).dialog("open");
+};
+PluginDialog.prototype.close = function () {
+  var self = this;
+  $(self.getElement()).dialog("close");
+};
+
+PluginDialog.prototype.destroy = function () {
+  var self = this;
+  if ($(self.getElement()).hasClass("ui-dialog-content")) {
+    $(self.getElement()).dialog("destroy");
+  }
+};
+
+PluginDialog.prototype.setPluginManager = function (pluginManager) {
+  this._pluginManager = pluginManager;
+};
+
+PluginDialog.prototype.getPluginManager = function () {
+  return this._pluginManager;
+};
+
+module.exports = PluginDialog;
diff --git a/frontend-js/src/main/js/gui/leftPanel/LeftPanel.js b/frontend-js/src/main/js/gui/leftPanel/LeftPanel.js
index 768b172362a75ea2f6f9d83df5976ec0de6f9c66..88848238989d4e3e578cc2996c85a7c600895309 100644
--- a/frontend-js/src/main/js/gui/leftPanel/LeftPanel.js
+++ b/frontend-js/src/main/js/gui/leftPanel/LeftPanel.js
@@ -44,7 +44,8 @@ LeftPanel.prototype._createPanelGui = function () {
   });
   var header = new Header({
     element: headerDiv,
-    customMap: self.getMap()
+    customMap: self.getMap(),
+    optionsMenu: true,
   });
   self.getElement().appendChild(headerDiv);
 
@@ -67,13 +68,12 @@ LeftPanel.prototype._createPanelGui = function () {
 
   self.setHeader(header);
 
-  var elementInfoDiv = Functions.createElement({
+  self.elementInfoDiv = Functions.createElement({
     name: "elementInfoDiv",
     type: "div",
     style: "background-color:#f3f3f3",
     className: "minerva-element-info-div"
   });
-  self.elementInfoDiv = elementInfoDiv;
 
   for (var i = 0; i < panels.length; i++) {
     self.addTab(panels[i], tabData);
@@ -283,6 +283,7 @@ LeftPanel.prototype.getLoginDialog = function () {
 
 LeftPanel.prototype.setPluginManager = function (pluginManager) {
   this._pluginManager = pluginManager;
+  this.getHeader().setPluginManager(pluginManager);
 };
 
 LeftPanel.prototype.getPluginManager = function () {
diff --git a/frontend-js/src/main/js/gui/leftPanel/ProjectInfoPanel.js b/frontend-js/src/main/js/gui/leftPanel/ProjectInfoPanel.js
index 977d2d1da1de9a9d63650cec03bf6436329b67d6..81c206085f06341c511c8e60d8e72375b1bdf442 100644
--- a/frontend-js/src/main/js/gui/leftPanel/ProjectInfoPanel.js
+++ b/frontend-js/src/main/js/gui/leftPanel/ProjectInfoPanel.js
@@ -20,7 +20,6 @@ function ProjectInfoPanel(params) {
   self._createInfoPanelLogic();
 
   self._createUserDataTab();
-  self._createPluginGui();
   var logoutButton = self.getControlElement(PanelControlElementType.USER_TAB_LOGOUT_BUTTON);
 
   logoutButton.onclick = function () {
@@ -329,54 +328,6 @@ ProjectInfoPanel.prototype._createUserDataTab = function () {
 
 };
 
-ProjectInfoPanel.prototype._createPluginGui = function () {
-  var self = this;
-  var guiUtils = self.getGuiUtils();
-  var pluginDataDiv = Functions.createElement({
-    type: "div",
-    className: "searchPanel"
-  });
-  self.getElement().appendChild(pluginDataDiv);
-
-  var pluginTitle = Functions.createElement({
-    type: "h3",
-    content: '<br/>Plugins<br/>'
-  });
-  pluginDataDiv.appendChild(pluginTitle);
-
-  var pluginFormTab = Functions.createElement({
-    type: "div",
-    style: "width:100%;display: table;border-spacing: 10px;"
-  });
-  pluginDataDiv.appendChild(pluginFormTab);
-
-  var pluginUrlLabel = Functions.createElement({
-    type: "span",
-    content: "URL:",
-    style: "color:#999999"
-  });
-  var pluginUrlInput = Functions.createElement({
-    type: "input",
-    name: "pluginUrlValue"
-  });
-  pluginDataDiv.appendChild(guiUtils.createTableRow([pluginUrlLabel, pluginUrlInput]));
-
-  var centerTag = Functions.createElement({
-    type: "center"
-  });
-  pluginDataDiv.appendChild(centerTag);
-
-  var logoutButton = Functions.createElement({
-    type: "button",
-    name: "loadPluginButton",
-    content: "LOAD PLUGIN"
-  });
-  centerTag.appendChild(logoutButton);
-  logoutButton.onclick = function () {
-    return self.getParent().getPluginManager().addPlugin({url: pluginUrlInput.value}).then(null, GuiConnector.alert);
-  }
-
-};
 
 ProjectInfoPanel.prototype.showUserProfilePage = function (user) {
 
diff --git a/frontend-js/src/main/js/map/AbstractCustomMap.js b/frontend-js/src/main/js/map/AbstractCustomMap.js
index c70194c0b84e2905dd6308a38c1c78eb21697b2c..2746a2973a215bca9d456dae973d620111695edd 100644
--- a/frontend-js/src/main/js/map/AbstractCustomMap.js
+++ b/frontend-js/src/main/js/map/AbstractCustomMap.js
@@ -369,7 +369,7 @@ AbstractCustomMap.prototype.registerMapClickEvents = function () {
 
   // context menu event
   google.maps.event.addListener(this.getGoogleMap(), 'rightclick', function () {
-    self.getTopMap().getContextMenu().open(GuiConnector.xPos, GuiConnector.yPos);
+    self.getTopMap().getContextMenu().open(GuiConnector.xPos, GuiConnector.yPos, new Date().getTime());
   });
 };
 
@@ -444,7 +444,7 @@ AbstractCustomMap.prototype.turnOnDrawing = function () {
 
         self.getTopMap().setSelectedPolygon(self.areaToString(newShape));
 
-        self.getTopMap().getSelectionContextMenu().open(GuiConnector.xPos, GuiConnector.yPos);
+        self.getTopMap().getSelectionContextMenu().open(GuiConnector.xPos, GuiConnector.yPos, new Date().getTime());
       });
     }
   });
diff --git a/frontend-js/src/main/js/map/TouchMap.js b/frontend-js/src/main/js/map/TouchMap.js
index c772a26dde1a0e4a38d4b66127abf12432e1daac..bdec92a6ce88a78baace48c665d1e5d0c6304a26 100644
--- a/frontend-js/src/main/js/map/TouchMap.js
+++ b/frontend-js/src/main/js/map/TouchMap.js
@@ -249,9 +249,9 @@ TouchMap.prototype.handleEnd = function (evt) {
     if (idx === self.firstFingerId && idx === self.lastStartedFinger && (dist < self.clickRange)) {
       var clickTime = (new Date().getTime() - self.lastStartedTime);
       if (clickTime < self.longClickTime) {
-        self.makeLeftClick(GuiConnector.xPos, GuiConnector.yPos);
+        self.makeLeftClick(GuiConnector.xPos, GuiConnector.yPos, evt.timeStamp);
       } else {
-        self.makeRightClick(GuiConnector.xPos, GuiConnector.yPos);
+        self.makeRightClick(GuiConnector.xPos, GuiConnector.yPos, evt.timeStamp);
       }
     }
     if (touches[i].identifier === self.firstFingerId) {
diff --git a/frontend-js/src/main/js/minerva.js b/frontend-js/src/main/js/minerva.js
index b46a387ec2750e0e2ebde038494a2ceecd4257cb..b2514003b69769e0fb3059dcebe9e361d3a492c5 100644
--- a/frontend-js/src/main/js/minerva.js
+++ b/frontend-js/src/main/js/minerva.js
@@ -209,18 +209,19 @@ function modifyParamsForTouchInterface(params) {
 function assignSplitBarHandler(customMap) {
   var splitBar = $('[name="minerva-plugin-split-bar"]');
   var rightPanelDiv = $('[name="minerva-plugin-div"]');
+  var mouseDownHandler = function (e) {
+    e.preventDefault();
+    //TODO should use global size (but element size)
+    var x = $("body").width() - e.pageX;
+    $(rightPanelDiv).css("width", x);
+    google.maps.event.trigger(customMap.getGoogleMap(), 'resize');
+  };
   $(splitBar).mousedown(function (e) {
     e.preventDefault();
-    $(document).mousemove(function (e) {
-      e.preventDefault();
-      //TODO should use global size (but element size)
-      var x = $("body").width() - e.pageX;
-      $(rightPanelDiv).css("width", x);
-      google.maps.event.trigger(customMap.getGoogleMap(), 'resize');
-    })
+    $(document).mousemove(mouseDownHandler);
   });
   $(document).mouseup(function (e) {
-    $(document).unbind('mousemove');
+    $(document).unbind('mousemove', mouseDownHandler);
   });
 }
 
@@ -262,7 +263,6 @@ function create(params) {
     assignSplitBarHandler(customMap);
 
 
-
     new DbOverlayCollection({
       map: customMap
     });
diff --git a/frontend-js/src/test/js/gui/Header-test.js b/frontend-js/src/test/js/gui/Header-test.js
index 481b4a1ff4633084cae4b4abab4fcbb79c342b8d..4d4b27fb812712b22358f79f6c2d1654f92e2c98 100644
--- a/frontend-js/src/test/js/gui/Header-test.js
+++ b/frontend-js/src/test/js/gui/Header-test.js
@@ -34,6 +34,18 @@ describe('Header', function() {
       assert.equal(logger.getWarnings().length, 0);
       assert.equal(0, $(".fa-lock", $(testDiv)).length);
     });
+    it('with options-link', function() {
+      var map = helper.createCustomMap();
+
+      var header = new Header({
+        element : testDiv,
+        customMap : map,
+        optionsMenu : true
+      });
+      assert.equal(logger.getWarnings().length, 0);
+      assert.equal(1, $(".fa-bars", $(testDiv)).length);
+      return header.destroy();
+    });
   });
 
   it('init', function() {
diff --git a/frontend-js/src/test/js/gui/MapContextMentu-test.js b/frontend-js/src/test/js/gui/MapContextMenu-test.js
similarity index 100%
rename from frontend-js/src/test/js/gui/MapContextMentu-test.js
rename to frontend-js/src/test/js/gui/MapContextMenu-test.js
diff --git a/frontend-js/src/test/js/gui/OptionsMenu-test.js b/frontend-js/src/test/js/gui/OptionsMenu-test.js
new file mode 100644
index 0000000000000000000000000000000000000000..0cabbe974b0416d716acaf4cd3a04b16efa16f08
--- /dev/null
+++ b/frontend-js/src/test/js/gui/OptionsMenu-test.js
@@ -0,0 +1,41 @@
+"use strict";
+
+/* exported logger */
+
+require("../mocha-config.js");
+
+var OptionsMenu = require('../../../main/js/gui/OptionsMenu');
+
+var chai = require('chai');
+var assert = chai.assert;
+var logger = require('../logger');
+
+describe('OptionsMenu', function () {
+
+  it('init', function () {
+    var map = helper.createCustomMap();
+
+    var menu = new OptionsMenu({
+      element: testDiv,
+      customMap: map
+    });
+    return menu.init();
+  });
+
+  it('open dialog', function () {
+    var map = helper.createCustomMap();
+
+    var menu = new OptionsMenu({
+      element: testDiv,
+      customMap: map
+    });
+    return menu.init().then(function () {
+      return menu.open(10, 10, 20);
+    }).then(function () {
+      return $("a", testDiv).trigger("click");
+    }).then(function () {
+      assert.equal(0, logger.getWarnings().length);
+      return menu.destroy();
+    });
+  });
+});
diff --git a/frontend-js/src/test/js/gui/SelectionContextMentu-test.js b/frontend-js/src/test/js/gui/SelectionContextMenu-test.js
similarity index 100%
rename from frontend-js/src/test/js/gui/SelectionContextMentu-test.js
rename to frontend-js/src/test/js/gui/SelectionContextMenu-test.js
diff --git a/frontend-js/src/test/js/minerva-test.js b/frontend-js/src/test/js/minerva-test.js
index 3be929789d6eeeb2b65c1f99fd82d8be15fe43a8..acff89f96bcd99f21b9df5f427a1e8eecea94886 100644
--- a/frontend-js/src/test/js/minerva-test.js
+++ b/frontend-js/src/test/js/minerva-test.js
@@ -65,15 +65,18 @@ describe('minerva global', function () {
 
   it("showComments", function () {
     var options = null;
+    var map ;
     return ServerConnectorMock.getProject().then(function (project) {
       options = helper.createCustomMapOptions(project);
       return minerva.create(options);
-    }).then(function () {
+    }).then(function (result) {
+      map = result;
       var commentCheckbox = document.getElementsByName("commentCheckbox")[0];
       commentCheckbox.checked = true;
       return commentCheckbox.onclick();
     }).then(function () {
       assert.ok(ServerConnectorMock.getSessionData(options.getProject()).getShowComments());
+      return map.destroy();
     });
   });
 
@@ -85,9 +88,10 @@ describe('minerva global', function () {
       return ServerConnectorMock.getProject().then(function (project) {
         options = helper.createCustomMapOptions(project);
         return minerva.create(options);
-      }).then(function () {
+      }).then(function (result) {
         var sessionData = ServerConnectorMock.getSessionData(options.getProject());
         assert.equal(sessionData.getZoomLevel(options.getProject().getModel()), 5);
+        return result.destroy();
       });
     });
 
@@ -97,11 +101,12 @@ describe('minerva global', function () {
       return ServerConnectorMock.getProject().then(function (project) {
         options = helper.createCustomMapOptions(project);
         return minerva.create(options);
-      }).then(function () {
+      }).then(function (result) {
         var center = ServerConnectorMock.getSessionData(options.getProject()).getCenter(options.getProject().getModel());
         assert.ok(center instanceof google.maps.Point);
         assert.equal(center.x, 5);
         assert.equal(center.y, 6);
+        return result.destroy();
       });
     });
 
@@ -118,7 +123,7 @@ describe('minerva global', function () {
   });
 
   it('create with layout', function () {
-    var layout, project, plugin;
+    var layout, project, plugin, map
     return ServerConnectorMock.getProject().then(function (result) {
       project = result;
       var options = helper.createCustomMapOptions(project);
@@ -132,6 +137,7 @@ describe('minerva global', function () {
 
       return minerva.create(options);
     }).then(function (result) {
+      map = result;
       assert.ok(result);
       // input file is not available so it's the background
       return plugin.getMinervaPluginProxy().project.map.getVisibleDataOverlays();
@@ -140,6 +146,7 @@ describe('minerva global', function () {
       assert.equal(visibleDataOverlays.length, 0);
       assert.equal(ServerConnectorMock.getSessionData(project).getSelectedBackgroundOverlay(), layout.getId());
       assert.equal(logger.getWarnings().length, 0);
+      return map.destroy();
     });
   });