diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/QueryException.java b/rest-api/src/main/java/lcsb/mapviewer/api/QueryException.java
index a6df0faec0db1460c28c325f6b49f1ec8e643bd2..6e5ea787241dc773cad190cc4bb4875a2b31c01a 100644
--- a/rest-api/src/main/java/lcsb/mapviewer/api/QueryException.java
+++ b/rest-api/src/main/java/lcsb/mapviewer/api/QueryException.java
@@ -6,4 +6,8 @@ public class QueryException extends Exception {
 		super(message);
 	}
 
+	public QueryException(String message, Exception reason) {
+		super(message, reason);
+	}
+
 }
diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/comment/CommentController.java b/rest-api/src/main/java/lcsb/mapviewer/api/comment/CommentController.java
index ce5c9fee4b4b6a2d17b6f1d2d16333e527e51a43..be23be4cb05706cc1a9d79d41aee654a4554202c 100644
--- a/rest-api/src/main/java/lcsb/mapviewer/api/comment/CommentController.java
+++ b/rest-api/src/main/java/lcsb/mapviewer/api/comment/CommentController.java
@@ -1,5 +1,6 @@
 package lcsb.mapviewer.api.comment;
 
+import java.awt.geom.Point2D;
 import java.util.List;
 import java.util.Map;
 
