diff --git a/frontend-js/src/main/js/plugin/MinervaPluginProxy.js b/frontend-js/src/main/js/plugin/MinervaPluginProxy.js
index 820bc0694b2e18de2982faecc7cacbe9f1caa74f..ea16e1ff7f1aa640da1dae33bc990f014576baa3 100644
--- a/frontend-js/src/main/js/plugin/MinervaPluginProxy.js
+++ b/frontend-js/src/main/js/plugin/MinervaPluginProxy.js
@@ -229,17 +229,43 @@ function createProjectMap(options) {
 
   map.registerDbOverlay(new UserDbOverlay({name: pluginId, map: map}));
 
+  var listenersData = [];
+
   return {
     getVisibleDataOverlays: function () {
       return map.getVisibleDataOverlays();
     },
     addListener: function (param) {
       var dbOverlay = getOverlayByName(map, param.dbOverlayName);
-      dbOverlay.addListener(param.type, function (e) {
+
+      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});
+    },
+    removeListener: function (param) {
+      var dbOverlay = getOverlayByName(map, param.dbOverlayName);
+      var indexToBeRemoved = -1;
+
+      for (var i = 0; i < listenersData.length; i++) {
+        var listenerData = listenersData[i];
+        if (listenerData.listener === param.callback &&
+          listenerData.object === dbOverlay &&
+          listenerData.type === param.type) {
+          indexToBeRemoved = i;
+        }
+      }
+      if (indexToBeRemoved === -1) {
+        throw new Error("Listener doesn't exist");
+      }
+      var listenerWrapper = listenersData[indexToBeRemoved].wrapper;
+
+      dbOverlay.removeListener(param.type, listenerWrapper);
+
+      listenersData.splice(indexToBeRemoved, 1);
     },
     getHighlightedBioEntities: function (dbOverlayName) {
       if (dbOverlayName === undefined) {
diff --git a/frontend-js/src/test/js/plugin/MinervaPluginProxy-test.js b/frontend-js/src/test/js/plugin/MinervaPluginProxy-test.js
index 4efd86fa13ce3270df6820880f82e42a0a2d020d..71339d6b563a62b35396604fd89ffa91fcc0c659 100644
--- a/frontend-js/src/test/js/plugin/MinervaPluginProxy-test.js
+++ b/frontend-js/src/test/js/plugin/MinervaPluginProxy-test.js
@@ -73,6 +73,59 @@ describe('MinervaPluginProxy', function () {
     });
   });
 
+  describe('removeListener', function () {
+    it('valid listener', function () {
+      var callbackOk = false;
+      var map, options;
+      return ServerConnector.getProject().then(function (project) {
+        map = helper.createCustomMap(project);
+        helper.createSearchDbOverlay(map);
+        var proxy = createProxy(map);
+
+        options = {
+          dbOverlayName: "search",
+          type: "onSearch",
+          callback: function (elements) {
+            assert.ok(elements.length > 0);
+            assert.ok(elements[0].length !== undefined, "Array of arrays expected as onSearch result");
+            callbackOk = true;
+          }
+        };
+        proxy.project.map.addListener(options);
+        proxy.project.map.removeListener(options);
+        assert.equal(0, logger.getWarnings().length);
+        return map.destroy();
+      });
+    });
+    it('unknown listener', function () {
+      var callbackOk = false;
+      var map, options;
+      return ServerConnector.getProject().then(function (project) {
+        map = helper.createCustomMap(project);
+        helper.createSearchDbOverlay(map);
+        var proxy = createProxy(map);
+
+        options = {
+          dbOverlayName: "search",
+          type: "onSearch",
+          callback: function (elements) {
+            assert.ok(elements.length > 0);
+            assert.ok(elements[0].length !== undefined, "Array of arrays expected as onSearch result");
+            callbackOk = true;
+          }
+        };
+        proxy.project.map.addListener(options);
+        proxy.project.map.removeListener({});
+      }).then(function () {
+        assert.notOk("Exception expected");
+      }, function (error) {
+        assert.ok(error.message.indexOf("Listener doesn't exist") >= 0);
+
+        return map.destroy();
+      });
+    });
+  });
+
   describe("getBioEntityById", function () {
     it("for alias", function () {
       var map, proxy;