diff --git a/frontend-js/src/main/js/ServerConnector.js b/frontend-js/src/main/js/ServerConnector.js
index cf8845a05b967228219011bea2d6f1b99c961813..a76aedaa23f8b240a3a653c334e3ddd235dd9052 100644
--- a/frontend-js/src/main/js/ServerConnector.js
+++ b/frontend-js/src/main/js/ServerConnector.js
@@ -1689,7 +1689,9 @@ ServerConnector.removeComment = function (params) {
   var queryParams = {
     commentId: params.commentId
   };
-  var filterParams = {};
+  var filterParams = {
+    reason: params.reason
+  };
   return self.getProjectId(params.projectId).then(function (result) {
     queryParams.projectId = result;
     return self.sendDeleteRequest(self.deleteCommentUrl(queryParams), filterParams);
diff --git a/frontend-js/src/main/js/gui/admin/CommentsAdminPanel.js b/frontend-js/src/main/js/gui/admin/CommentsAdminPanel.js
index 75e221292c8dc03e90a558b016c03445d63e2054..424b951e96625d123243b3dc780e8fd92dfe28dc 100644
--- a/frontend-js/src/main/js/gui/admin/CommentsAdminPanel.js
+++ b/frontend-js/src/main/js/gui/admin/CommentsAdminPanel.js
@@ -19,86 +19,86 @@ function CommentsAdminPanel(params) {
 CommentsAdminPanel.prototype = Object.create(AbstractAdminPanel.prototype);
 CommentsAdminPanel.prototype.constructor = CommentsAdminPanel;
 
-CommentsAdminPanel.prototype._createGui = function() {
+CommentsAdminPanel.prototype._createGui = function () {
   var self = this;
   var projectsDiv = Functions.createElement({
-    type : "div",
+    type: "div",
   });
   self.getElement().appendChild(projectsDiv);
 
   var dataDiv = Functions.createElement({
-    type : "div",
-    style : "display:table",
+    type: "div",
+    style: "display:table",
   });
   projectsDiv.appendChild(dataDiv);
 
   var commentsCell = Functions.createElement({
-    type : "div",
-    style : "display:table-cell;width:100%;vertical-align:top",
+    type: "div",
+    style: "display:table-cell;width:100%;vertical-align:top",
   });
   projectsDiv.appendChild(commentsCell);
 
   var commentsTable = Functions.createElement({
-    type : "table",
-    name : "commentsTable",
-    className : "display",
-    style : "width:100%",
+    type: "table",
+    name: "commentsTable",
+    className: "display",
+    style: "width:100%",
   });
   commentsCell.appendChild(commentsTable);
 
   $(commentsTable).DataTable({
-    columns : [ {
-      title : 'Id',
+    columns: [{
+      title: 'Id',
     }, {
-      title : 'Title',
+      title: 'Title',
     }, {
-      title : 'Author',
+      title: 'Author',
     }, {
-      title : 'Email',
+      title: 'Email',
     }, {
-      title : 'Content',
+      title: 'Content',
     }, {
-      title : 'Removed',
+      title: 'Removed',
     }, {
-      title : 'Pinned',
-    }, ],
+      title: 'Pinned',
+    },],
   });
 
   var projectsCell = Functions.createElement({
-    type : "div",
-    style : "display:table-cell",
+    type: "div",
+    style: "display:table-cell",
   });
   projectsDiv.appendChild(projectsCell);
 
   var selectProject = Functions.createElement({
-    type : "select",
-    name : "projectSelect",
+    type: "select",
+    name: "projectSelect",
   });
   selectProject.size = "12";
-  selectProject.onchange = function() {
+  selectProject.onchange = function () {
     return self.onProjectChange();
   };
 
   projectsCell.appendChild(Functions.createElement({
-    type : "h3",
-    content : "Project",
+    type: "h3",
+    content: "Project",
   }));
   projectsCell.appendChild(selectProject);
 };
 
-CommentsAdminPanel.prototype.init = function() {
+CommentsAdminPanel.prototype.init = function () {
   var self = this;
   return self.refreshProjects();
 };
 
-CommentsAdminPanel.prototype.refreshProjects = function() {
+CommentsAdminPanel.prototype.refreshProjects = function () {
   var self = this;
   var projectSelect = $("[name='projectSelect']", self.getElement())[0];
-  return ServerConnector.getProjects().then(function(projects) {
+  return ServerConnector.getProjects().then(function (projects) {
     while (projectSelect.firstChild) {
       projectSelect.removeChild(projectSelect.firstChild);
     }
-    projects.sort(function(project1, project2) {
+    projects.sort(function (project1, project2) {
       if (project1.getProjectId() < project2.getProjectId()) {
         return -1;
       } else if (project1.getProjectId() > project2.getProjectId()) {
@@ -115,45 +115,50 @@ CommentsAdminPanel.prototype.refreshProjects = function() {
       projectSelect.appendChild(new Option(name, value));
     }
     return ServerConnector.getProjectId();
-  }).then(function(projectId) {
+  }).then(function (projectId) {
     projectSelect.value = projectId;
     return self.onProjectChange();
   });
 };
 
-CommentsAdminPanel.prototype.getSelectedProjectId = function() {
+CommentsAdminPanel.prototype.getSelectedProjectId = function () {
   var projectSelect = $("[name='projectSelect']", this.getElement())[0];
   return projectSelect.value;
 };
 
-CommentsAdminPanel.prototype.onProjectChange = function() {
+CommentsAdminPanel.prototype.onProjectChange = function () {
   var self = this;
 
   return ServerConnector.getComments({
-    projectId : self.getSelectedProjectId(),
-  }).then(function(comments) {
+    projectId: self.getSelectedProjectId()
+  }).then(function (comments) {
     var dataTable = $($("[name='commentsTable']", self.getElement())[0]).DataTable();
     var data = [];
     for (var i = 0; i < comments.length; i++) {
       data.push(self.commentToTableRow(comments[i]));
     }
     dataTable.clear().rows.add(data).draw();
-    $("[name='commentsTable']", self.getElement()).on("click", "[name='removeComment']", function() {
+    $("[name='commentsTable']", self.getElement()).on("click", "[name='removeComment']", function () {
       var button = this;
-      return ServerConnector.removeComment({
-        commentId : $(button).attr("data")
-      }).then(function() {
-        $(button).after("<span>YES</span>");
-        button.style.display = "none";
-      });
+      return self.askConfirmRemoval().then(function (param) {
+        if (param.status) {
+          return ServerConnector.removeComment({
+            commentId: $(button).attr("data"),
+            reason: param.reason
+          }).then(function () {
+            $(button).after("<span>YES (" + param.reason + ")</span>");
+            button.style.display = "none";
+          });
+        }
+      })
     });
   });
 };
 
-CommentsAdminPanel.prototype.commentToTableRow = function(comment) {
+CommentsAdminPanel.prototype.commentToTableRow = function (comment) {
   var self = this;
   var projectId = self.getSelectedProjectId();
-  var toYesNo = function(val) {
+  var toYesNo = function (val) {
     if (val) {
       return "YES";
     } else {
@@ -163,10 +168,10 @@ CommentsAdminPanel.prototype.commentToTableRow = function(comment) {
   var title = null;
   if (!comment.isRemoved()) {
     var commentLink = "index.xhtml?id=" + projectId + // 
-    "&x=" + comment.getCoordinates().x + // 
-    "&y=" + comment.getCoordinates().y + // 
-    "&zoom=12" + //
-    "&comments=on";
+      "&x=" + comment.getCoordinates().x + //
+      "&y=" + comment.getCoordinates().y + //
+      "&zoom=12" + //
+      "&comments=on";
     title = "<a href='" + commentLink + "' target='" + projectId + "'>" + comment.getTitle() + "</a>";
   } else {
     title = comment.getTitle();
@@ -174,7 +179,7 @@ CommentsAdminPanel.prototype.commentToTableRow = function(comment) {
 
   var remove = null;
   if (comment.isRemoved()) {
-    remove = "YES";
+    remove = "YES (" + comment.getRemoveReason() + ")";
   } else {
     remove = "<button name='removeComment' data='" + comment.getId() + "'>REMOVE</button>";
   }
@@ -189,22 +194,41 @@ CommentsAdminPanel.prototype.commentToTableRow = function(comment) {
     email = "N/A";
   }
 
-  var row = [ comment.getId(), // 
-  title, //
-  author, // 
-  email, // 
-  comment.getContent(), // 
-  remove, //
-  toYesNo(comment.isPinned()) ];
+  var row = [comment.getId(), //
+    title, //
+    author, //
+    email, //
+    comment.getContent(), //
+    remove, //
+    toYesNo(comment.isPinned())];
   return row;
 };
 
 CommentsAdminPanel.prototype.destroy = function () {
-    var self = this;
-    var table = $("[name='commentsTable']", self.getElement())[0];
-    if ($.fn.DataTable.isDataTable(table)) {
-        $(table).DataTable().destroy();
-    }
+  var self = this;
+  var table = $("[name='commentsTable']", self.getElement())[0];
+  if ($.fn.DataTable.isDataTable(table)) {
+    $(table).DataTable().destroy();
+  }
+};
+
+CommentsAdminPanel.prototype.askConfirmRemoval = function () {
+  return new Promise(function (resolve) {
+    $('<form><input type="text" style="z-index:10000" name="name"><br></form>').dialog({
+      modal: true,
+      title: "Why do you want to remove this comment?",
+      buttons: {
+        'OK': function () {
+          $(this).dialog('close');
+          resolve({reason: $('input[name="name"]').val(), status: true});
+        },
+        'Cancel': function () {
+          $(this).dialog('close');
+          resolve({status: false});
+        }
+      }
+    });
+  })
 };
 
 module.exports = CommentsAdminPanel;
diff --git a/frontend-js/src/main/js/map/data/Comment.js b/frontend-js/src/main/js/map/data/Comment.js
index 735e508c1de3989d1bd2be8460eb3e0de856fbce..b075e577929e33fde2d370162b5a1b1a6955dbf4 100644
--- a/frontend-js/src/main/js/map/data/Comment.js
+++ b/frontend-js/src/main/js/map/data/Comment.js
@@ -7,10 +7,11 @@ function Comment(javaObject) {
     id : javaObject.elementId,
     type : javaObject.type,
     modelId : javaObject.modelId,
-    icon : javaObject.icon,
+    icon : javaObject.icon
   }));
   this.setId(javaObject.id);
   this.setRemoved(javaObject.removed);
+  this.setRemoveReason(javaObject.removeReason);
   this.setPinned(javaObject.pinned);
 
   if (javaObject.title !== undefined) {
@@ -82,5 +83,11 @@ Comment.prototype.setEmail = function(email) {
 Comment.prototype.getEmail = function() {
   return this._email;
 };
+Comment.prototype.setRemoveReason = function(removeReason) {
+  this._removeReason = removeReason;
+};
+Comment.prototype.getRemoveReason = function() {
+  return this._removeReason;
+};
 
 module.exports = Comment;
diff --git a/frontend-js/src/main/js/map/data/Mesh.js b/frontend-js/src/main/js/map/data/Mesh.js
index 612111fec621ccab07cc808cd37cf4125afedb83..500ef3a9a107101e11642b1478ca03731a5652a7 100644
--- a/frontend-js/src/main/js/map/data/Mesh.js
+++ b/frontend-js/src/main/js/map/data/Mesh.js
@@ -9,29 +9,28 @@ function Mesh(jsonObject) {
 }
 
 Mesh.prototype.setSynonyms = function (synonyms) {
-  this.synonyms = synonyms;
+  this._synonyms = synonyms;
 };
 Mesh.prototype.getSynonyms = function () {
-  return this.synonyms;
+  return this._synonyms;
 };
 Mesh.prototype.setName = function (name) {
-  this.name = name;
+  this._name = name;
 };
 Mesh.prototype.getName = function () {
-  return this.name;
+  return this._name;
 };
 Mesh.prototype.setId = function (id) {
-  this.id = id;
+  this._id = id;
 };
 Mesh.prototype.getId = function () {
-  return this.id;
+  return this._id;
 };
 Mesh.prototype.setDescription = function (description) {
-  this.description = description;
+  this._description = description;
 };
 Mesh.prototype.getDescription = function () {
-  return this.description;
+  return this._description;
 };
 
-
 module.exports = Mesh;
diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/BaseController.java b/rest-api/src/main/java/lcsb/mapviewer/api/BaseController.java
index e210ca049b46b67c266fa57be45dfacf142aa0c4..7e9ca40a76fc9c562bd22f607d5a79f71536adf3 100644
--- a/rest-api/src/main/java/lcsb/mapviewer/api/BaseController.java
+++ b/rest-api/src/main/java/lcsb/mapviewer/api/BaseController.java
@@ -23,62 +23,70 @@ import lcsb.mapviewer.common.Configuration;
 import lcsb.mapviewer.common.exception.InvalidStateException;
 
 public abstract class BaseController {
-	private Logger			 logger	= Logger.getLogger(BaseController.class);
+  private Logger logger = Logger.getLogger(BaseController.class);
 
-	private ObjectMapper mapper	= new ObjectMapper();
+  private ObjectMapper mapper = new ObjectMapper();
 
-	@ExceptionHandler({ Exception.class })
-	public ResponseEntity<Object> handleException(Exception e, WebRequest request) {
-		if (e instanceof lcsb.mapviewer.services.SecurityException) {
-			return new ResponseEntity<Object>("{\"error\" : \"Access denied.\",\"reason\":\"" + e.getMessage() + "\"}", new HttpHeaders(), HttpStatus.FORBIDDEN);
-		} else if (e instanceof ObjectNotFoundException) {
-			return new ResponseEntity<Object>("{\"error\" : \"Object not found.\",\"reason\":\"" + e.getMessage() + "\"}", new HttpHeaders(), HttpStatus.NOT_FOUND);
-		} else if (e instanceof ObjectExistsException) {
-			return new ResponseEntity<Object>(
-					"{\"error\" : \"Object already exists.\",\"reason\":\"" + e.getMessage() + "\"}", new HttpHeaders(), HttpStatus.CONFLICT);
-		} else if (e instanceof QueryException) {
-			logger.error(e, e);
-			return new ResponseEntity<Object>(
-					"{\"error\" : \"Query server error.\",\"reason\":\"" + e.getMessage() + "\"}", new HttpHeaders(), HttpStatus.BAD_REQUEST);
-		} else if (e instanceof ServletRequestBindingException && e.getMessage().indexOf(Configuration.AUTH_TOKEN) >= 0) {
-			return new ResponseEntity<Object>("{\"error\" : \"Access denied.\",\"reason\":\"" + e.getMessage() + "\"}", new HttpHeaders(), HttpStatus.FORBIDDEN);
-		} else {
-			logger.error(e, e);
-			return new ResponseEntity<Object>(
-					"{\"error\" : \"Internal server error.\",\"reason\":\"" + e.getMessage() + "\"}", new HttpHeaders(), HttpStatus.INTERNAL_SERVER_ERROR);
-		}
-	}
+  @ExceptionHandler({ Exception.class })
+  public ResponseEntity<Object> handleException(Exception e, WebRequest request) {
+    if (e instanceof lcsb.mapviewer.services.SecurityException) {
+      return new ResponseEntity<Object>("{\"error\" : \"Access denied.\",\"reason\":\"" + e.getMessage() + "\"}",
+          new HttpHeaders(), HttpStatus.FORBIDDEN);
+    } else if (e instanceof ObjectNotFoundException) {
+      return new ResponseEntity<Object>("{\"error\" : \"Object not found.\",\"reason\":\"" + e.getMessage() + "\"}",
+          new HttpHeaders(), HttpStatus.NOT_FOUND);
+    } else if (e instanceof ObjectExistsException) {
+      return new ResponseEntity<Object>(
+          "{\"error\" : \"Object already exists.\",\"reason\":\"" + e.getMessage() + "\"}", new HttpHeaders(),
+          HttpStatus.CONFLICT);
+    } else if (e instanceof QueryException) {
+      logger.error(e, e);
+      return new ResponseEntity<Object>("{\"error\" : \"Query server error.\",\"reason\":\"" + e.getMessage() + "\"}",
+          new HttpHeaders(), HttpStatus.BAD_REQUEST);
+    } else if (e instanceof ServletRequestBindingException && e.getMessage().indexOf(Configuration.AUTH_TOKEN) >= 0) {
+      return new ResponseEntity<Object>("{\"error\" : \"Access denied.\",\"reason\":\"" + e.getMessage() + "\"}",
+          new HttpHeaders(), HttpStatus.FORBIDDEN);
+    } else {
+      logger.error(e, e);
+      return new ResponseEntity<Object>(
+          "{\"error\" : \"Internal server error.\",\"reason\":\"" + e.getMessage() + "\"}", new HttpHeaders(),
+          HttpStatus.INTERNAL_SERVER_ERROR);
+    }
+  }
 
-	public Map<String, Object> parseBody(String body) throws IOException, JsonParseException, JsonMappingException {
-		ObjectNode result = mapper.readValue(body, ObjectNode.class);
-		return mapper.convertValue(result, Map.class);
-	}
+  public Map<String, Object> parseBody(String body) throws IOException, JsonParseException, JsonMappingException {
+    if (body == null || body.isEmpty()) {
+      return new HashMap<>();
+    }
+    ObjectNode result = mapper.readValue(body, ObjectNode.class);
+    return mapper.convertValue(result, Map.class);
+  }
 
-	protected Map<String, Object> getData(Map<String, Object> node, String objectName) {
-		return (Map<String, Object>) node.get(objectName);
-	}
+  protected Map<String, Object> getData(Map<String, Object> node, String objectName) {
+    return (Map<String, Object>) node.get(objectName);
+  }
 
-	protected Map<String, String> parsePostBody(String body) {
-		Map<String, String> result = new HashMap<>();
-		String[] parameters = body.split("&");
-		for (String string : parameters) {
-			int position = string.indexOf("=");
-			if (position < 0) {
-				position = string.length();
-			}
-			String key = string.substring(0, position);
-			String value = null;
-			if (position < string.length()) {
-				value = string.substring(position + 1, string.length());
-				try {
-					value = URLDecoder.decode(value, "UTF-8");
-				} catch (UnsupportedEncodingException e) {
-					throw new InvalidStateException("Cannot decode input", e);
-				}
-			}
-			result.put(key, value);
-		}
-		return result;
-	}
+  protected Map<String, String> parsePostBody(String body) {
+    Map<String, String> result = new HashMap<>();
+    String[] parameters = body.split("&");
+    for (String string : parameters) {
+      int position = string.indexOf("=");
+      if (position < 0) {
+        position = string.length();
+      }
+      String key = string.substring(0, position);
+      String value = null;
+      if (position < string.length()) {
+        value = string.substring(position + 1, string.length());
+        try {
+          value = URLDecoder.decode(value, "UTF-8");
+        } catch (UnsupportedEncodingException e) {
+          throw new InvalidStateException("Cannot decode input", e);
+        }
+      }
+      result.put(key, value);
+    }
+    return result;
+  }
 
 }
diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/projects/comments/CommentController.java b/rest-api/src/main/java/lcsb/mapviewer/api/projects/comments/CommentController.java
index 2617a3c3f8df33777cc5dabd9b693ee7e81ef069..c941446e661d92e6d34b8f4c33c21f4bd4318d51 100644
--- a/rest-api/src/main/java/lcsb/mapviewer/api/projects/comments/CommentController.java
+++ b/rest-api/src/main/java/lcsb/mapviewer/api/projects/comments/CommentController.java
@@ -1,6 +1,7 @@
 package lcsb.mapviewer.api.projects.comments;
 
 import java.awt.geom.Point2D;
+import java.io.IOException;
 import java.util.List;
 import java.util.Map;
 
@@ -8,11 +9,15 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.MediaType;
 import org.springframework.web.bind.annotation.CookieValue;
 import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+
 import lcsb.mapviewer.api.BaseController;
 import lcsb.mapviewer.api.QueryException;
 import lcsb.mapviewer.common.Configuration;
@@ -22,152 +27,157 @@ import lcsb.mapviewer.services.search.data.ElementIdentifier.ElementIdentifierTy
 @RestController
 public class CommentController extends BaseController {
 
-	@Autowired
-	private CommentRestImpl commentController;
-
-	@RequestMapping(value = "/projects/{projectId}/comments/models/{modelId}/", method = { RequestMethod.GET }, produces = { MediaType.APPLICATION_JSON_VALUE })
-	public List<Map<String, Object>> getComments(//
-			@CookieValue(value = Configuration.AUTH_TOKEN) String token, //
-			@PathVariable(value = "projectId") String projectId, //
-			@RequestParam(value = "columns", defaultValue = "") String columns, //
-			@RequestParam(value = "removed", defaultValue = "") String removed //
-	) throws SecurityException, QueryException {
-		return commentController.getCommentList(token, projectId, columns, "", "", removed);
-	}
-
-	@RequestMapping(value = "/projects/{projectId}/comments/{commentId}/", method = { RequestMethod.DELETE }, produces = { MediaType.APPLICATION_JSON_VALUE })
-	public Map<String, Object> removeComment(//
-			@CookieValue(value = Configuration.AUTH_TOKEN) String token, //
-			@PathVariable(value = "projectId") String projectId, //
-			@PathVariable(value = "commentId") String commentId //
-	) throws SecurityException, QueryException {
-		return commentController.removeComment(token, projectId, commentId);
-	}
-
-	@RequestMapping(value = "/projects/{projectId}/comments/models/{modelId}/bioEntities/reactions/{reactionId}", method = { RequestMethod.GET },
-			produces = { MediaType.APPLICATION_JSON_VALUE })
-	public List<Map<String, Object>> getCommentsByReaction(//
-			@CookieValue(value = Configuration.AUTH_TOKEN) String token, //
-			@PathVariable(value = "projectId") String projectId, //
-			@RequestParam(value = "columns", defaultValue = "") String columns, //
-			@PathVariable(value = "reactionId") String reactionId, //
-			@RequestParam(value = "removed", defaultValue = "") String removed //
-	) throws SecurityException, QueryException {
-		return commentController.getCommentList(token, projectId, columns, reactionId, ElementIdentifierType.REACTION.getJsName(), removed);
-	}
-
-	@RequestMapping(value = "/projects/{projectId}/comments/models/{modelId}/bioEntities/elements/{elementId}", method = { RequestMethod.GET },
-			produces = { MediaType.APPLICATION_JSON_VALUE })
-	public List<Map<String, Object>> getCommentsByElement(//
-			@CookieValue(value = Configuration.AUTH_TOKEN) String token, //
-			@PathVariable(value = "projectId") String projectId, //
-			@RequestParam(value = "columns", defaultValue = "") String columns, //
-			@PathVariable(value = "elementId") String elementId, //
-			@RequestParam(value = "removed", defaultValue = "") String removed //
-	) throws SecurityException, QueryException {
-		return commentController.getCommentList(token, projectId, columns, elementId, ElementIdentifierType.ALIAS.getJsName(), removed);
-	}
-
-	@RequestMapping(value = "/projects/{projectId}/comments/models/{modelId}/points/{coordinates:.+}", method = { RequestMethod.GET },
-			produces = { MediaType.APPLICATION_JSON_VALUE })
-	public List<Map<String, Object>> getCommentsByPoint(//
-			@CookieValue(value = Configuration.AUTH_TOKEN) String token, //
-			@PathVariable(value = "projectId") String projectId, //
-			@RequestParam(value = "columns", defaultValue = "") String columns, //
-			@PathVariable(value = "coordinates") String coordinates, //
-			@RequestParam(value = "removed", defaultValue = "") String removed //
-	) throws SecurityException, QueryException {
-		return commentController.getCommentList(token, projectId, columns, coordinates, ElementIdentifierType.POINT.getJsName(), removed);
-	}
-
-	@RequestMapping(value = "/projects/{projectId}/comments/models/{modelId}/bioEntities/elements/{elementId}", method = { RequestMethod.POST },
-			produces = { MediaType.APPLICATION_JSON_VALUE })
-	public Map<String, Object> addCommentForElement(//
-			@CookieValue(value = Configuration.AUTH_TOKEN) String token, //
-			@PathVariable(value = "projectId") String projectId, //
-			@PathVariable(value = "elementId") String elementId, //
-			@RequestParam(value = "name") String name, //
-			@RequestParam(value = "email") String email, //
-			@RequestParam(value = "content") String content, //
-			@RequestParam(value = "pinned", defaultValue = "true") String pinned, //
-			@RequestParam(value = "coordinates") String coordinates, //
-			@PathVariable(value = "modelId") String modelId //
-	) throws SecurityException, QueryException {
-		Point2D pointCoordinates = parseCoordinates(coordinates);
-		return commentController.addComment(
-				token, projectId, ElementIdentifierType.ALIAS.getJsName(), elementId, name, email, content, pinned.toLowerCase().equals("true"), pointCoordinates,
-				modelId);
-	}
-
-	@RequestMapping(value = "/projects/{projectId}/comments/models/{modelId}/bioEntities/reactions/{reactionId}", method = { RequestMethod.POST },
-			produces = { MediaType.APPLICATION_JSON_VALUE })
-	public Map<String, Object> addCommentForReaction(//
-			@CookieValue(value = Configuration.AUTH_TOKEN) String token, //
-			@PathVariable(value = "projectId") String projectId, //
-			@PathVariable(value = "reactionId") String reactionId, //
-			@RequestParam(value = "name") String name, //
-			@RequestParam(value = "email") String email, //
-			@RequestParam(value = "content") String content, //
-			@RequestParam(value = "pinned", defaultValue = "true") String pinned, //
-			@RequestParam(value = "coordinates") String coordinates, //
-			@PathVariable(value = "modelId") String modelId //
-	) throws SecurityException, QueryException {
-		Point2D pointCoordinates = parseCoordinates(coordinates);
-		return commentController.addComment(
-				token, projectId, ElementIdentifierType.REACTION.getJsName(), reactionId, name, email, content, pinned.toLowerCase().equals("true"), pointCoordinates,
-				modelId);
-	}
-
-	@RequestMapping(value = "/projects/{projectId}/comments/models/{modelId}/points/{coordinates}", method = { RequestMethod.POST },
-			produces = { MediaType.APPLICATION_JSON_VALUE })
-	public Map<String, Object> addCommentForPoint(//
-			@CookieValue(value = Configuration.AUTH_TOKEN) String token, //
-			@PathVariable(value = "projectId") String projectId, //
-			@RequestParam(value = "name") String name, //
-			@RequestParam(value = "email") String email, //
-			@RequestParam(value = "content") String content, //
-			@RequestParam(value = "pinned", defaultValue = "true") String pinned, //
-			@PathVariable(value = "coordinates") String coordinates, //
-			@PathVariable(value = "modelId") String modelId //
-	) throws SecurityException, QueryException {
-		Point2D pointCoordinates = parseCoordinates(coordinates);
-		return commentController.addComment(
-				token, projectId, ElementIdentifierType.POINT.getJsName(), coordinates, name, email, content, pinned.toLowerCase().equals("true"), pointCoordinates,
-				modelId);
-	}
-
-	private Point2D parseCoordinates(String coordinates) throws QueryException {
-		String[] tmp = coordinates.split(",");
-		if (tmp.length != 2) {
-			throw new QueryException("Coordinates must be in the format: 'xxx.xx,yyy.yy'");
-		}
-		Double x = null;
-		Double y = null;
-		try {
-			x = Double.valueOf(tmp[0]);
-			y = Double.valueOf(tmp[1]);
-		} catch (NumberFormatException e) {
-			throw new QueryException("Coordinates must be in the format: 'xxx.xx,yyy.yy'", e);
-		}
-		Point2D pointCoordinates = new Point2D.Double(x, y);
-		return pointCoordinates;
-	}
-
-	/**
-	 * @return the overlayController
-	 * @see #commentController
-	 */
-	public CommentRestImpl getOverlayController() {
-		return commentController;
-	}
-
-	/**
-	 * @param overlayController
-	 *          the overlayController to set
-	 * @see #commentController
-	 */
-	public void setOverlayController(CommentRestImpl overlayController) {
-		this.commentController = overlayController;
-	}
+  @Autowired
+  private CommentRestImpl commentController;
+
+  @RequestMapping(value = "/projects/{projectId}/comments/models/{modelId}/", method = {
+      RequestMethod.GET }, produces = { MediaType.APPLICATION_JSON_VALUE })
+  public List<Map<String, Object>> getComments(//
+      @CookieValue(value = Configuration.AUTH_TOKEN) String token, //
+      @PathVariable(value = "projectId") String projectId, //
+      @RequestParam(value = "columns", defaultValue = "") String columns, //
+      @RequestParam(value = "removed", defaultValue = "") String removed //
+  ) throws SecurityException, QueryException {
+    return commentController.getCommentList(token, projectId, columns, "", "", removed);
+  }
+
+  @RequestMapping(value = "/projects/{projectId}/comments/{commentId}/", method = { RequestMethod.DELETE }, produces = {
+      MediaType.APPLICATION_JSON_VALUE })
+  public Map<String, Object> removeComment(//
+      @RequestBody(required = false) String body, //
+      @CookieValue(value = Configuration.AUTH_TOKEN) String token, //
+      @PathVariable(value = "projectId") String projectId, //
+      @PathVariable(value = "commentId") String commentId //
+  ) throws SecurityException, QueryException, JsonParseException, JsonMappingException, IOException {
+    Map<String, Object> node = parseBody(body);
+    String reason = (String) node.get("reason");
+    return commentController.removeComment(token, projectId, commentId, reason);
+  }
+
+  @RequestMapping(value = "/projects/{projectId}/comments/models/{modelId}/bioEntities/reactions/{reactionId}", method = {
+      RequestMethod.GET }, produces = { MediaType.APPLICATION_JSON_VALUE })
+  public List<Map<String, Object>> getCommentsByReaction(//
+      @CookieValue(value = Configuration.AUTH_TOKEN) String token, //
+      @PathVariable(value = "projectId") String projectId, //
+      @RequestParam(value = "columns", defaultValue = "") String columns, //
+      @PathVariable(value = "reactionId") String reactionId, //
+      @RequestParam(value = "removed", defaultValue = "") String removed //
+  ) throws SecurityException, QueryException {
+    return commentController.getCommentList(token, projectId, columns, reactionId,
+        ElementIdentifierType.REACTION.getJsName(), removed);
+  }
+
+  @RequestMapping(value = "/projects/{projectId}/comments/models/{modelId}/bioEntities/elements/{elementId}", method = {
+      RequestMethod.GET }, produces = { MediaType.APPLICATION_JSON_VALUE })
+  public List<Map<String, Object>> getCommentsByElement(//
+      @CookieValue(value = Configuration.AUTH_TOKEN) String token, //
+      @PathVariable(value = "projectId") String projectId, //
+      @RequestParam(value = "columns", defaultValue = "") String columns, //
+      @PathVariable(value = "elementId") String elementId, //
+      @RequestParam(value = "removed", defaultValue = "") String removed //
+  ) throws SecurityException, QueryException {
+    return commentController.getCommentList(token, projectId, columns, elementId,
+        ElementIdentifierType.ALIAS.getJsName(), removed);
+  }
+
+  @RequestMapping(value = "/projects/{projectId}/comments/models/{modelId}/points/{coordinates:.+}", method = {
+      RequestMethod.GET }, produces = { MediaType.APPLICATION_JSON_VALUE })
+  public List<Map<String, Object>> getCommentsByPoint(//
+      @CookieValue(value = Configuration.AUTH_TOKEN) String token, //
+      @PathVariable(value = "projectId") String projectId, //
+      @RequestParam(value = "columns", defaultValue = "") String columns, //
+      @PathVariable(value = "coordinates") String coordinates, //
+      @RequestParam(value = "removed", defaultValue = "") String removed //
+  ) throws SecurityException, QueryException {
+    return commentController.getCommentList(token, projectId, columns, coordinates,
+        ElementIdentifierType.POINT.getJsName(), removed);
+  }
+
+  @RequestMapping(value = "/projects/{projectId}/comments/models/{modelId}/bioEntities/elements/{elementId}", method = {
+      RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE })
+  public Map<String, Object> addCommentForElement(//
+      @CookieValue(value = Configuration.AUTH_TOKEN) String token, //
+      @PathVariable(value = "projectId") String projectId, //
+      @PathVariable(value = "elementId") String elementId, //
+      @RequestParam(value = "name") String name, //
+      @RequestParam(value = "email") String email, //
+      @RequestParam(value = "content") String content, //
+      @RequestParam(value = "pinned", defaultValue = "true") String pinned, //
+      @RequestParam(value = "coordinates") String coordinates, //
+      @PathVariable(value = "modelId") String modelId //
+  ) throws SecurityException, QueryException {
+    Point2D pointCoordinates = parseCoordinates(coordinates);
+    return commentController.addComment(token, projectId, ElementIdentifierType.ALIAS.getJsName(), elementId, name,
+        email, content, pinned.toLowerCase().equals("true"), pointCoordinates, modelId);
+  }
+
+  @RequestMapping(value = "/projects/{projectId}/comments/models/{modelId}/bioEntities/reactions/{reactionId}", method = {
+      RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE })
+  public Map<String, Object> addCommentForReaction(//
+      @CookieValue(value = Configuration.AUTH_TOKEN) String token, //
+      @PathVariable(value = "projectId") String projectId, //
+      @PathVariable(value = "reactionId") String reactionId, //
+      @RequestParam(value = "name") String name, //
+      @RequestParam(value = "email") String email, //
+      @RequestParam(value = "content") String content, //
+      @RequestParam(value = "pinned", defaultValue = "true") String pinned, //
+      @RequestParam(value = "coordinates") String coordinates, //
+      @PathVariable(value = "modelId") String modelId //
+  ) throws SecurityException, QueryException {
+    Point2D pointCoordinates = parseCoordinates(coordinates);
+    return commentController.addComment(token, projectId, ElementIdentifierType.REACTION.getJsName(), reactionId, name,
+        email, content, pinned.toLowerCase().equals("true"), pointCoordinates, modelId);
+  }
+
+  @RequestMapping(value = "/projects/{projectId}/comments/models/{modelId}/points/{coordinates}", method = {
+      RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE })
+  public Map<String, Object> addCommentForPoint(//
+      @CookieValue(value = Configuration.AUTH_TOKEN) String token, //
+      @PathVariable(value = "projectId") String projectId, //
+      @RequestParam(value = "name") String name, //
+      @RequestParam(value = "email") String email, //
+      @RequestParam(value = "content") String content, //
+      @RequestParam(value = "pinned", defaultValue = "true") String pinned, //
+      @PathVariable(value = "coordinates") String coordinates, //
+      @PathVariable(value = "modelId") String modelId //
+  ) throws SecurityException, QueryException {
+    Point2D pointCoordinates = parseCoordinates(coordinates);
+    return commentController.addComment(token, projectId, ElementIdentifierType.POINT.getJsName(), coordinates, name,
+        email, content, pinned.toLowerCase().equals("true"), pointCoordinates, modelId);
+  }
+
+  private Point2D parseCoordinates(String coordinates) throws QueryException {
+    String[] tmp = coordinates.split(",");
+    if (tmp.length != 2) {
+      throw new QueryException("Coordinates must be in the format: 'xxx.xx,yyy.yy'");
+    }
+    Double x = null;
+    Double y = null;
+    try {
+      x = Double.valueOf(tmp[0]);
+      y = Double.valueOf(tmp[1]);
+    } catch (NumberFormatException e) {
+      throw new QueryException("Coordinates must be in the format: 'xxx.xx,yyy.yy'", e);
+    }
+    Point2D pointCoordinates = new Point2D.Double(x, y);
+    return pointCoordinates;
+  }
+
+  /**
+   * @return the overlayController
+   * @see #commentController
+   */
+  public CommentRestImpl getOverlayController() {
+    return commentController;
+  }
+
+  /**
+   * @param overlayController
+   *          the overlayController to set
+   * @see #commentController
+   */
+  public void setOverlayController(CommentRestImpl overlayController) {
+    this.commentController = overlayController;
+  }
 
 }
\ No newline at end of file
diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/projects/comments/CommentRestImpl.java b/rest-api/src/main/java/lcsb/mapviewer/api/projects/comments/CommentRestImpl.java
index 192efa5d6d25fc01a5b9c59740efcd4613eb49ea..b35bf061173f85c9524bb6207169d06a7ff40df9 100644
--- a/rest-api/src/main/java/lcsb/mapviewer/api/projects/comments/CommentRestImpl.java
+++ b/rest-api/src/main/java/lcsb/mapviewer/api/projects/comments/CommentRestImpl.java
@@ -130,6 +130,8 @@ public class CommentRestImpl extends BaseRestImpl {
         value = comment.isDeleted();
       } else if (column.equals("coord")) {
         value = getCoordinates(comment);
+      } else if (column.equals("removereason")) {
+        value = comment.getRemoveReason();
       } else if (column.equals("type")) {
         value = getType(comment);
       } else if (column.equals("icon")) {
@@ -240,6 +242,7 @@ public class CommentRestImpl extends BaseRestImpl {
         columnsSet.add("pinned");
         columnsSet.add("author");
         columnsSet.add("email");
+        columnsSet.add("removeReason");
       }
     } else {
       for (String str : columns.split(",")) {
@@ -328,7 +331,7 @@ public class CommentRestImpl extends BaseRestImpl {
     return preparedComment(comment, createCommentColumnSet("", isAdmin), isAdmin);
   }
 
-  public Map<String, Object> removeComment(String token, String projectId, String commentId)
+  public Map<String, Object> removeComment(String token, String projectId, String commentId, String reason)
       throws SecurityException, QueryException {
     AuthenticationToken authenticationToken = getUserService().getToken(token);
     Project project = getProjectService().getProjectByProjectId(projectId, authenticationToken);
@@ -340,7 +343,7 @@ public class CommentRestImpl extends BaseRestImpl {
       throw new ObjectNotFoundException("Comment with given id doesn't exist");
     }
 
-    commentService.deleteComment(comment, authenticationToken);
+    commentService.deleteComment(comment, authenticationToken, reason);
     return okStatus();
   }
 
diff --git a/service/src/main/java/lcsb/mapviewer/services/impl/CommentService.java b/service/src/main/java/lcsb/mapviewer/services/impl/CommentService.java
index 08f6daf43d0283ab8e70a941a951e4d4e720ccd1..faf8f766ae94a39b5accd4f67f10098b8d555708 100644
--- a/service/src/main/java/lcsb/mapviewer/services/impl/CommentService.java
+++ b/service/src/main/java/lcsb/mapviewer/services/impl/CommentService.java
@@ -426,11 +426,12 @@ public class CommentService implements ICommentService {
   }
 
   @Override
-  public void deleteComment(Comment comment, AuthenticationToken token) throws UserAccessException {
+  public void deleteComment(Comment comment, AuthenticationToken token, String reason) throws UserAccessException {
     Project project = comment.getModelData().getProject();
     boolean editComments = userService.userHasPrivilege(token, PrivilegeType.EDIT_COMMENTS_PROJECT, project);
     if (editComments || userService.getUserByToken(token).equals(comment.getUser())) {
       comment.setDeleted(true);
+      comment.setRemoveReason(reason);
       commentDao.update(comment);
     } else {
       throw new UserAccessException("You have no privileges to remove the comment");
diff --git a/service/src/main/java/lcsb/mapviewer/services/interfaces/ICommentService.java b/service/src/main/java/lcsb/mapviewer/services/interfaces/ICommentService.java
index 06d32a16cc550af0da85dea6377d1931bda5ba79..dd3db2c6beb22011de2f1a352a919a8893a903f5 100644
--- a/service/src/main/java/lcsb/mapviewer/services/interfaces/ICommentService.java
+++ b/service/src/main/java/lcsb/mapviewer/services/interfaces/ICommentService.java
@@ -60,7 +60,7 @@ public interface ICommentService {
 	 */
 	void deleteComment(User loggedUser, String commentId, String reason);
 	
-	void deleteComment(Comment comment, AuthenticationToken token) throws UserAccessException;
+	void deleteComment(Comment comment, AuthenticationToken token, String reason) throws UserAccessException;
 
 	/**
 	 * Method returns all comments for a given map.