@@ -22,11 +23,34 @@ public class CommentController extends BaseController {
 	private CommentRestImpl commentController;
 
 	@RequestMapping(value = "/getCommentList", method = { RequestMethod.GET, RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE })
-	public List<Map<String,Object>> getOverlayList(@RequestParam(value = "token") String token, @RequestParam(value = "projectId") String projectId,
+	public List<Map<String, Object>> getOverlayList(@RequestParam(value = "token") String token, @RequestParam(value = "projectId") String projectId,
 			@RequestParam(value = "columns", defaultValue = "") String columns) throws SecurityException, QueryException {
 		return commentController.getCommentList(token, projectId, columns);
 	}
 
+	@RequestMapping(value = "/addComment", method = { RequestMethod.GET, RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE })
+	public Map<String, Object> addComment(@RequestParam(value = "token") String token, @RequestParam(value = "projectId") String projectId,
+			@RequestParam(value = "elementType", defaultValue = "POINT") String elementType, @RequestParam(value = "elementId", defaultValue = "") 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,
+			@RequestParam(value = "modelId") String modelId) throws SecurityException, 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 commentController
+				.addComment(token, projectId, elementType, elementId, name, email, content, pinned.toLowerCase().equals("true"), pointCoordinates, modelId);
+	}
+
 	/**
 	 * @return the overlayController
 	 * @see #commentController
diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/comment/CommentRestImpl.java b/rest-api/src/main/java/lcsb/mapviewer/api/comment/CommentRestImpl.java
index 4309e028aacde014dd9f51446fa999373c42cfbc..253474b53caefc6fcff1135458f53f0a7c489af3 100644
--- a/rest-api/src/main/java/lcsb/mapviewer/api/comment/CommentRestImpl.java
+++ b/rest-api/src/main/java/lcsb/mapviewer/api/comment/CommentRestImpl.java
@@ -290,4 +290,46 @@ public class CommentRestImpl {
 		this.elementDao = elementDao;
 	}
 
+	public Map<String, Object> addComment(String token, String projectId, String elementType, String elementId, String name, String email, String content,
+			boolean pinned, Point2D pointCoordinates, String submodelId) throws QueryException, SecurityException {
+		AuthenticationToken authenticationToken = userService.getToken(token);
+		Model model = modelService.getLastModelByProjectId(projectId, authenticationToken);
+		if (model == null) {
+			throw new QueryException("Project with given id doesn't exist");
+		}
+
+		Integer modelId = null;
+		try {
+			modelId = Integer.valueOf(submodelId);
+		} catch (NumberFormatException e) {
+			throw new QueryException("Invalid model identifier for given project", e);
+		}
+		Model submodel = model.getSubmodelById(modelId);
+		if (submodel == null) {
+			throw new QueryException("Invalid model identifier for given project");
+		}
+		Object commentedObject;
+		if (elementType.equals(ElementIdentifierType.ALIAS.getJsName())) {
+			commentedObject = submodel.getElementByDbId(Integer.valueOf(elementId));
+			if (commentedObject == null) {
+				throw new QueryException("Invalid commented element identifier for given project");
+			}
+		} else if (elementType.equals(ElementIdentifierType.REACTION.getJsName())) {
+			commentedObject = submodel.getReactionByDbId(Integer.valueOf(elementId));
+			if (commentedObject == null) {
+				throw new QueryException("Invalid commented element identifier for given project");
+			}
+		} else if (elementType.equals(ElementIdentifierType.POINT.getJsName())) {
+			commentedObject = null;
+		} else {
+			throw new QueryException("Unknown type of commented object: " + elementType);
+		}
+
+		commentService.addComment(name, email, content, model, pointCoordinates, commentedObject, pinned, submodel);
+		// TODO Auto-generated method stub
+		Map<String, Object> result = new HashMap<>();
+		result.put("status", "OK");
+		return result;
+	}
+
 }
diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/overlay/OverlayRestImpl.java b/rest-api/src/main/java/lcsb/mapviewer/api/overlay/OverlayRestImpl.java
index b23e1052b6fb6f4a61f7145eeb54e4fd2b0c0cc8..5b567c93f7f12ccdbece39aaa2553f2ab004bc47 100644
--- a/rest-api/src/main/java/lcsb/mapviewer/api/overlay/OverlayRestImpl.java
+++ b/rest-api/src/main/java/lcsb/mapviewer/api/overlay/OverlayRestImpl.java
@@ -15,6 +15,7 @@ import lcsb.mapviewer.services.SecurityException;
 import lcsb.mapviewer.services.interfaces.ILayoutService;
 import lcsb.mapviewer.services.interfaces.IModelService;
 import lcsb.mapviewer.services.interfaces.IUserService;
+import lcsb.mapviewer.services.search.data.ElementIdentifier.ElementIdentifierType;
 import lcsb.mapviewer.services.search.layout.LightLayoutAliasView;
 import lcsb.mapviewer.services.search.layout.LightLayoutReactionView;
 import lcsb.mapviewer.services.view.AuthenticationToken;
@@ -103,7 +104,7 @@ public class OverlayRestImpl {
 		List<LightLayoutAliasView> speciesList = layoutService.getAliasesForLayout(model, overlayId, authenticationToken);
 		for (LightLayoutAliasView lightLayoutAliasView : speciesList) {
 			Map<String, Object> element = new HashMap<>();
-			element.put("type", "ALIAS");
+			element.put("type", ElementIdentifierType.ALIAS);
 			element.put("overlayContent", lightLayoutAliasView);
 			result.add(element);
 		}
@@ -111,7 +112,7 @@ public class OverlayRestImpl {
 		List<LightLayoutReactionView> reactions = layoutService.getReactionsForLayout(model, overlayId, authenticationToken);
 		for (LightLayoutReactionView lightReactionView : reactions) {
 			Map<String, Object> element = new HashMap<>();
-			element.put("type", "REACTION");
+			element.put("type", ElementIdentifierType.REACTION);
 			element.put("overlayContent", lightReactionView);
 			result.add(element);
 		}
diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/project/ProjectController.java b/rest-api/src/main/java/lcsb/mapviewer/api/project/ProjectController.java
index d68310bbe473ea3b8ee7dcd2dc35fed60cb7ea47..b023eb744c9baa65f6459168484019e1f4024e4d 100644
--- a/rest-api/src/main/java/lcsb/mapviewer/api/project/ProjectController.java
+++ b/rest-api/src/main/java/lcsb/mapviewer/api/project/ProjectController.java
@@ -1,5 +1,6 @@
 package lcsb.mapviewer.api.project;
 
+import java.awt.geom.Point2D;
 import java.util.List;
 import java.util.Map;
 
@@ -11,9 +12,8 @@ import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
 import lcsb.mapviewer.api.BaseController;
+import lcsb.mapviewer.api.QueryException;
 import lcsb.mapviewer.services.SecurityException;
-import lcsb.mapviewer.services.search.ElementView;
-import lcsb.mapviewer.services.search.data.LightAliasView;
 
 @RestController
 @RequestMapping("/project")
@@ -39,4 +39,25 @@ public class ProjectController extends BaseController {
 		return projectController.getReactions(projectId, id, columns, token);
 	}
 
+	@RequestMapping(value = "/getClosestElementsByCoordinates", method = { RequestMethod.GET, RequestMethod.POST },
+			produces = { MediaType.APPLICATION_JSON_VALUE })
+	public List<Map<String, Object>> getClosestElementsByCoordinates(@RequestParam(value = "projectId") String projectId,
+			@RequestParam(value = "modelId") String modelId, @RequestParam(value = "token") String token, @RequestParam(value = "coordinates") String coordinates,
+			@RequestParam(value = "count", defaultValue = "5") Integer count) throws QueryException, SecurityException {
+		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 projectController.getClosestElementsByCoordinates(projectId, modelId, token, pointCoordinates, Integer.valueOf(count));
+	}
+
 }
\ No newline at end of file
diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/project/ProjectRestImpl.java b/rest-api/src/main/java/lcsb/mapviewer/api/project/ProjectRestImpl.java
index 2c41521cc69a224e217f1ec3c538d4f91368d10b..4b207934092e19dfd3fc062477ad26577080bac6 100644
--- a/rest-api/src/main/java/lcsb/mapviewer/api/project/ProjectRestImpl.java
+++ b/rest-api/src/main/java/lcsb/mapviewer/api/project/ProjectRestImpl.java
@@ -1,5 +1,6 @@
 package lcsb.mapviewer.api.project;
 
+import java.awt.geom.Point2D;
 import java.awt.geom.Rectangle2D;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -8,20 +9,27 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.commons.lang3.StringUtils;
 import org.apache.log4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.bind.annotation.RequestParam;
 
+import lcsb.mapviewer.common.exception.InvalidStateException;
 import lcsb.mapviewer.model.Project;
 import lcsb.mapviewer.model.map.model.Model;
+import lcsb.mapviewer.model.map.reaction.Modifier;
+import lcsb.mapviewer.model.map.reaction.Product;
+import lcsb.mapviewer.model.map.reaction.Reactant;
 import lcsb.mapviewer.model.map.reaction.Reaction;
 import lcsb.mapviewer.model.map.species.Element;
 import lcsb.mapviewer.services.SecurityException;
 import lcsb.mapviewer.services.UserAccessException;
 import lcsb.mapviewer.services.interfaces.IModelService;
 import lcsb.mapviewer.services.interfaces.IProjectService;
+import lcsb.mapviewer.services.interfaces.ISearchService;
 import lcsb.mapviewer.services.interfaces.IUserService;
+import lcsb.mapviewer.services.search.data.ElementIdentifier.ElementIdentifierType;
 import lcsb.mapviewer.services.search.data.LightReactionView;
 import lcsb.mapviewer.services.view.AnnotationViewFactory;
 
@@ -38,6 +46,9 @@ public class ProjectRestImpl {
 	@Autowired
 	private IModelService		modelService;
 
+	@Autowired
+	private ISearchService	searchService;
+
 	@Autowired
 	AnnotationViewFactory		annotationViewFactory;
 
@@ -92,6 +103,36 @@ public class ProjectRestImpl {
 		return result;
 	}
 
+	public List<Map<String, Object>> getClosestElementsByCoordinates(String projectId, String modelId, String token, Point2D coordinates, Integer count)
+			throws UserAccessException, SecurityException {
+		List<Map<String, Object>> resultMap = new ArrayList<>();
+
+		Model model = modelService.getLastModelByProjectId(projectId, userService.getToken(token));
+
+		Model submodel = model.getSubmodelById(modelId);
+
+		List<Object> elements = searchService.getClosestElements(submodel, coordinates, count);
+		for (Object object : elements) {
+			Map<String, Object> result = new HashMap<>();
+			if (object instanceof Element) {
+				result.put("type", ElementIdentifierType.ALIAS);
+				Element element = (Element) object;
+				result.put("id", element.getId());
+				result.put("modelId", element.getModel().getId());
+			} else if (object instanceof Reaction) {
+				result.put("type", ElementIdentifierType.REACTION);
+				Reaction element = (Reaction) object;
+				result.put("id", element.getId());
+				result.put("modelId", element.getModel().getId());
+
+			} else {
+				throw new InvalidStateException("Unknown type of result: " + object.getClass());
+			}
+			resultMap.add(result);
+		}
+		return resultMap;
+	};
+
 	public List<Map<String, Object>> getReactions(String projectId, String id, String columns, String token) throws UserAccessException, SecurityException {
 		Model model = modelService.getLastModelByProjectId(projectId, userService.getToken(token));
 		Set<Integer> ids = new HashSet<>();
@@ -127,10 +168,30 @@ public class ProjectRestImpl {
 				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("lines")) {
@@ -212,10 +273,14 @@ public class ProjectRestImpl {
 		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");
 		} else {
 			for (String str : columns.split(",")) {
 				columnsSet.add(str);
@@ -241,4 +306,21 @@ public class ProjectRestImpl {
 		this.modelService = modelService;
 	}
 
+	/**
+	 * @return the searchService
+	 * @see #searchService
+	 */
+	public ISearchService getSearchService() {
+		return searchService;
+	}
+
+	/**
+	 * @param searchService
+	 *          the searchService to set
+	 * @see #searchService
+	 */
+	public void setSearchService(ISearchService searchService) {
+		this.searchService = searchService;
+	}
+
 }
