diff --git a/CHANGELOG b/CHANGELOG
index cf80b16b0fec961e1a72a1f702e5faa7b181475b..7add9e01945b4afb6bd6cf94d3ff27b8aac1c711 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -11,6 +11,18 @@ minerva (12.1.0~alpha.0) experimental; urgency=medium
 
  -- Piotr Gawron <piotr.gawron@uni.lu>  Wed, 25 Jul 2018 10:00:00 +0200
 
+minerva (12.0.2) stable; urgency=medium
+  * Bug fix: data overlay by annotation type fixed
+  * Bug fix: [plugin] getting reactions with set of id larger than 100 elements
+    works properly
+  * Bug fix: name of commented protein was remembered for the new comment
+  * Bug fix: setting zoom level wasn't ranged and validated
+  * Bug fix: when uploading data overlay there is a warning regarding mixed new
+    line characters when necessary
+  * Performance: tomcat inside docker image by default can use 3G of memory
+
+ -- Piotr Gawron <piotr.gawron@uni.lu>  Tue, 31 Jul 2018 13:00:00 +0200
+
 minerva (12.0.1) stable; urgency=medium
   * Bug fix: setting default zoom level on submap
   * Bug fix: opened submap had different background then current selection
diff --git a/Docker/Dockerfile b/Docker/Dockerfile
index 4cfae15c6f7834c910b4ff29f530c7431777cca8..d5910e1a2cd48a2e3f0371aea69ad88cdcfba783 100644
--- a/Docker/Dockerfile
+++ b/Docker/Dockerfile
@@ -45,6 +45,7 @@ ADD policy-rc.d /tmp/policy-rc.d
 
 RUN apt-get update
 
+RUN sed -i "/JAVA_OPTS=\"-Djava.awt.headless=true -Xmx128m -XX:+UseConcMarkSweepGC\"/c\JAVA_OPTS=\"-Djava.awt.headless=true -Xmx3096m -XX:+UseConcMarkSweepGC\"" /etc/default/tomcat7
 
 #when we install minerva allow to start services, so everything can be installed properly
 #but we need to disable tomcat7 because tomcat7 requires SYS_PTRACE and we cannot start it:
diff --git a/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/ChebiAnnotator.java b/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/ChebiAnnotator.java
index cc2af5f03a65e73a088b803350be2885206ba860..5a673aa4b636c7f0122d662bddb9f471ec6b534b 100644
--- a/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/ChebiAnnotator.java
+++ b/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/ChebiAnnotator.java
@@ -27,7 +27,6 @@ import lcsb.mapviewer.model.map.MiriamType;
 import lcsb.mapviewer.model.map.species.Chemical;
 import lcsb.mapviewer.modelutils.map.ElementUtils;
 import uk.ac.ebi.chebi.webapps.chebiWS.client.ChebiWebServiceClient;
-import uk.ac.ebi.chebi.webapps.chebiWS.model.ChebiWebServiceFault_Exception;
 import uk.ac.ebi.chebi.webapps.chebiWS.model.DataItem;
 import uk.ac.ebi.chebi.webapps.chebiWS.model.Entity;
 import uk.ac.ebi.chebi.webapps.chebiWS.model.LiteEntity;
@@ -205,7 +204,7 @@ public class ChebiAnnotator extends ElementAnnotator implements IExternalService
           }
         }
       }
-    } catch (ChebiWebServiceFault_Exception e) {
+    } catch (Exception e) {
       throw new ChebiSearchException("Problem with chebi connection", e);
     }
     return null;
@@ -290,7 +289,7 @@ public class ChebiAnnotator extends ElementAnnotator implements IExternalService
       String value = miriamListToStringList(result);
 
       setCacheValue(query, value);
-    } catch (ChebiWebServiceFault_Exception e) {
+    } catch (Exception e) {
       throw new ChebiSearchException("Problem with chebi", e);
     }
     return result;
@@ -300,7 +299,7 @@ public class ChebiAnnotator extends ElementAnnotator implements IExternalService
    * Serialize list of chebi identifiers.
    * 
    * @param list
-   *          list of chebi identfiers
+   *          list of chebi identifiers
    * @return string with identifiers
    */
   private String miriamListToStringList(List<MiriamData> list) {
@@ -357,7 +356,6 @@ public class ChebiAnnotator extends ElementAnnotator implements IExternalService
     }
     try {
       ChebiWebServiceClient client = getClient();
-
       LiteEntityList entities = client.getLiteEntity(id, SearchCategory.CHEBI_ID, MAX_SEARCH_RESULTS_FROM_CHEBI_API,
           StarsCategory.ALL);
       List<LiteEntity> resultList = entities.getListElement();
@@ -374,7 +372,7 @@ public class ChebiAnnotator extends ElementAnnotator implements IExternalService
         setCacheValue("id: " + id, chebiSerializer.objectToString(result));
       }
       return result;
