diff --git a/frontend-js/src/main/js/ServerConnector.js b/frontend-js/src/main/js/ServerConnector.js
index 5dd2d408f4a7fb33a12f4d421890f80d4cee6ebe..a09ffb94f0f06043855c2276e63b96fffcfa6f09 100644
--- a/frontend-js/src/main/js/ServerConnector.js
+++ b/frontend-js/src/main/js/ServerConnector.js
@@ -1194,7 +1194,9 @@ ServerConnector.getOverlayById = function (overlayId, projectId) {
 
 ServerConnector.getReactions = function (params) {
   var self = this;
-  var queryParams = {};
+  var queryParams = {
+    modelId: params.modelId
+  };
   if (params.ids === undefined) {
     params.ids = [];
   }
diff --git a/frontend-js/src/main/js/gui/PluginDialog.js b/frontend-js/src/main/js/gui/PluginDialog.js
index 1133b62a4c9bd5849860dc7fe009fe00d623beba..fd351bac1583f542de07b0ec827cf139b45bf52f 100644
--- a/frontend-js/src/main/js/gui/PluginDialog.js
+++ b/frontend-js/src/main/js/gui/PluginDialog.js
@@ -1,7 +1,4 @@
 "use strict";
-var Promise = require('bluebird');
-
-
 var AbstractGuiElement = require('./AbstractGuiElement');
 var GuiConnector = require('../GuiConnector');
 var GuiUtils = require('./leftPanel/GuiUtils');
@@ -56,12 +53,10 @@ PluginDialog.prototype._createPluginGui = function () {
   var pluginManager = self.getPluginManager();
 
   var loadedPlugins = [];
-  var processedPlugins = [];
   var plugins = pluginManager.getPlugins();
   var i;
   for (i = 0; i < plugins.length; i++) {
     loadedPlugins[plugins[i].getOptions().url] = true;
-    processedPlugins[plugins[i].getOptions().url] = false;
   }
 
   for (i = 0; i < self._knownPlugins.length; i++) {
@@ -75,23 +70,7 @@ PluginDialog.prototype._createPluginGui = function () {
     });
     pluginUrl.readOnly = true;
     var button;
-    if (loadedPlugins[url]) {
-      button = Functions.createElement({
-        type: "button",
-        content: "UNLOAD",
-        onclick: function () {
-          var promises = [];
-          for (var i = 0; i < plugins.length; i++) {
-            if (plugins[i].getOptions().url === $(this).data("url")) {
-              promises.push(pluginManager.removePlugin(plugins[i]));
-            }
-          }
-          return Promise.all(promises).then(function () {
-            self.close();
-          }).then(null, GuiConnector.alert);
-        }
-      });
-    } else {
+    if (!loadedPlugins[url]) {
       button = Functions.createElement({
         type: "button",
         content: "LOAD",
@@ -103,39 +82,33 @@ PluginDialog.prototype._createPluginGui = function () {
       });
     }
     $(button).data("url", url);
-    processedPlugins[url] = true;
 
     pluginFormTab.appendChild(guiUtils.createTableRow([Functions.createElement({type: "span"}), pluginUrl, button]));
   }
-  for (url in loadedPlugins) {
-    if (loadedPlugins.hasOwnProperty(url) && !processedPlugins[url]) {
-      pluginUrl = Functions.createElement({
-        type: "input",
-        value: url,
-        style: "color:#999999"
-      });
-      pluginUrl.readOnly = true;
-      button = Functions.createElement({
-        type: "button",
-        content: "UNLOAD",
-        onclick: function () {
-          var promises = [];
-          for (var i = 0; i < plugins.length; i++) {
-            if (plugins[i].getOptions().url === $(this).data("url")) {
-              promises.push(pluginManager.removePlugin(plugins[i]));
-            }
-          }
-          return Promise.all(promises).then(function () {
-            self.close();
-          }).then(null, GuiConnector.alert);
-        }
-      });
-
-      $(button).data("url", url);
+  for (i = 0; i < plugins.length; i++) {
+    var plugin = plugins[i];
+    var removePlugin = (function () {
+      var pluginToRemove = plugin;
+      return function () {
+        return pluginManager.removePlugin(pluginToRemove).then(function () {
+          self.close();
+        }).then(null, GuiConnector.alert);
+      }
+    })();
+    pluginUrl = Functions.createElement({
+      type: "input",
+      value: plugins[i].getOptions().url,
+      style: "color:#999999"
+    });
+    pluginUrl.readOnly = true;
+    button = Functions.createElement({
+      type: "button",
+      content: "UNLOAD",
+      onclick: removePlugin
+    });
 
-      pluginFormTab.appendChild(guiUtils.createTableRow([Functions.createElement({type: "span"}), pluginUrl, button]));
+    pluginFormTab.appendChild(guiUtils.createTableRow([Functions.createElement({type: "span"}), pluginUrl, button]));
 
-    }
   }
 };
 
@@ -173,8 +146,8 @@ PluginDialog.prototype.close = function () {
 PluginDialog.prototype.destroy = function () {
   var self = this;
   var div = self.getElement();
-  if ($(self.getElement()).hasClass("ui-dialog-content")) {
-    $(self.getElement()).dialog("destroy");
+  if ($(div).hasClass("ui-dialog-content")) {
+    $(div).dialog("destroy");
   }
 };
 
diff --git a/frontend-js/src/main/js/gui/leftPanel/GuiUtils.js b/frontend-js/src/main/js/gui/leftPanel/GuiUtils.js
index acc4f48ffd840bed390b80fe526c4903365cb9be..d6ebbb214bda55b40fb90e0bddb5ac6090dbe514 100644
--- a/frontend-js/src/main/js/gui/leftPanel/GuiUtils.js
+++ b/frontend-js/src/main/js/gui/leftPanel/GuiUtils.js
@@ -534,7 +534,7 @@ GuiUtils.prototype.createTab = function (params) {
   tabData.content.appendChild(contentDiv);
 
   $(contentDiv).css("overflow", "auto");
-  $(contentDiv).css("height", "calc(100vh - " + $(contentDiv).position().top + "px)");
+  $(contentDiv).css("height", "calc(100vh - " + $(contentDiv).offset().top + "px)");
 
   return {
     title: navLink,
diff --git a/frontend-js/src/main/js/map/data/MapModel.js b/frontend-js/src/main/js/map/data/MapModel.js
index 1e4e53b9f6ff0d03d8c6e9288c8078043b270ec9..000602857d2fa04286c5aa712fb26be8d9cbe6b4 100644
--- a/frontend-js/src/main/js/map/data/MapModel.js
+++ b/frontend-js/src/main/js/map/data/MapModel.js
@@ -746,7 +746,8 @@ MapModel.prototype.getReactionsForElements = function(elements, complete) {
 
   var result = [];
   return ServerConnector.getReactions({
-    participantId : ids,
+    modelId: self.getId(),
+    participantId : ids
   }).then(function(reactions) {
     result = reactions;
 
@@ -781,7 +782,7 @@ MapModel.prototype.getCompartments = function() {
     promise = ServerConnector.getAliases({
       columns : "id,bounds,modelId",
       type : "Compartment",
-      modelId : self.getId(),
+      modelId : self.getId()
     }).then(function(compartments) {
       self._compartments = [];
       for (var i = 0; i < compartments.length; i++) {
diff --git a/frontend-js/src/main/js/minerva.js b/frontend-js/src/main/js/minerva.js
index b2514003b69769e0fb3059dcebe9e361d3a492c5..71b007ad67a6e48c7b97fdd0b4538765c3c4668a 100644
--- a/frontend-js/src/main/js/minerva.js
+++ b/frontend-js/src/main/js/minerva.js
@@ -104,7 +104,7 @@ function createDivStructure(element) {
   var splitBar = functions.createElement({
     type: "div",
     name: "minerva-plugin-split-bar",
-    style: "width:5px;height:100%;clear: both;display: table-cell;vertical-align:top",
+    style: "width:5px;height:100%;clear: both;display: table-cell;vertical-align:top;border-left:1px dotted gray;cursor:col-resize",
     content: "&nbsp"
   });
   element.appendChild(splitBar);
@@ -206,7 +206,7 @@ function modifyParamsForTouchInterface(params) {
   return params;
 }
 
-function assignSplitBarHandler(customMap) {
+function assignSplitBarHandler(customMap, pluginManager) {
   var splitBar = $('[name="minerva-plugin-split-bar"]');
   var rightPanelDiv = $('[name="minerva-plugin-div"]');
   var mouseDownHandler = function (e) {
@@ -215,6 +215,7 @@ function assignSplitBarHandler(customMap) {
     var x = $("body").width() - e.pageX;
     $(rightPanelDiv).css("width", x);
     google.maps.event.trigger(customMap.getGoogleMap(), 'resize');
+    return pluginManager.callListeners("onResize");
   };
   $(splitBar).mousedown(function (e) {
     e.preventDefault();
@@ -260,8 +261,6 @@ function create(params) {
 
     customMap = new CustomMap(params);
 
-    assignSplitBarHandler(customMap);
-
 
     new DbOverlayCollection({
       map: customMap
@@ -279,6 +278,7 @@ function create(params) {
       configuration: params.getConfiguration()
     });
     leftPanel.setPluginManager(pluginManager);
+    assignSplitBarHandler(customMap, pluginManager);
 
     topMenu = new TopMenu({
       element: functions.getElementByName(element, "menuDiv"),
diff --git a/frontend-js/src/main/js/plugin/MinervaPluginProxy.js b/frontend-js/src/main/js/plugin/MinervaPluginProxy.js
index 59e9adb5876f52c70a4752bffd28d8c3646d68fc..7c3c39890d4fbc2f794b73206437b8203e94751d 100644
--- a/frontend-js/src/main/js/plugin/MinervaPluginProxy.js
+++ b/frontend-js/src/main/js/plugin/MinervaPluginProxy.js
@@ -236,15 +236,26 @@ function createProjectMap(options) {
       return map.getVisibleDataOverlays();
     },
     addListener: function (param) {
-      var dbOverlay = getOverlayByName(map, param.dbOverlayName);
+      var object = null;
+      var listenerWrapper = null;
+      if (param.dbOverlayName !== undefined) {
+        object = getOverlayByName(map, param.dbOverlayName);
+        listenerWrapper = function (e) {
+          return getFullElements(map, e.arg.identifiedElements).then(function (result) {
+            return param.callback(result);
+          });
+        };
+      } else if (param.object === "plugin") {
+        object = options.plugin;
+        listenerWrapper = function () {
+          return param.callback();
+        };
+      } else {
+        throw new Error("Invalid argument");
+      }
 
-      var listenerWrapper = function (e) {
-        return getFullElements(map, e.arg.identifiedElements).then(function (result) {
-          return param.callback(result);
-        });
-      };
-      dbOverlay.addListener(param.type, listenerWrapper);
-      listenersData.push({listener: param.callback, wrapper: listenerWrapper, object: dbOverlay, type: param.type});
+      object.addListener(param.type, listenerWrapper);
+      listenersData.push({listener: param.callback, wrapper: listenerWrapper, object: object, type: param.type});
     },
     removeListener: function (param) {
       var dbOverlay = getOverlayByName(map, param.dbOverlayName);
diff --git a/frontend-js/src/main/js/plugin/Plugin.js b/frontend-js/src/main/js/plugin/Plugin.js
index 960c24d71654c95fc9f0750b7a436edd0af86011..8b650459d264bfb185ccfb606ee2862cf156d23f 100644
--- a/frontend-js/src/main/js/plugin/Plugin.js
+++ b/frontend-js/src/main/js/plugin/Plugin.js
@@ -15,6 +15,7 @@ function Plugin(options) {
   var self = this;
   self.setOptions(options);
   self.registerListenerType("onUnload");
+  self.registerListenerType("onResize");
 }
 
 Plugin.prototype = Object.create(ObjectWithListeners.prototype);
@@ -59,7 +60,7 @@ Plugin.prototype.load = function () {
     var error = false;
     try {
       // noinspection JSUnusedLocalSymbols
-      var define = function (pluginFunction) {
+      var minervaDefine = function (pluginFunction) {
         try {
           if (typeof pluginFunction === "function") {
             pluginData = pluginFunction();
@@ -71,6 +72,7 @@ Plugin.prototype.load = function () {
             map: options.map,
             configuration: options.configuration,
             element: options.element,
+            plugin: self,
             pluginId: "plugin" + (pluginId++)
           });
           self.setLoadedPluginData(pluginData);
@@ -80,6 +82,7 @@ Plugin.prototype.load = function () {
           error = e;
         }
       };
+      content += "//# sourceURL=" + options.url;
       eval(content);
     } catch (e) {
       error = e;
@@ -91,6 +94,20 @@ Plugin.prototype.load = function () {
 
 };
 
+Plugin.prototype.getMinWidth = function () {
+  var result = 0;
+  var data = this.getLoadedPluginData();
+  if (data.minWidth !== undefined) {
+    var value = 0;
+    if (typeof data.minWidth === "function") {
+      value = parseInt(data.minWidth());
+    } else {
+      value = parseInt(data.minWidth);
+    }
+  }
+  return value;
+};
+
 Plugin.prototype.unload = function () {
   var self = this;
   return Promise.resolve().then(function () {
@@ -98,7 +115,7 @@ Plugin.prototype.unload = function () {
   }).then(function () {
     var removedListeners = self.getMinervaPluginProxy().project.map.removeAllListeners();
     if (removedListeners.length > 0) {
-      logger.warn("'"+self.getLoadedPluginData().getName() + "' plugin didn't remove all registered listeners");
+      logger.warn("'" + self.getLoadedPluginData().getName() + "' plugin didn't remove all registered listeners");
     }
     return self.callListeners("onUnload");
   }).then(function () {
diff --git a/frontend-js/src/main/js/plugin/PluginManager.js b/frontend-js/src/main/js/plugin/PluginManager.js
index 0ff0e7fe05a944676765ac61727e5325464a8ca1..354e94906bb647f77e35306de26f772e63291fea 100644
--- a/frontend-js/src/main/js/plugin/PluginManager.js
+++ b/frontend-js/src/main/js/plugin/PluginManager.js
@@ -7,8 +7,8 @@ var GuiConnector = require('../GuiConnector');
 
 var Promise = require("bluebird");
 
+// noinspection JSUnusedLocalSymbols
 var logger = require('../logger');
-var Functions = require('../Functions');
 
 
 function PluginManager(options) {
@@ -20,6 +20,15 @@ function PluginManager(options) {
   self.setConfiguration(options.configuration);
   self._plugins = [];
   self._pluginOnResizeHandlers = {};
+
+  self.registerListenerType("onResize");
+  self.addListener("onResize", function () {
+    var promises = [];
+    for (var i = 0; i < self._plugins.length; i++) {
+      promises.push(self._plugins[i].callListeners("onResize"));
+    }
+    return Promise.resolve(promises);
+  });
 }
 
 PluginManager.prototype = Object.create(ObjectWithListeners.prototype);
@@ -71,7 +80,7 @@ PluginManager.prototype.addPlugin = function (options) {
       configuration: self.getConfiguration(),
       map: self.getMap()
     });
-    plugin.addListener("onUnload", function(){
+    plugin.addListener("onUnload", function () {
       tabData.content.parentNode.removeChild(tabData.content);
       tabData.title.parentNode.parentNode.removeChild(tabData.title.parentNode);
     });
@@ -82,12 +91,14 @@ PluginManager.prototype.addPlugin = function (options) {
     const tab = $(tabData.content);
     tab.css('overflow', 'auto');
     var adjustHeight = function () {
-      tab.css('height', 'calc( 100vh - ' + tab.position().top + 'px )');
+      tab.css('height', 'calc( 100vh - ' + tab.offset().top + 'px )');
     };
 
     self._pluginOnResizeHandlers[plugin.getPluginId()] = adjustHeight;
     GuiConnector.addWindowResizeEvent(adjustHeight);
     adjustHeight();
+    return self.adjustMinWidth();
+  }).then(function () {
     return plugin;
   });
 };
@@ -98,9 +109,12 @@ PluginManager.prototype.createTabForPlugin = function () {
   var guiUtils = new GuiUtils(self.getConfiguration());
   if (tabData === undefined) {
     self.getElement().style.width = "300px";
+    self.getElement().style.maxWidth = "600px";
+    self.getElement().style.minWidth = "150px";
     self.getElement().style.height = "100%";
     self._tabData = guiUtils.createTabDiv({element: self.getElement(), id: "plugin_tab"});
     tabData = self._tabData;
+    $(tabData.content).css('position', 'relative');
   }
   return guiUtils.createTab({
     title: "",
@@ -108,6 +122,27 @@ PluginManager.prototype.createTabForPlugin = function () {
     tabData: tabData
   });
 };
+PluginManager.prototype.adjustMinWidth = function () {
+  var self = this;
+  var oldVal = self.getElement().style.minWidth;
+  var minWidth = 150;
+  var i;
+  for (i = 0; i < self._plugins.length; i++) {
+    var plugin = self._plugins[i];
+    var value = plugin.getMinWidth();
+    if (value > minWidth) {
+      minWidth = value;
+    }
+  }
+  var newVal = minWidth + "px";
+  self.getElement().style.minWidth = newVal;
+  if (newVal !== oldVal) {
+    return self.callListeners("onResize");
+  } else {
+    return Promise.resolve();
+  }
+};
+
 PluginManager.prototype.removePlugin = function (plugin) {
   var self = this;
   var found = false;
@@ -121,7 +156,9 @@ PluginManager.prototype.removePlugin = function (plugin) {
     return Promise.reject(new Error("Plugin not registered"));
   }
   GuiConnector.removeWindowResizeEvent(self._pluginOnResizeHandlers[plugin.getPluginId()]);
-  return plugin.unload();
+  return plugin.unload().then(function () {
+    return self.adjustMinWidth();
+  });
 };
 
 PluginManager.prototype.destroy = function () {
diff --git a/frontend-js/src/test/js/ServerConnector-test.js b/frontend-js/src/test/js/ServerConnector-test.js
index 754d45cfdcef8efcb6937c016ecb2edd9d1020c5..7b844e1e805d8a2e16a1a9bfec32bd3f9b3afd07 100644
--- a/frontend-js/src/test/js/ServerConnector-test.js
+++ b/frontend-js/src/test/js/ServerConnector-test.js
@@ -153,7 +153,7 @@ describe('ServerConnector', function () {
     var modelId = 15781;
     return ServerConnector.getImageDownloadUrl({
       modelId: modelId,
-      handlerClass: "lcsb.mapviewer.converter.graphics.PngImageGenerator",
+      handlerClass: "lcsb.mapviewer.converter.graphics.PngImageGenerator"
     }).then(function (url) {
       assert.ok(url);
       assert.ok(url.indexOf(modelId) >= 0);
@@ -165,7 +165,7 @@ describe('ServerConnector', function () {
     var modelId = 15781;
     return ServerConnector.getModelDownloadUrl({
       modelId: modelId,
-      handlerClass: "lcsb.mapviewer.converter.model.celldesigner.CellDesignerXmlParser",
+      handlerClass: "lcsb.mapviewer.converter.model.celldesigner.CellDesignerXmlParser"
     }).then(function (url) {
       assert.ok(url);
       assert.ok(url.indexOf(modelId) >= 0);
@@ -195,13 +195,13 @@ describe('ServerConnector', function () {
 
   it('removeOverlay', function () {
     return ServerConnector.removeOverlay({
-      overlayId: 17296,
+      overlayId: 17296
     });
   });
 
   it('removeComment', function () {
     return ServerConnector.removeComment({
-      commentId: 4290,
+      commentId: 4290
     });
   });
 
@@ -230,7 +230,7 @@ describe('ServerConnector', function () {
 
   it('getModelDownloadUrl', function () {
     return ServerConnector.getModelDownloadUrl({
-      backgroundOverlayId: "cv14081",
+      backgroundOverlayId: "cv14081"
     }).then(function (url) {
       assert.ok(url);
     });
@@ -305,16 +305,16 @@ describe('ServerConnector', function () {
 
   describe('returnUserOrSystemColor ', function () {
     it('user has empty color', function () {
-      var systemColor = {};
+      var systemColor = "0000FF";
       return ServerConnector.returnUserOrSystemColor("", Promise.resolve(systemColor)).then(function (result) {
-        assert.ok(result = systemColor);
+        assert.ok(255, result);
       });
     });
     it('user has defined color', function () {
-      var userColor = {};
-      var systemColor = {};
+      var userColor = "000001";
+      var systemColor = "000010";
       return ServerConnector.returnUserOrSystemColor(userColor, Promise.resolve(systemColor)).then(function (result) {
-        assert.ok(result = userColor);
+        assert.ok(1, result);
       });
     });
   });
diff --git a/frontend-js/src/test/js/gui/OptionsMenu-test.js b/frontend-js/src/test/js/gui/OptionsMenu-test.js
index 416b1dc307e4a4b85ca2d8d35b4f6617e5c5700a..58e741d7332de438f3e87227a410ec88150da3f9 100644
--- a/frontend-js/src/test/js/gui/OptionsMenu-test.js
+++ b/frontend-js/src/test/js/gui/OptionsMenu-test.js
@@ -47,5 +47,4 @@ describe('OptionsMenu', function () {
       return pluginManager.destroy();
     });
   });
-})
-;
+});
diff --git a/frontend-js/src/test/js/plugin/PluginManager-test.js b/frontend-js/src/test/js/plugin/PluginManager-test.js
index 61d8ac2df925f77b5b8f9fe3bceb686641a030e7..f37e2cfeee5c2c6e391f57eb9ca6e1ac156e8d09 100644
--- a/frontend-js/src/test/js/plugin/PluginManager-test.js
+++ b/frontend-js/src/test/js/plugin/PluginManager-test.js
@@ -7,6 +7,8 @@ require("../mocha-config");
 
 var Plugin = require('../../../main/js/plugin/Plugin');
 var PluginManager = require('../../../main/js/plugin/PluginManager');
+var ProxyAccessPlugin = require('./ProxyAccessPlugin');
+
 
 var logger = require('../logger');
 var assert = require('assert');
@@ -38,6 +40,27 @@ describe('PluginManager', function () {
         assert.equal(1, manager.getPlugins().length);
       });
     });
+    it('with min width', function () {
+      var manager = new PluginManager(createParams());
+      return manager.addPlugin({url: "./testFiles/plugin/min-width.js"}).then(function () {
+        assert.equal("200px", $(manager.getElement()).css("min-width"));
+      });
+    });
+    it('with onResize listener', function () {
+      var manager = new PluginManager(createParams());
+      var plugin = new ProxyAccessPlugin({});
+      var listenerCalled = false;
+      return manager.addPlugin(plugin).then(function () {
+        plugin.getMinervaPluginProxy().project.map.addListener({
+          object: "plugin", type: "onResize", callback: function () {
+            listenerCalled = true;
+          }
+        });
+        return manager.addPlugin({url: "./testFiles/plugin/min-width.js"});
+      }).then(function () {
+        assert.ok(listenerCalled);
+      });
+    });
     it('after removal', function () {
       var manager = new PluginManager(createParams());
       return manager.addPlugin({url: "./testFiles/plugin/empty.js"}).then(function (plugin) {
diff --git a/frontend-js/src/test/js/plugin/ProxyAccessPlugin.js b/frontend-js/src/test/js/plugin/ProxyAccessPlugin.js
index 1dfe2df922218b584fda055dd9b971c4c1ef1437..696549ef59ca79472fa1082f85f7ed6735fe1350 100644
--- a/frontend-js/src/test/js/plugin/ProxyAccessPlugin.js
+++ b/frontend-js/src/test/js/plugin/ProxyAccessPlugin.js
@@ -8,13 +8,17 @@ var Promise = require('bluebird');
 var logger = require('../logger');
 
 function ProxyAccessPlugin(options) {
+  Plugin.call(this);
 }
 
 ProxyAccessPlugin.prototype = Object.create(Plugin.prototype);
 ProxyAccessPlugin.prototype.constructor = ProxyAccessPlugin;
 
 ProxyAccessPlugin.prototype.setOptions = function (options) {
-  this.setMinervaPluginProxy(new MinervaPluginProxy(options));
+  if (options !== undefined) {
+    options.plugin = this;
+    this.setMinervaPluginProxy(new MinervaPluginProxy(options));
+  }
 };
 
 ProxyAccessPlugin.prototype.load = function () {
diff --git a/frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/reactions/participantId=329156,329157,329158,329159,329160,329161,329162,329163,329164,329165,329166,329167,329168,329169,329170,329171,329172,329173,329174,329175,329176,329177,329178,329179,329180,329181,329182,329183,329184,329185&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/15781/bioEntities/reactions/participantId=329156,329157,329158,329159,329160,329161,329162,329163,329164,329165,329166,329167,329168,329169,329170,329171,329172,329173,329174,329175,329176,329177,329178,329179,329180,329181,329182,329183,329184,329185&token=MOCK_TOKEN_ID&
similarity index 100%
rename from frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/reactions/participantId=329156,329157,329158,329159,329160,329161,329162,329163,329164,329165,329166,329167,329168,329169,329170,329171,329172,329173,329174,329175,329176,329177,329178,329179,329180,329181,329182,329183,329184,329185&token=MOCK_TOKEN_ID&
rename to frontend-js/testFiles/apiCalls/projects/sample/models/15781/bioEntities/reactions/participantId=329156,329157,329158,329159,329160,329161,329162,329163,329164,329165,329166,329167,329168,329169,329170,329171,329172,329173,329174,329175,329176,329177,329178,329179,329180,329181,329182,329183,329184,329185&token=MOCK_TOKEN_ID&
diff --git a/frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/reactions/participantId=329167&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/15781/bioEntities/reactions/participantId=329167&token=MOCK_TOKEN_ID&
similarity index 100%
rename from frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/reactions/participantId=329167&token=MOCK_TOKEN_ID&
rename to frontend-js/testFiles/apiCalls/projects/sample/models/15781/bioEntities/reactions/participantId=329167&token=MOCK_TOKEN_ID&
diff --git a/frontend-js/testFiles/plugin-invalid/invalid_register.js b/frontend-js/testFiles/plugin-invalid/invalid_register.js
index f8b555f8c9aecccb91ace2d921e8964e8006ed11..607f1da2c32f227008e6e9c346d3ff580f499de2 100644
--- a/frontend-js/testFiles/plugin-invalid/invalid_register.js
+++ b/frontend-js/testFiles/plugin-invalid/invalid_register.js
@@ -1,4 +1,4 @@
-define(function () {
+minervaDefine(function () {
   return {
     register: function (object) {
       throw new Error("Let's crash");
diff --git a/frontend-js/testFiles/plugin-invalid/unclean-unregister.js b/frontend-js/testFiles/plugin-invalid/unclean-unregister.js
index a309c06a475b6ef5d444021d31eade224eea8e91..a7c00e2c55824505ed6740963cab18960fd29d72 100644
--- a/frontend-js/testFiles/plugin-invalid/unclean-unregister.js
+++ b/frontend-js/testFiles/plugin-invalid/unclean-unregister.js
@@ -1,4 +1,4 @@
-define(function () {
+minervaDefine(function () {
   return {
     register: function (minervaObject) {
       options = {
diff --git a/frontend-js/testFiles/plugin/empty-without-function.js b/frontend-js/testFiles/plugin/empty-without-function.js
index bafb6d13a6cf3b927941251b270111f11b70ffc2..e0b51b2161304fbaa3663e497b8f42deb0e8decb 100644
--- a/frontend-js/testFiles/plugin/empty-without-function.js
+++ b/frontend-js/testFiles/plugin/empty-without-function.js
@@ -1,4 +1,4 @@
-define({
+minervaDefine({
   register: function (object) {
     console.log("registering test plugin");
   },
diff --git a/frontend-js/testFiles/plugin/empty.js b/frontend-js/testFiles/plugin/empty.js
index a3fd24885e527b3933a46efdf362b82fbd403fbf..a8e14229f38ebf43e61642799887410b9a2364b3 100644
--- a/frontend-js/testFiles/plugin/empty.js
+++ b/frontend-js/testFiles/plugin/empty.js
@@ -1,4 +1,4 @@
-define(function () {
+minervaDefine(function () {
   return {
     register: function (object) {
       console.log("registering test plugin");
diff --git a/frontend-js/testFiles/plugin/highlight-something.js b/frontend-js/testFiles/plugin/highlight-something.js
index 985dec3860a6168245a2aa536fc3c15870438d95..be4c1edce0ed6594e08030917ac295713fb56194 100644
--- a/frontend-js/testFiles/plugin/highlight-something.js
+++ b/frontend-js/testFiles/plugin/highlight-something.js
@@ -1,4 +1,4 @@
-define(function () {
+minervaDefine(function () {
   return {
     register: function (minervaObject) {
       minervaObject.element.innerHTML = "<div><button id='show'>highlight something</button></div>";
diff --git a/frontend-js/testFiles/plugin/min-width.js b/frontend-js/testFiles/plugin/min-width.js
new file mode 100644
index 0000000000000000000000000000000000000000..6752a72ac12e72440fa02ebfc298762965bae2ef
--- /dev/null
+++ b/frontend-js/testFiles/plugin/min-width.js
@@ -0,0 +1,25 @@
+minervaDefine(function () {
+  return {
+    register: function (object) {
+      console.log("registering test plugin with min width");
+      object.project.map.addListener({
+        object: "plugin", type: "onResize", callback: function () {
+          console.log("Resize of plugin tab called");
+        }
+      });
+
+    },
+    unregister: function () {
+      console.log("unregistering test plugin");
+    },
+    getName: function () {
+      return "test plugin";
+    },
+    minWidth: function () {
+      return 200;
+    },
+    getVersion: function () {
+      return "0.0.1";
+    }
+  };
+});
\ No newline at end of file
diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/bioEntities/reactions/ReactionsRestImpl.java b/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/bioEntities/reactions/ReactionsRestImpl.java
index 276e9256cc39ca0e194e842316b157438e5c6a15..d8a8ed17ac8d9e7a93c5dfd817f5d74e295ad6da 100644
--- a/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/bioEntities/reactions/ReactionsRestImpl.java
+++ b/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/bioEntities/reactions/ReactionsRestImpl.java
@@ -28,167 +28,168 @@ import lcsb.mapviewer.services.search.data.LightReactionView;
 @Transactional(value = "txManager")
 public class ReactionsRestImpl extends BaseRestImpl {
 
-	/**
-	 * Default class logger.
-	 */
-	@SuppressWarnings("unused")
-	private Logger				logger = Logger.getLogger(ReactionsRestImpl.class);
-
-	@Autowired
-	private IUserService	userService;
-
-	@Autowired
-	private IModelService	modelService;
-
-	/**
-	 * @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 List<Map<String, Object>> getReactions(String projectId, String id, String columns, String modelId, String token, String participantElementId)
-			throws UserAccessException, SecurityException {
-		Model model = modelService.getLastModelByProjectId(projectId, userService.getToken(token));
-		Set<Integer> ids = new HashSet<>();
-		if (!id.equals("")) {
-			for (String str : id.split(",")) {
-				ids.add(Integer.valueOf(str));
-			}
-		}
-		Set<Element> elementSet = new HashSet<>();
-		if (!participantElementId.equals("")) {
-			for (String str : participantElementId.split(",")) {
-				elementSet.add(model.getElementByDbId(Integer.valueOf(str)));
-			}
-		}
-		Set<String> columnsSet = createReactionColumnSet(columns);
-
-		List<Map<String, Object>> result = new ArrayList<>();
-
-		List<Model> models = getModels(projectId, modelId, token);
-
-		for (Model model2 : models) {
-			for (Reaction reaction : model2.getReactions()) {
-				if (ids.size() == 0 || ids.contains(reaction.getId())) {
-					if (elementSet.size() == 0 || reactionContainsElement(reaction, elementSet)) {
-						result.add(preparedReaction(reaction, columnsSet));
-					}
-				}
-			}
-		}
-
-		return result;
-	}
-
-	private boolean reactionContainsElement(Reaction reaction, Set<Element> elementSet) {
-		for (Element element : elementSet) {
-			if (reaction.containsElement(element)) {
-				return true;
-			}
-		}
-		return false;
-	}
-
-	private Map<String, Object> preparedReaction(Reaction reaction, Set<String> columnsSet) {
-		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 = reaction.getId();
-			} else if (column.equals("modelid")) {
-				value = reaction.getModelData().getId();
-			} else if (column.equals("reactionid")) {
-				value = reaction.getIdReaction();
-			} else if (column.equals("name")) {
-				value = reaction.getName();
-			} else if (column.equals("centerpoint")) {
-				value = reaction.getCenterPoint();
-			} else if (column.equals("products")) {
-				List<Integer> ids = new ArrayList<>();
-				for (Product product : reaction.getProducts()) {
-					ids.add(product.getElement().getId());
-				}
-				value = StringUtils.join(ids, ",");
-			} else if (column.equals("reactants")) {
-				List<Integer> ids = new ArrayList<>();
-				for (Reactant reactant : reaction.getReactants()) {
-					ids.add(reactant.getElement().getId());
-				}
-				value = StringUtils.join(ids, ",");
-			} else if (column.equals("modifiers")) {
-				List<Integer> ids = new ArrayList<>();
-				for (Modifier product : reaction.getModifiers()) {
-					ids.add(product.getElement().getId());
-				}
-				value = StringUtils.join(ids, ",");
-			} else if (column.equals("type")) {
-				value = reaction.getStringType();
-			} else if (column.equals("hierarchyvisibilitylevel")) {
-				value = reaction.getVisibilityLevel();
-			} else if (column.equals("lines")) {
-				value = new LightReactionView(reaction).getLines();
-			} else if (column.equals("notes")) {
-				value = reaction.getNotes();
-			} else if (column.equals("references")) {
-				value = createAnnotations(reaction.getMiriamData());
-			} else {
-				value = "Unknown column";
-			}
-			result.put(string, value);
-		}
-		return result;
-	}
-
-	private Set<String> createReactionColumnSet(String columns) {
-		Set<String> columnsSet = new HashSet<>();
-		if (columns.equals("")) {
-			columnsSet.add("id");
-			columnsSet.add("reactionId");
-			columnsSet.add("modelId");
-			columnsSet.add("type");
-			columnsSet.add("lines");
-			columnsSet.add("centerPoint");
-			columnsSet.add("products");
-			columnsSet.add("reactants");
-			columnsSet.add("modifiers");
-			columnsSet.add("hierarchyVisibilityLevel");
-			columnsSet.add("references");
-			columnsSet.add("notes");
-		} else {
-			for (String str : columns.split(",")) {
-				columnsSet.add(str);
-			}
-		}
-		return columnsSet;
-	}
-
-	/**
-	 * @return the modelService
-	 * @see #modelService
-	 */
-	public IModelService getModelService() {
-		return modelService;
-	}
-
-	/**
-	 * @param modelService
-	 *          the modelService to set
-	 * @see #modelService
-	 */
-	public void setModelService(IModelService modelService) {
-		this.modelService = modelService;
-	}
+  /**
+   * Default class logger.
+   */
+  @SuppressWarnings("unused")
+  private Logger logger = Logger.getLogger(ReactionsRestImpl.class);
+
+  @Autowired
+  private IUserService userService;
+
+  @Autowired
+  private IModelService modelService;
+
+  /**
+   * @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 List<Map<String, Object>> getReactions(String projectId, String id, String columns, String modelId,
+      String token, String participantElementId) throws UserAccessException, SecurityException {
+    Set<Integer> ids = new HashSet<>();
+    if (!id.equals("")) {
+      for (String str : id.split(",")) {
+        ids.add(Integer.valueOf(str));
+      }
+    }
+    List<Model> models = getModels(projectId, modelId, token);
+
+    Set<Element> elementSet = new HashSet<>();
+    if (!participantElementId.equals("")) {
+      for (String str : participantElementId.split(",")) {
+        for (Model model : models) {
+          elementSet.add(model.getElementByDbId(Integer.valueOf(str)));
+        }
+      }
+    }
+    Set<String> columnsSet = createReactionColumnSet(columns);
+
+    List<Map<String, Object>> result = new ArrayList<>();
+
+    for (Model model2 : models) {
+      for (Reaction reaction : model2.getReactions()) {
+        if (ids.size() == 0 || ids.contains(reaction.getId())) {
+          if (elementSet.size() == 0 || reactionContainsElement(reaction, elementSet)) {
+            result.add(preparedReaction(reaction, columnsSet));
+          }
+        }
+      }
+    }
+
+    return result;
+  }
+
+  private boolean reactionContainsElement(Reaction reaction, Set<Element> elementSet) {
+    for (Element element : elementSet) {
+      if (reaction.containsElement(element)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  private Map<String, Object> preparedReaction(Reaction reaction, Set<String> columnsSet) {
+    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 = reaction.getId();
+      } else if (column.equals("modelid")) {
+        value = reaction.getModelData().getId();
+      } else if (column.equals("reactionid")) {
+        value = reaction.getIdReaction();
+      } else if (column.equals("name")) {
+        value = reaction.getName();
+      } else if (column.equals("centerpoint")) {
+        value = reaction.getCenterPoint();
+      } else if (column.equals("products")) {
+        List<Integer> ids = new ArrayList<>();
+        for (Product product : reaction.getProducts()) {
+          ids.add(product.getElement().getId());
+        }
+        value = StringUtils.join(ids, ",");
+      } else if (column.equals("reactants")) {
+        List<Integer> ids = new ArrayList<>();
+        for (Reactant reactant : reaction.getReactants()) {
+          ids.add(reactant.getElement().getId());
+        }
+        value = StringUtils.join(ids, ",");
+      } else if (column.equals("modifiers")) {
+        List<Integer> ids = new ArrayList<>();
+        for (Modifier product : reaction.getModifiers()) {
+          ids.add(product.getElement().getId());
+        }
+        value = StringUtils.join(ids, ",");
+      } else if (column.equals("type")) {
+        value = reaction.getStringType();
+      } else if (column.equals("hierarchyvisibilitylevel")) {
+        value = reaction.getVisibilityLevel();
+      } else if (column.equals("lines")) {
+        value = new LightReactionView(reaction).getLines();
+      } else if (column.equals("notes")) {
+        value = reaction.getNotes();
+      } else if (column.equals("references")) {
+        value = createAnnotations(reaction.getMiriamData());
+      } else {
+        value = "Unknown column";
+      }
+      result.put(string, value);
+    }
+    return result;
+  }
+
+  private Set<String> createReactionColumnSet(String columns) {
+    Set<String> columnsSet = new HashSet<>();
+    if (columns.equals("")) {
+      columnsSet.add("id");
+      columnsSet.add("reactionId");
+      columnsSet.add("modelId");
+      columnsSet.add("type");
+      columnsSet.add("lines");
+      columnsSet.add("centerPoint");
+      columnsSet.add("products");
+      columnsSet.add("reactants");
+      columnsSet.add("modifiers");
+      columnsSet.add("hierarchyVisibilityLevel");
+      columnsSet.add("references");
+      columnsSet.add("notes");
+    } else {
+      for (String str : columns.split(",")) {
+        columnsSet.add(str);
+      }
+    }
+    return columnsSet;
+  }
+
+  /**
+   * @return the modelService
+   * @see #modelService
+   */
+  public IModelService getModelService() {
+    return modelService;
+  }
+
+  /**
+   * @param modelService
+   *          the modelService to set
+   * @see #modelService
+   */
+  public void setModelService(IModelService modelService) {
+    this.modelService = modelService;
+  }
 
 }
diff --git a/web/src/main/webapp/resources/js/plugins/empty.js b/web/src/main/webapp/resources/js/plugins/empty.js
deleted file mode 100644
index a3fd24885e527b3933a46efdf362b82fbd403fbf..0000000000000000000000000000000000000000
--- a/web/src/main/webapp/resources/js/plugins/empty.js
+++ /dev/null
@@ -1,16 +0,0 @@
-define(function () {
-  return {
-    register: function (object) {
-      console.log("registering test plugin");
-    },
-    unregister: function () {
-      console.log("unregistering test plugin");
-    },
-    getName: function () {
-      return "test plugin";
-    },
-    getVersion: function () {
-      return "0.0.1";
-    }
-  };
-});
\ No newline at end of file