diff --git a/rest-api/src/test/java/lcsb/mapviewer/api/project/ProjectRestImplTest.java b/rest-api/src/test/java/lcsb/mapviewer/api/project/ProjectRestImplTest.java
index 9911c0d844cdb80dc966fbc6ef11cf122e68f708..f3ffe752fd34822f4d89bd2f9e69af0afc49304e 100644
--- a/rest-api/src/test/java/lcsb/mapviewer/api/project/ProjectRestImplTest.java
+++ b/rest-api/src/test/java/lcsb/mapviewer/api/project/ProjectRestImplTest.java
@@ -1,9 +1,12 @@
 package lcsb.mapviewer.api.project;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyString;
 
+import java.awt.geom.Point2D;
+import java.util.List;
 import java.util.Map;
 
 import org.apache.log4j.Logger;
@@ -22,10 +25,10 @@ public class ProjectRestImplTest extends RestTestFunctions {
 	Logger					logger = Logger.getLogger(ProjectRestImplTest.class);
 
 	@Autowired
-	ProjectRestImpl	projectRestImpl;
+	ProjectRestImpl	_projectRestImpl;
 
 	@Autowired
-	IModelService modelService;
+	IModelService		modelService;
 
 	@AfterClass
 	public static void tearDownAfterClass() throws Exception {
@@ -42,11 +45,8 @@ public class ProjectRestImplTest extends RestTestFunctions {
 	@Test
 	public void testGetElementsProcessAllColumns() throws Exception {
 		try {
-			Model model = super.getModelForFile("testFiles/model/sample.xml", true);
-			IModelService mockModelService = Mockito.mock(IModelService.class);
-			Mockito.when(mockModelService.getLastModelByProjectId(anyString(), any())).thenReturn(model);
-			projectRestImpl.setModelService(mockModelService);
-			for (Map<String, Object> element : projectRestImpl.getElements("sample", "", "", token.getId())) {
+			ProjectRestImpl projectRest = createMockProjectRest("testFiles/model/sample.xml");
+			for (Map<String, Object> element : projectRest.getElements("sample", "", "", token.getId())) {
 				for (String paramName : element.keySet()) {
 					Object val = element.get(paramName);
 					String paramValue = "";
@@ -59,9 +59,28 @@ public class ProjectRestImplTest extends RestTestFunctions {
 		} catch (Exception e) {
 			e.printStackTrace();
 			throw e;
-		} finally {
-			projectRestImpl.setModelService(modelService);
 		}
 	}
 
+	@Test
+	public void testGetClosestElementsByCoordinates() throws Exception {
+		try {
+			ProjectRestImpl projectRest = createMockProjectRest("testFiles/model/sample.xml");
+			int count = 3;
+			List<Map<String, Object>> result = projectRest.getClosestElementsByCoordinates("sample", "0", token.getId(), new Point2D.Double(1, 2), count);
+			assertEquals(count, result.size());
+		} catch (Exception e) {
+			e.printStackTrace();
+			throw e;
+		}
+	}
+
+	private ProjectRestImpl createMockProjectRest(String string) throws Exception {
+		Model model = super.getModelForFile(string, true);
+		IModelService mockModelService = Mockito.mock(IModelService.class);
+		Mockito.when(mockModelService.getLastModelByProjectId(anyString(), any())).thenReturn(model);
+		_projectRestImpl.setModelService(mockModelService);
+		return _projectRestImpl;
+	}
+
 }
diff --git a/service/src/main/java/lcsb/mapviewer/services/impl/SearchService.java b/service/src/main/java/lcsb/mapviewer/services/impl/SearchService.java
index cec3c35b2c82b2db77c86e476718286966e6c284..05986fdeeb56ffe5b5767a7662ca62c61e30508c 100644
--- a/service/src/main/java/lcsb/mapviewer/services/impl/SearchService.java
+++ b/service/src/main/java/lcsb/mapviewer/services/impl/SearchService.java
@@ -533,7 +533,7 @@ public class SearchService implements ISearchService {
 		// probably this could be improved algorithmitically, right now all objects
 		// are sorted by distance, and numberOfElements closest are chosen as a list
 		// of results
-		List<DistanceToObject> tmpList = new ArrayList<DistanceToObject>();
+		List<DistanceToObject> tmpList = new ArrayList<>();
 		for (Reaction reaction : model.getReactions()) {
 			tmpList.add(new DistanceToObject(reaction, point));
 		}