-    } catch (ChebiWebServiceFault_Exception e) {
+    } catch (Exception e) {
       throw new ChebiSearchException("Problem with chebi", e);
     }
   }
@@ -387,7 +385,7 @@ public class ChebiAnnotator extends ElementAnnotator implements IExternalService
    *          identifier): "CHEBI:XXXXX" or "XXXXX"
    * @return common name of chemical
    * @throws ChebiSearchException
-   *           thrown when there is a problemw ith accessing information from
+   *           thrown when there is a problem with accessing information from
    *           external chebi database
    */
   protected String getChebiNameForChebiId(MiriamData id) throws ChebiSearchException {
diff --git a/frontend-js/src/main/js/ServerConnector.js b/frontend-js/src/main/js/ServerConnector.js
index b5f1f91ffc246eb2d9cf8487c0c153f3420c1afb..d7a7c127f013f4f2097aa51c5fc61504d3ad2916 100644
--- a/frontend-js/src/main/js/ServerConnector.js
+++ b/frontend-js/src/main/js/ServerConnector.js
@@ -74,6 +74,7 @@ ServerConnector.init = function () {
     self.removeListener("onDataLoadStop", listeners[i]);
   }
 
+  self.MAX_NUMBER_OF_IDS_IN_GET_QUERY = 100;
 };
 ServerConnector.registerListenerType("onDataLoadStart");
 ServerConnector.registerListenerType("onDataLoadStop");
@@ -238,10 +239,19 @@ ServerConnector._sendRequest = function (params) {
  * @returns {Promise}
  */
 ServerConnector.sendPostRequest = function (url, params) {
+  var formParams = {};
+  for (var key in params) {
+    if (params.hasOwnProperty(key)) {
+      formParams[key] = this.objectToRequestString(params[key]);
+      if (formParams[key] === undefined) {
+        formParams[key] = params[key];
+      }
+    }
+  }
   return this.sendRequest({
     method: "POST",
     url: url,
-    form: params
+    form: formParams
   });
 };
 
@@ -289,6 +299,25 @@ ServerConnector.getServerBaseUrl = function () {
   return this._serverBaseUrl;
 };
 
+/**
+ *
+ * @param {Object} object
+ * @returns {string}
+ */
+ServerConnector.objectToRequestString = function (object) {
+  var value;
+  if (object instanceof Point) {
+    value = this.pointToString(object);
+  } else if (Object.prototype.toString.call(object) === '[object Array]') {
+    value = this.idsToString(object);
+  } else if (typeof object === 'string' || object instanceof String || !isNaN(object)) {
+    value = object.toString();
+  } else {
+    value = undefined;
+  }
+  return value;
+};
+
 ServerConnector.createGetParams = function (params, prefix) {
   var sorted = [], key;
 
@@ -306,18 +335,12 @@ ServerConnector.createGetParams = function (params, prefix) {
     if (prefix !== undefined) {
       key = prefix + "." + key;
     }
-    if (value instanceof Point) {
-      value = this.pointToString(value);
-    } else if (Object.prototype.toString.call(value) === '[object Array]') {
-      value = this.idsToString(value);
-    } else if (typeof value === 'string' || value instanceof String || !isNaN(value)) {
-    } else {
-      result += this.createGetParams(value, key);
-      value = undefined;
-    }
 
-    if (value !== undefined && value !== "") {
-      result += key + "=" + value + "&";
+    var serializedValue = this.objectToRequestString(value);
+    if (serializedValue === undefined) {
+      result += this.createGetParams(value, key);
+    } else if (serializedValue !== undefined && serializedValue !== "") {
+      result += key + "=" + serializedValue + "&";
     }
   }
   return result;
@@ -1513,6 +1536,15 @@ ServerConnector.getOverlayById = function (overlayId, projectId) {
   });
 };
 
+/**
+ *
+ * @param {number} [params.modelId]
+ * @param {number[]} [params.ids]
+ * @param {number[]} [params.participantId]
+ * @param {string[]} [params.columns]
+ * @param {string} [params.projectId]
+ * @returns {*}
+ */
 ServerConnector.getReactions = function (params) {
   var self = this;
   var queryParams = {
@@ -1531,7 +1563,7 @@ ServerConnector.getReactions = function (params) {
   };
   return self.getProjectId(params.projectId).then(function (result) {
     queryParams.projectId = result;
-    if (filterParams.id.length > 100 || filterParams.participantId.length > 100) {
+    if (filterParams.id.length > self.MAX_NUMBER_OF_IDS_IN_GET_QUERY || filterParams.participantId.length > self.MAX_NUMBER_OF_IDS_IN_GET_QUERY) {
       return self.sendPostRequest(self.getReactionsUrl(queryParams), filterParams);
     } else {
       return self.sendGetRequest(self.getReactionsUrl(queryParams, filterParams));
@@ -1571,7 +1603,7 @@ ServerConnector.getAliases = function (params) {
   };
   return self.getProjectId(params.projectId).then(function (result) {
     queryParams.projectId = result;
-    if (filterParams.id.length > 100) {
+    if (filterParams.id.length > self.MAX_NUMBER_OF_IDS_IN_GET_QUERY) {
       return self.sendPostRequest(self.getAliasesUrl(queryParams), filterParams);
     } else {
       return self.sendGetRequest(self.getAliasesUrl(queryParams, filterParams));
diff --git a/frontend-js/src/main/js/gui/AddOverlayDialog.js b/frontend-js/src/main/js/gui/AddOverlayDialog.js
index 497045042e7987b2dfe9674b8806d69ad4897ec8..c1ebf8a420f517009c356d065a73b9d95f8ae0fa 100644
--- a/frontend-js/src/main/js/gui/AddOverlayDialog.js
+++ b/frontend-js/src/main/js/gui/AddOverlayDialog.js
@@ -154,6 +154,10 @@ AddOverlayDialog.prototype.processFile = function (file) {
           if (overlay.getType() !== undefined) {
             typeSelect.val(overlay.getType());
           }
+          if (overlayParser.containsMixedNewLineCharacters(evt.target.result)) {
+            GuiConnector.warn("Selected file contains new line characters from different operating systems " +
+              "(MAC/Windows/Linux). This might cause confusion when reading the file in the editor later on.")
+          }
           resolve(self.getFileContent());
         } catch (error) {
           reject(error);
diff --git a/frontend-js/src/main/js/gui/CommentDialog.js b/frontend-js/src/main/js/gui/CommentDialog.js
index 4cfd4d4cd8b5f561cff3597d26997d3f7b32a57c..0ca87663084dad9a3f1217e80ac3c515b973a3dc 100644
--- a/frontend-js/src/main/js/gui/CommentDialog.js
+++ b/frontend-js/src/main/js/gui/CommentDialog.js
@@ -38,13 +38,13 @@ function createRow(elements) {
   return row;
 }
 
-CommentDialog.prototype.open = function (types) {
+CommentDialog.prototype.open = function (identifiedElements) {
   var self = this;
   self.setTypes([CommentDialog.GENERAL]);
 
   var promises = [CommentDialog.GENERAL];
-  for (var i = 0; i < types.length; i++) {
-    var ie = types[i];
+  for (var i = 0; i < identifiedElements.length; i++) {
+    var ie = identifiedElements[i];
     if (ie.getType() === "ALIAS") {
       promises.push(self.getMap().getSubmapById(ie.getModelId()).getModel().getAliasById(ie.getId(), true));
     } else if (ie.getType() === "REACTION") {
@@ -182,6 +182,7 @@ CommentDialog.prototype.setTypes = function (types) {
   typeOptions.value = 0;
 
   this._types = types;
+  typeOptions.onchange();
 };
 
 CommentDialog.prototype.getTypes = function () {
diff --git a/frontend-js/src/main/js/gui/admin/EditProjectDialog.js b/frontend-js/src/main/js/gui/admin/EditProjectDialog.js
index 4e1127816fd5763d179ea7f7d3d66bce21ae5b04..76286f728493369b9a42a301d4251a2d959e3595 100644
--- a/frontend-js/src/main/js/gui/admin/EditProjectDialog.js
+++ b/frontend-js/src/main/js/gui/admin/EditProjectDialog.js
@@ -114,7 +114,7 @@ EditProjectDialog.prototype.addTab = function (params) {
     navigationObject: navLi,
     navigationBar: params.tabMenuDiv
   });
-  $(contentDiv).css("overflow","auto");
+  $(contentDiv).css("overflow", "auto");
 
   if (params.content !== undefined) {
     contentDiv.appendChild(params.content);
@@ -821,7 +821,12 @@ function getValueOrEmpty(value) {
   }
 }
 
-EditProjectDialog.prototype.mapToTableRow = function (map, users) {
+/**
+ *
+ * @param {MapModel} map
+ * @returns {Array}
+ */
+EditProjectDialog.prototype.mapToTableRow = function (map) {
   var row = [];
   var id = map.getId();
   var centerX = getValueOrEmpty(map.getDefaultCenterX());
@@ -831,7 +836,17 @@ EditProjectDialog.prototype.mapToTableRow = function (map, users) {
   row[1] = map.getName();
   row[2] = "<input name='defaultCenterX-" + id + "' value='" + centerX + "'/>";
   row[3] = "<input name='defaultCenterY-" + id + "' value='" + centerY + "'/>";
-  row[4] = "<input name='defaultZoomLevel-" + id + "' value='" + zoomLevel + "'/>";
+  var zoomLevelSelect = "<select name='defaultZoomLevel-" + id + "' value='" + zoomLevel + "'>" +
+    "<option value=''>---</option>";
+  for (var i = map.getMinZoom(); i <= map.getMaxZoom(); i++) {
+    var selected = "";
+    if (i === zoomLevel) {
+      selected = " selected ";
+    }
+    zoomLevelSelect += "<option value='" + i + "' " + selected + ">" + (i - map.getMinZoom()) + "</option>";
+  }
+  zoomLevelSelect += "</select>";
+  row[4] = zoomLevelSelect;
   row[5] = "<button name='saveMap' data='" + id + "'><i class=\"fa fa-save\" style=\"font-size:17px\"></i></button>";
 
   return row;
@@ -921,8 +936,10 @@ EditProjectDialog.prototype.saveOverlay = function (overlayId) {
 EditProjectDialog.prototype.saveMap = function (mapId) {
   var self = this;
   var map = self._mapsById[mapId];
-  map.setDefaultCenterX($("[name='defaultCenterX-" + mapId + "']", self.getElement())[0].value);
-  map.setDefaultCenterY($("[name='defaultCenterY-" + mapId + "']", self.getElement())[0].value);
+  var centerX = parseInt($("[name='defaultCenterX-" + mapId + "']", self.getElement())[0].value);
+  var centerY = parseInt($("[name='defaultCenterY-" + mapId + "']", self.getElement())[0].value);
+  map.setDefaultCenterX(centerX);
+  map.setDefaultCenterY(centerY);
   map.setDefaultZoomLevel($("[name='defaultZoomLevel-" + mapId + "']", self.getElement())[0].value);
 
   return ServerConnector.updateModel({projectId: self.getProject().getProjectId(), model: map});
diff --git a/frontend-js/src/main/js/map/OverlayParser.js b/frontend-js/src/main/js/map/OverlayParser.js
index 320c0b936c4e09eedceea040c4c5f88e58eb7541..239de8d595203d790a3d6ec10662ce9c0c8c1dfe 100644
--- a/frontend-js/src/main/js/map/OverlayParser.js
+++ b/frontend-js/src/main/js/map/OverlayParser.js
@@ -9,13 +9,24 @@ function OverlayParser() {
 
 /**
  *
- * @param {string| Uint8Array|ArrayBuffer} content
- * @returns {DataOverlay}
+ * @param {string| Uint8Array | ArrayBuffer} content
+ * @returns {string}
+ * @private
  */
-OverlayParser.prototype.parse = function (content) {
+OverlayParser.prototype._extractContent = function (content) {
   if (content instanceof Uint8Array || content instanceof ArrayBuffer) {
     content = new TextDecoder("UTF8").decode(content);
   }
+  return content;
+};
+
+/**
+ *
+ * @param {string| Uint8Array|ArrayBuffer} content
+ * @returns {DataOverlay}
+ */
+OverlayParser.prototype.parse = function (content) {
+  content = this._extractContent(content);
   var data = {content: content};
   var lines = content.split("\n");
   for (var i = 0; i < lines.length; i++) {
@@ -42,5 +53,36 @@ OverlayParser.prototype.parse = function (content) {
   return new DataOverlay(data);
 };
 
+/**
+ *
+ * @param {string| Uint8Array | ArrayBuffer} content
+ * @returns {boolean}
+ */
+OverlayParser.prototype.containsMixedNewLineCharacters = function (content) {
+  content = this._extractContent(content);
+  var newLineRegEx = /[\r\n]+/g;
+  var match = newLineRegEx.exec(content);
+  var newLineFormats = {};
+  var counter = 0;
+  while (match !== null && match !== undefined) {
+    var foundMultiplication = false;
+    var key = '';
+    //this is just a heuristic - let's assume there are at most 10 empty lines in a file
+    for (var i = 0; i < 10; i++) {
+      key += match[0];
+      if (newLineFormats[key]) {
+        foundMultiplication = true;
+      } else {
+        newLineFormats[key] = true;
+      }
+    }
+    if (!foundMultiplication) {
+      counter++;
+    }
+    match = newLineRegEx.exec(content);
+  }
+  return counter > 1;
+};
+
 
 module.exports = OverlayParser;
diff --git a/frontend-js/src/main/js/map/data/MapModel.js b/frontend-js/src/main/js/map/data/MapModel.js
index 2173114711ad26566674abb7edb539d4d5d8f0c3..bbe8d3236763325946f391fa3fdeb4c38782667f 100644
--- a/frontend-js/src/main/js/map/data/MapModel.js
+++ b/frontend-js/src/main/js/map/data/MapModel.js
@@ -455,8 +455,16 @@ MapModel.prototype.getDefaultZoomLevel = function () {
   return this._defaultZoomLevel;
 };
 
+/**
+ *
+ * @param {number} defaultZoomLevel
+ */
 MapModel.prototype.setDefaultZoomLevel = function (defaultZoomLevel) {
-  this._defaultZoomLevel = defaultZoomLevel;
+  if (!isNaN(defaultZoomLevel)) {
+    this._defaultZoomLevel = defaultZoomLevel;
+  } else {
+    this._defaultZoomLevel = null;
+  }
 };
 
 /**
@@ -467,8 +475,16 @@ MapModel.prototype.getDefaultCenterX = function () {
   return this._defaultCenterX;
 };
 
+/**
+ *
+ * @param {number} defaultCenterX
+ */
 MapModel.prototype.setDefaultCenterX = function (defaultCenterX) {
-  this._defaultCenterX = defaultCenterX;
+  if (!isNaN(defaultCenterX)) {
+    this._defaultCenterX = defaultCenterX;
+  } else {
+    this._defaultCenterX = null;
+  }
 };
 
 /**
@@ -480,7 +496,11 @@ MapModel.prototype.getDefaultCenterY = function () {
 };
 
 MapModel.prototype.setDefaultCenterY = function (defaultCenterY) {
-  this._defaultCenterY = defaultCenterY;
+  if (!isNaN(defaultCenterY)) {
+    this._defaultCenterY = defaultCenterY;
+  } else {
+    this._defaultCenterY = null;
+  }
 };
 
 MapModel.prototype.getSubmodelType = function () {
diff --git a/frontend-js/src/test/js/ServerConnector-test.js b/frontend-js/src/test/js/ServerConnector-test.js
index b157e2232c241cbf76113e2aeaea049cc8764767..d7fab5dc49f8276bdea510ec565740b569b53484 100644
--- a/frontend-js/src/test/js/ServerConnector-test.js
+++ b/frontend-js/src/test/js/ServerConnector-test.js
@@ -13,6 +13,7 @@ var LayoutAlias = require('../../main/js/map/data/LayoutAlias');
 var MapModel = require('../../main/js/map/data/MapModel');
 var NetworkError = require('../../main/js/NetworkError');
 var Project = require('../../main/js/map/data/Project');
+var Point = require('../../main/js/map/canvas/Point');
 var Reaction = require('../../main/js/map/data/Reaction');
 var ServerConnector = require('../../main/js/ServerConnector');
 var SecurityError = require('../../main/js/SecurityError');
@@ -110,7 +111,7 @@ describe('ServerConnector', function () {
       });
     });
     it('without ids', function () {
-      return ServerConnector.getReactions([]).then(function (result) {
+      return ServerConnector.getReactions({}).then(function (result) {
         assert.equal(result.length, 28);
         var reaction = result[0];
         assert.ok(reaction instanceof Reaction);
@@ -118,6 +119,32 @@ describe('ServerConnector', function () {
         assert.equal(reaction.getModelId(), 15781);
       });
     });
+
+    it('with ids', function () {
+      return ServerConnector.getReactions({
+        modelId: 15781,
+        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]
+      }).then(function (result) {
+        assert.equal(result.length, 28);
+        var reaction = result[0];
+        assert.ok(reaction instanceof Reaction);
+        assert.equal(reaction.getId(), 153524);
+        assert.equal(reaction.getModelId(), 15781);
+      });
+    });
+    it('with ids when asking for too many elements for gett query', function () {
+      ServerConnector.MAX_NUMBER_OF_IDS_IN_GET_QUERY = 0;
+      return ServerConnector.getReactions({
+        modelId: 15781,
+        participantId: [329167]
+      }).then(function (result) {
+        assert.equal(result.length, 5);
+        var reaction = result[0];
+        assert.ok(reaction instanceof Reaction);
+        assert.equal(reaction.getId(), 153518);
+        assert.equal(reaction.getModelId(), 15781);
+      });
+    });
   });
 
 
@@ -420,4 +447,23 @@ describe('ServerConnector', function () {
   });
 
 
+  describe('objectToRequestString', function () {
+    it('string', function () {
+      assert.equal("test_string", ServerConnector.objectToRequestString("test_string"));
+    });
+    it('number', function () {
+      assert.equal("12", ServerConnector.objectToRequestString(12));
+    });
+    it('point', function () {
+      assert.equal("0.00,10.00", ServerConnector.objectToRequestString(new Point(0, 10)));
+    });
+    it('array of ids', function () {
+      assert.equal("1,4", ServerConnector.objectToRequestString([1, 4]));
+    });
+    it('not sorted array of ids', function () {
+      assert.equal("1,4,5", ServerConnector.objectToRequestString([5, 1, 4]));
+    });
+  });
+
+
 });
diff --git a/frontend-js/src/test/js/map/OverlayParser-test.js b/frontend-js/src/test/js/map/OverlayParser-test.js
index 48ce28d457854d75db0760b5b895aefa11f9ee66..a79ced51117e2e786a780e87053bddfdceac1859 100644
--- a/frontend-js/src/test/js/map/OverlayParser-test.js
+++ b/frontend-js/src/test/js/map/OverlayParser-test.js
@@ -42,5 +42,50 @@ describe('OverlayParser', function () {
       });
     });
   });
+  describe('containsMixedNewLineCharacters', function () {
+    it('normal file', function () {
+      return ServerConnector.sendGetRequest("testFiles/overlay/good.txt").then(function (fileContent) {
+        var parser = new OverlayParser();
+        assert.notOk(parser.containsMixedNewLineCharacters(fileContent));
+      });
+    });
+    it('windows/linux mix', function () {
+      var content = "line1\n\rline2\n";
+      var parser = new OverlayParser();
+      assert.ok(parser.containsMixedNewLineCharacters(content));
+    });
+
+    it('windows empty lines', function () {
+      var content = "line1\n\rline2\n\r\n\rline4";
+      var parser = new OverlayParser();
+      assert.notOk(parser.containsMixedNewLineCharacters(content));
+    });
+
+    it('windows/mac mix', function () {
+      var content = "line1\n\rline2\r";
+      var parser = new OverlayParser();
+      assert.ok(parser.containsMixedNewLineCharacters(content));
+    });
+
+    it('mac empty lines', function () {
+      var content = "line1\rline2\r\rline4";
+      var parser = new OverlayParser();
+      assert.notOk(parser.containsMixedNewLineCharacters(content));
+    });
+
+    it('windows/mac mix 2', function () {
+      var content = "line1\n\r\rline2\n\rline3";
+      var parser = new OverlayParser();
+      assert.ok(parser.containsMixedNewLineCharacters(content));
+    });
+
+    it('linux empty lines', function () {
+      var content = "line1\nline2\n\nline4";
+      var parser = new OverlayParser();
+      assert.notOk(parser.containsMixedNewLineCharacters(content));
+    });
+
+
+  });
 
 });
diff --git a/frontend-js/testFiles/apiCalls/projects/sample/models/15781/bioEntities/reactions/POST_participantId=329167&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/15781/bioEntities/reactions/POST_participantId=329167&token=MOCK_TOKEN_ID&
new file mode 100644
index 0000000000000000000000000000000000000000..dcf64c8357fb8c21d2c6ba4eeed2cddf02eeb5c2
--- /dev/null
+++ b/frontend-js/testFiles/apiCalls/projects/sample/models/15781/bioEntities/reactions/POST_participantId=329167&token=MOCK_TOKEN_ID&
@@ -0,0 +1 @@
+[{"centerPoint":{"x":142.99978766600722,"y":179.00261878591084},"hierarchyVisibilityLevel":null,"id":153518,"kineticLaw":null,"lines":[{"start":{"x":141.01308884552796,"y":203.5052375718217},"end":{"x":142.676524190943,"y":182.98953497836953},"type":"START"},{"start":{"x":143.32305114107143,"y":175.01570259345215},"end":{"x":144.98648648648648,"y":154.5},"type":"END"}],"modelId":15781,"modifiers":[],"notes":"","products":[{"aliasId":329167,"stoichiometry":null}],"reactants":[{"aliasId":329169,"stoichiometry":null}],"reactionId":"re8","references":[],"type":"State transition"},{"centerPoint":{"x":92.15973884958811,"y":136.13620918163832},"hierarchyVisibilityLevel":null,"id":153512,"kineticLaw":null,"lines":[{"start":{"x":75.73715058611361,"y":134.3476104598738},"end":{"x":88.18325303297577,"y":135.7031265679479},"type":"START"},{"start":{"x":96.13622466620043,"y":136.56929179532878},"end":{"x":108.58232711306259,"y":137.92480790340286},"type":"END"}],"modelId":15781,"modifiers":[],"notes":"","products":[{"aliasId":329167,"stoichiometry":null}],"reactants":[{"aliasId":329168,"stoichiometry":null}],"reactionId":"re4","references":[],"type":"State transition"},{"centerPoint":{"x":128.5,"y":47.0},"hierarchyVisibilityLevel":null,"id":153510,"kineticLaw":null,"lines":[{"start":{"x":92.0,"y":36.98039215686274},"end":{"x":124.64269540833152,"y":45.94113207287532},"type":"START"},{"start":{"x":132.35730459166848,"y":48.05886792712468},"end":{"x":165.0,"y":57.01960784313726},"type":"END"},{"start":{"x":144.03021943732247,"y":129.5},"end":{"x":131.99804583067973,"y":53.145215648491444},"type":"MIDDLE"}],"modelId":15781,"modifiers":[{"aliasId":329167,"stoichiometry":null}],"notes":"","products":[{"aliasId":329179,"stoichiometry":null}],"reactants":[{"aliasId":329173,"stoichiometry":null}],"reactionId":"re5","references":[],"type":"State transition"},{"centerPoint":{"x":172.17324895317853,"y":109.17253521126761},"hierarchyVisibilityLevel":null,"id":153504,"kineticLaw":null,"lines":[{"start":{"x":155.9662162162162,"y":129.5},"end":{"x":169.67962640764847,"y":112.300129590407},"type":"START"},{"start":{"x":174.6668714987086,"y":106.04494083212823},"end":{"x":188.38028169014086,"y":88.84507042253522},"type":"END"}],"modelId":15781,"modifiers":[],"notes":"","products":[{"aliasId":329179,"stoichiometry":null}],"reactants":[{"aliasId":329167,"stoichiometry":null}],"reactionId":"re3","references":[],"type":"State transition"},{"centerPoint":{"x":196.68292177751908,"y":142.47367216614504},"hierarchyVisibilityLevel":null,"id":153499,"kineticLaw":null,"lines":[{"start":{"x":180.0362865221489,"y":142.31809613572102},"end":{"x":192.68309645382215,"y":142.43629062106376},"type":"START"},{"start":{"x":200.68274710121602,"y":142.5110537112263},"end":{"x":213.32955703288923,"y":142.62924819656908},"type":"END"}],"modelId":15781,"modifiers":[],"notes":"","products":[{"aliasId":329172,"stoichiometry":null}],"reactants":[{"aliasId":329167,"stoichiometry":null}],"reactionId":"re10","references":[],"type":"State transition"}]
\ No newline at end of file
diff --git a/model-command/src/main/java/lcsb/mapviewer/commands/ColorModelCommand.java b/model-command/src/main/java/lcsb/mapviewer/commands/ColorModelCommand.java
index dc51d7bd73453defe5766ff822ca1c53d2f436fa..0604eb7b481275c4ed3a5633bcbbfa0ec6712451 100644
--- a/model-command/src/main/java/lcsb/mapviewer/commands/ColorModelCommand.java
+++ b/model-command/src/main/java/lcsb/mapviewer/commands/ColorModelCommand.java
@@ -221,7 +221,14 @@ public class ColorModelCommand extends ModelCommand {
         }
       }
       for (MiriamData md : schema.getMiriamData()) {
-        if (!element.getMiriamData().contains(md)) {
+        boolean found = false;
+        for (MiriamData elementMiriamData : element.getMiriamData()) {
+          if (elementMiriamData.getDataType().equals(md.getDataType())
+              && elementMiriamData.getResource().equals(md.getResource())) {
+            found = true;
+          }
+        }
+        if (!found) {
           return false;
         }
       }
diff --git a/model-command/src/test/java/lcsb/mapviewer/commands/ColorModelCommandTest.java b/model-command/src/test/java/lcsb/mapviewer/commands/ColorModelCommandTest.java
index 7d0d731afd3c9ca331c41b0b6391db033ca863e3..a7e8702c8fa6596d13dec3033575fef71122e445 100644
--- a/model-command/src/test/java/lcsb/mapviewer/commands/ColorModelCommandTest.java
+++ b/model-command/src/test/java/lcsb/mapviewer/commands/ColorModelCommandTest.java
@@ -360,6 +360,61 @@ public class ColorModelCommandTest extends CommandTestFunctions {
 
   }
 
+  @Test
+  public void testSpeciesMatchWithMiriamData() throws Exception {
+    try {
+      GenericColorSchema colorSchema = new GenericColorSchema();
+      colorSchema.setName("s1");
+      colorSchema.addMiriamData(new MiriamData(MiriamType.HGNC_SYMBOL, "SNCA"));
+
+      GenericColorSchema colorSchema2 = new GenericColorSchema();
+      colorSchema2.setName("s1");
+      colorSchema2.addMiriamData(new MiriamData(MiriamType.HGNC_SYMBOL, "PARK7"));
+
+      GenericProtein species = new GenericProtein("id");
+      species.setName("s1");
+      species.addMiriamData(new MiriamData(MiriamType.HGNC_SYMBOL, "SNCA"));
+
+      List<ColorSchema> schemas = new ArrayList<>();
+      schemas.add(colorSchema);
+
+      ColorModelCommand factory = new ColorModelCommand(new ModelFullIndexed(null), schemas, colorExtractor);
+
+      assertTrue(factory.match(species, colorSchema));
+      assertFalse(factory.match(species, colorSchema2));
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+
+  }
+
+  @Test
+  public void testSpeciesMatchWithMiriamDataDifferentAnnotator() throws Exception {
+    try {
+      GenericColorSchema colorSchema = new GenericColorSchema();
+      colorSchema.setName("s1");
+      colorSchema.addMiriamData(new MiriamData(MiriamType.HGNC_SYMBOL, "SNCA"));
+
+      GenericProtein species = new GenericProtein("id");
+      species.setName("s1");
+      species.addMiriamData(new MiriamData(MiriamType.HGNC_SYMBOL, "SNCA", Object.class));
+
+      List<ColorSchema> schemas = new ArrayList<>();
+      schemas.add(colorSchema);
+
+      ColorModelCommand factory = new ColorModelCommand(new ModelFullIndexed(null), schemas, colorExtractor);
+
+      assertTrue(factory.match(species, colorSchema));
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+
+  }
+
   @Test
   public void testReactionMatchWithProteinMiriamData() throws Exception {
     try {
diff --git a/persist/src/db/12.0.2/fix_db_20180731.sql b/persist/src/db/12.0.2/fix_db_20180731.sql
new file mode 100644
index 0000000000000000000000000000000000000000..d4a1bab394e65235f4c3005ed11554aa303fafac
--- /dev/null
+++ b/persist/src/db/12.0.2/fix_db_20180731.sql
@@ -0,0 +1,2 @@
+-- issue #461 - duplicates in reaction ids resolved
+update reaction_table r set  idreaction=concat(r.idreaction,'_',r.iddb) from (select idreaction, model_iddb from reaction_table group by idreaction, model_iddb having count(*)>1) t where r.idreaction=t.idreaction and r.model_iddb=t.model_iddb;
diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/ModelRestImpl.java b/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/ModelRestImpl.java
index 78c6e8a518283853d4616af260f59264de0ff694..5e3659dbc1a4d3ece5da1918825bc07267448108 100644
--- a/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/ModelRestImpl.java
+++ b/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/ModelRestImpl.java
@@ -138,6 +138,8 @@ public class ModelRestImpl extends BaseRestImpl {
   private Double parseDouble(Object value) throws QueryException {
     if (value instanceof Double) {
       return (Double) value;
+    } else if (value instanceof Integer) {
+      return ((Integer) value).doubleValue();
     } else if (value instanceof String) {
       if (((String) value).equalsIgnoreCase("")) {
         return null;
@@ -151,7 +153,7 @@ public class ModelRestImpl extends BaseRestImpl {
     } else if (value == null) {
       return null;
     } else {
-      throw new InvalidArgumentException();
+      throw new QueryException("Don't know how to change " + value.getClass() + " into Double");
     }
   }
 }