diff --git a/frontend-js/src/main/js/gui/admin/AddProjectDialog.js b/frontend-js/src/main/js/gui/admin/AddProjectDialog.js
index 5811bd86c8e30480f3682a6b2c5893a37006d79b..26dea5dfd6dd9bdc3a4793fc5dead2f571d1f640 100644
--- a/frontend-js/src/main/js/gui/admin/AddProjectDialog.js
+++ b/frontend-js/src/main/js/gui/admin/AddProjectDialog.js
@@ -590,7 +590,10 @@ AddProjectDialog.prototype.onSaveClicked = function () {
       "disease": self.getDisease(),
       "organism": self.getOrganism(),
       "sbgn": self.isSbgn(),
-      "semantic-zoom": self.isSemanticZooming()
+      "semantic-zoom": self.isSemanticZooming(),
+      "annotate": self.isAnnotateAutomatically(),
+      "verify-annotations": self.isVerifyAnnotations(),
+
     };
     return ServerConnector.addProject(options);
   });
diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/projects/ProjectRestImpl.java b/rest-api/src/main/java/lcsb/mapviewer/api/projects/ProjectRestImpl.java
index 652a49ce9eec5e368d1d683c4a2fc983172d534c..b788a8feb8c46cccf085cc3aacc6986f40341f21 100644
--- a/rest-api/src/main/java/lcsb/mapviewer/api/projects/ProjectRestImpl.java
+++ b/rest-api/src/main/java/lcsb/mapviewer/api/projects/ProjectRestImpl.java
@@ -62,6 +62,7 @@ import lcsb.mapviewer.model.user.PrivilegeType;
 import lcsb.mapviewer.model.user.User;
 import lcsb.mapviewer.services.SecurityException;
 import lcsb.mapviewer.services.interfaces.ILayoutService;
+import lcsb.mapviewer.services.interfaces.IProjectService;
 import lcsb.mapviewer.services.utils.ColorSchemaReader;
 import lcsb.mapviewer.services.utils.CreateProjectParams;
 import lcsb.mapviewer.services.utils.data.BuildInLayout;
@@ -72,483 +73,500 @@ import lcsb.mapviewer.services.view.OverviewImageViewFactory;
 @Transactional(value = "txManager")
 public class ProjectRestImpl extends BaseRestImpl {
 
-	/**
-	 * Constant defining size of the array returned by
-	 * {@link PathIterator#currentSegment(double[])} method. More nformation can
-	 * be found <a href=
-	 * "http://docs.oracle.com/javase/7/docs/api/java/awt/geom/PathIterator.html#currentSegment(double[])"
-	 * >here</a>
-	 */
-	private static final int				 PATH_ITERATOR_SEGMENT_SIZE	= 6;
-
-	/**
-	 * Default class logger.
-	 */
-	private Logger									 logger											= Logger.getLogger(ProjectRestImpl.class);
-
-	@Autowired
-	private PublicationsRestImpl		 publicationsRestImpl;
-
-	@Autowired
-	private ILayoutService					 layoutService;
-
-	@Autowired
-	private OverviewImageViewFactory factory;
-
-	public ProjectMetaData getProject(String projectId, String token) throws SecurityException, ObjectNotFoundException {
-		AuthenticationToken authenticationToken = getUserService().getToken(token);
-		Project project = getProjectService().getProjectByProjectId(projectId, authenticationToken);
-		if (project == null) {
-			throw new ObjectNotFoundException("Project with given id doesn't exist");
-		}
-		ProjectMetaData result = createData(project);
-		return result;
-	}
-
-	private ProjectMetaData createData(Project project) {
-		ProjectMetaData result = new ProjectMetaData();
-
-		result.setName(project.getName());
-		result.setProjectId(project.getProjectId());
-		result.setIdObject(project.getId());
-		result.setVersion(project.getVersion());
-		result.setNotifyEmail(project.getNotifyEmail());
-		if (project.getStatus() != null) {
-			result.setStatus(project.getStatus().toString());
-		}
-		result.setProgress(project.getProgress());
-
-		result.setOverviewImageViews(factory.createList(project.getOverviewImages()));
-
-		Set<OverviewImage> set = new HashSet<>();
-		set.addAll(project.getOverviewImages());
-		for (OverviewImage image : project.getOverviewImages()) {
-			for (OverviewLink ol : image.getLinks()) {
-				if (ol instanceof OverviewImageLink) {
-					set.remove(((OverviewImageLink) ol).getLinkedOverviewImage());
-				}
-			}
-		}
-		if (set.size() > 0) {
-			result.setTopOverviewImage(factory.create(set.iterator().next()));
-		} else if (project.getOverviewImages().size() > 0) {
-			logger.warn("Cannot determine top level image. Taking first one. " + project.getOverviewImages().get(0).getFilename());
-			result.setTopOverviewImage(factory.create(project.getOverviewImages().get(0)));
-		}
-
-		if (project.getOrganism() != null) {
-			result.setOrganism(createAnnotation(project.getOrganism()));
-		}
-		if (project.getDisease() != null) {
-			result.setDisease(createAnnotation(project.getDisease()));
-		}
-
-		return result;
-	}
-
-	/**
-	 * @return the factory
-	 * @see #factory
-	 */
-	public OverviewImageViewFactory getFactory() {
-		return factory;
-	}
-
-	/**
-	 * @param factory
-	 *          the factory to set
-	 * @see #factory
-	 */
-	public void setFactory(OverviewImageViewFactory factory) {
-		this.factory = factory;
-	}
-
-	public FileEntry getSource(String token, String projectId) throws SecurityException, QueryException {
-		AuthenticationToken authenticationToken = getUserService().getToken(token);
-		Project project = getProjectService().getProjectByProjectId(projectId, authenticationToken);
-		if (project == null) {
-			throw new ObjectNotFoundException("Project with given id doesn't exist");
-		}
-		return project.getInputData();
-	}
-
-	public FileEntry getModelAsImage(String token, String projectId, String modelId, String handlerClass, String backgroundOverlayId, String overlayIds,
-			String zoomLevel, String polygonString)
-			throws SecurityException, QueryException, IOException, InvalidColorSchemaException, CommandExecutionException, DrawingException {
-		AuthenticationToken authenticationToken = getUserService().getToken(token);
-		User user = getUserService().getUserByToken(authenticationToken);
-
-		Model topModel = getModelService().getLastModelByProjectId(projectId, authenticationToken);
-		if (topModel == null) {
-			throw new ObjectNotFoundException("Project with given id doesn't exist");
-		}
-
-		Model originalModel = topModel.getSubmodelById(modelId);
-
-		if (originalModel == null) {
-			throw new ObjectNotFoundException("Model with given id doesn't exist");
-		}
-
-		Layout overlay = null;
-		if (!backgroundOverlayId.equals("")) {
-			overlay = topModel.getLayoutByIdentifier(Integer.valueOf(backgroundOverlayId));
-
-			if (overlay == null) {
-				throw new ObjectNotFoundException("Unknown overlay in model. Layout.id=" + backgroundOverlayId);
-			}
-		} else {
-			if (topModel.getLayouts().size() > 0) {
-				overlay = topModel.getLayouts().get(0);
-			}
-		}
-
-		Model colorModel = new CopyCommand(originalModel).execute();
-		if (overlay != null) {
-			if (overlay.getInputData() != null) {
-				ColorSchemaReader reader = new ColorSchemaReader();
-				Collection<ColorSchema> schemas = reader.readColorSchema(overlay.getInputData().getFileContent());
-
-				new ColorModelCommand(colorModel, schemas, getUserService().getColorExtractorForUser(user)).execute();
-			} else if (overlay.getTitle().equals(BuildInLayout.CLEAN.getTitle())) {
-				// this might not return true if we change CLEAN.title in future...
-
-				// if it's clean then remove coloring
-				new ClearColorModelCommand(colorModel).execute();
-			} else if (overlay.isHierarchicalView()) {
-				new SetFixedHierarchyLevelCommand(colorModel, overlay.getHierarchyViewLevel()).execute();
-			}
-		}
-
-		Integer level = Configuration.MIN_ZOOM_LEVEL;
-		if (!zoomLevel.equals("")) {
-			level = Integer.valueOf(zoomLevel);
-		}
-
-		// transform polygon
-		CoordinationConverter cc = new CoordinationConverter(colorModel);
-		Double minX = originalModel.getWidth();
-		Double minY = originalModel.getHeight();
-		Double maxX = 0.0;
-		Double maxY = 0.0;
-		Path2D polygon = cc.latLngToPolygon(polygonString);
-
-		PathIterator pathIter = polygon.getPathIterator(null);
-		while (!pathIter.isDone()) {
-			final double[] segment = new double[PATH_ITERATOR_SEGMENT_SIZE];
-			if (pathIter.currentSegment(segment) != PathIterator.SEG_CLOSE) {
-				minX = Math.min(minX, segment[0]);
-				maxX = Math.max(maxX, segment[0]);
-				minY = Math.min(minY, segment[1]);
-				maxY = Math.max(maxY, segment[1]);
-			}
-			pathIter.next();
-		}
-
-		maxX = Math.min(originalModel.getWidth(), maxX);
-		maxY = Math.min(originalModel.getHeight(), maxY);
-		minX = Math.max(0.0, minX);
-		minY = Math.max(0.0, minY);
-
-		Double scale = Math.max(originalModel.getHeight(), originalModel.getWidth()) / (originalModel.getTileSize());
-
-		for (int i = level; i > Configuration.MIN_ZOOM_LEVEL; i--) {
-			scale /= 2;
-		}
-
-		ColorExtractor colorExtractor = getUserService().getColorExtractorForUser(user);
-
-		Params params = new Params().//
-				x(minX).//
-				y(minY).//
-				height((maxY - minY) / scale).//
-				width((maxX - minX) / scale).//
-				level(level - Configuration.MIN_ZOOM_LEVEL).//
-				nested(false).// automatically set nested view as invalid
-				scale(scale).//
-				colorExtractor(colorExtractor).//
-				sbgn(topModel.getProject().isSbgnFormat()).//
-				model(colorModel);
-		if (overlay != null) {
-			params.nested(overlay.isHierarchicalView());
-		}
-		List<Integer> visibleLayoutIds = deserializeIdList(overlayIds);
-		for (Integer integer : visibleLayoutIds) {
-			Map<Object, ColorSchema> map = layoutService.getElementsForLayout(colorModel, integer, authenticationToken);
-			params.addVisibleLayout(map);
-		}
-
-		ImageGenerators imageGenerator = new ImageGenerators();
-		String extension = imageGenerator.getExtension(handlerClass);
-		File file = File.createTempFile("map", "." + extension);
-
-		imageGenerator.generate(handlerClass, params, file.getAbsolutePath());
-
-		FileEntry entry = new UploadedFileEntry();
-		entry.setOriginalFileName("map." + extension);
-		entry.setFileContent(IOUtils.toByteArray(new FileInputStream(file)));
-		file.delete();
-		return entry;
-
-	}
-
-	private List<Integer> deserializeIdList(String overlayIds) {
-		List<Integer> result = new ArrayList<>();
-		String[] tmp = overlayIds.split(",");
-		for (String string : tmp) {
-			if (!string.equals("")) {
-				result.add(Integer.valueOf(string));
-			}
-		}
-		return result;
-	}
-
-	public FileEntry getModelAsModelFile(String token, String projectId, String modelId, String handlerClass, String backgroundOverlayId, String overlayIds,
-			String zoomLevel, String polygonString) throws SecurityException, QueryException, IOException, InvalidColorSchemaException, CommandExecutionException,
-			ConverterException, InconsistentModelException {
-		AuthenticationToken authenticationToken = getUserService().getToken(token);
-
-		Model topModel = getModelService().getLastModelByProjectId(projectId, authenticationToken);
-		if (topModel == null) {
-			throw new ObjectNotFoundException("Project with given id doesn't exist");
-		}
-
-		Model originalModel = topModel.getSubmodelById(modelId);
-
-		if (originalModel == null) {
-			throw new ObjectNotFoundException("Model with given id doesn't exist");
-		}
-
-		CoordinationConverter cc = new CoordinationConverter(originalModel);
-		Path2D polygon = cc.latLngToPolygon(polygonString);
-
-		// create model bounded by the polygon
-		SubModelCommand subModelCommand = new SubModelCommand(originalModel, polygon);
-		Model part = subModelCommand.execute();
-
-		IConverter parser = getModelParser(handlerClass);
-		InputStream is = parser.exportModelToInputStream(part);
-
-		String fileExtension = parser.getFileExtension();
-
-		FileEntry entry = new UploadedFileEntry();
-		entry.setOriginalFileName("model." + fileExtension);
-		entry.setFileContent(IOUtils.toByteArray(is));
-		return entry;
-
-	}
-
-	public Map<String, Object> getStatistics(String projectId, String token) throws SecurityException, ObjectNotFoundException {
-		Map<String, Object> result = new HashMap<String, Object>();
-		AuthenticationToken authenticationToken = getUserService().getToken(token);
-
-		Model model = getModelService().getLastModelByProjectId(projectId, authenticationToken);
-		if (model == null) {
-			throw new ObjectNotFoundException("Project with given id doesn't exist");
-		}
-
-		Map<MiriamType, Integer> elementAnnotations = new HashMap<>();
-		for (MiriamType mt : MiriamType.values()) {
-			elementAnnotations.put(mt, 0);
-		}
-		Set<Model> models = new HashSet<>();
-		models.add(model);
-		models.addAll(model.getSubmodels());
-
-		for (Model model2 : models) {
-			for (Element alias : model2.getElements()) {
-				for (MiriamData md : alias.getMiriamData()) {
-					Integer amount = elementAnnotations.get(md.getDataType());
-					amount += 1;
-					elementAnnotations.put(md.getDataType(), amount);
-				}
-			}
-		}
-		result.put("elementAnnotations", elementAnnotations);
-
-		Map<MiriamType, Integer> reactionAnnotations = new HashMap<>();
-		for (MiriamType mt : MiriamType.values()) {
-			reactionAnnotations.put(mt, 0);
-		}
-		for (Model model2 : models) {
-			for (Reaction reaction : model2.getReactions()) {
-				for (MiriamData md : reaction.getMiriamData()) {
-					Integer amount = reactionAnnotations.get(md.getDataType());
-					amount += 1;
-					reactionAnnotations.put(md.getDataType(), amount);
-				}
-			}
-		}
-
-		result.put("reactionAnnotations", reactionAnnotations);
-
-		result.put("publications", publicationsRestImpl.getPublications(models).size());
-
-		return result;
-	}
-
-	public List<ProjectMetaData> getProjects(String token) throws SecurityException {
-		AuthenticationToken authenticationToken = getUserService().getToken(token);
-		List<Project> projects = getProjectService().getAllProjects(authenticationToken);
-		List<ProjectMetaData> result = new ArrayList<>();
-		for (Project project : projects) {
-			result.add(createData(project));
-		}
-		return result;
-	}
-
-	public ProjectMetaData updateProject(String token, String projectId, Map<String, Object> data) throws SecurityException, QueryException {
-		AuthenticationToken authenticationToken = getUserService().getToken(token);
-		Project project = getProjectService().getProjectByProjectId(projectId, authenticationToken);
-		if (project == null) {
-			throw new ObjectNotFoundException("Project with given id doesn't exist");
-		}
-		boolean canModify = getUserService().userHasPrivilege(authenticationToken, PrivilegeType.ADD_MAP);
-		if (!canModify) {
-			throw new SecurityException("You cannot update projects");
-		}
-		Set<String> fields = data.keySet();
-		for (String fieldName : fields) {
-			Object value = data.get(fieldName);
-			String stringValue = null;
-			if (value instanceof String) {
-				stringValue = (String) value;
-			}
-			if (fieldName.equalsIgnoreCase("version")) {
-				project.setVersion((String) value);
-			} else if (fieldName.equalsIgnoreCase("id")) {
-				try {
-					int id = Integer.parseInt(stringValue);
-					if (id != project.getId()) {
-						throw new QueryException("Invalid id: " + stringValue);
-					}
-				} catch (NumberFormatException e) {
-					throw new QueryException("Invalid id: " + stringValue);
-				}
-			} else if (fieldName.equalsIgnoreCase("projectId")) {
-				if (!project.getProjectId().equalsIgnoreCase(stringValue)) {
-					throw new QueryException("You cannot modify projectId");
-				}
-			} else if (fieldName.equalsIgnoreCase("name")) {
-				project.setName((String) value);
-			} else if (fieldName.equalsIgnoreCase("notifyEmail")) {
-				project.setNotifyEmail(stringValue);
-			} else if (fieldName.equalsIgnoreCase("organism")) {
-				MiriamData organism = updateMiriamData(project.getOrganism(), value);
-				project.setOrganism(organism);
-			} else if (fieldName.equalsIgnoreCase("disease")) {
-				MiriamData disease = updateMiriamData(project.getDisease(), value);
-				project.setDisease(disease);
-			} else {
-				throw new QueryException("Unknown field: " + fieldName);
-			}
-		}
-		getProjectService().updateProject(project);
-		return getProject(projectId, token);
-	}
-
-	private MiriamData updateMiriamData(MiriamData organism, Object res) {
-		if (res == null) {
-			return null;
-		}
-		if (organism == null) {
-			organism = new MiriamData();
-		}
-
-		if (res instanceof Map) {
-			@SuppressWarnings("unchecked")
-			Map<String, Object> map = (Map<String, Object>) res;
-			organism.setDataType(MiriamType.valueOf((String) map.get("type")));
-			organism.setResource((String) map.get("resource"));
-			return organism;
-		} else {
-			throw new InvalidArgumentException("invalid miriamdData: " + res);
-		}
-	}
-
-	public ProjectMetaData addProject(String token, String projectId, MultiValueMap<String, String> data, String path)
-			throws SecurityException, QueryException, IOException {
-		AuthenticationToken authenticationToken = getUserService().getToken(token);
-		User user = getUserService().getUserByToken(authenticationToken);
-		Project project = getProjectService().getProjectByProjectId(projectId, authenticationToken);
-		if (project != null) {
-			throw new ObjectExistsException("Project with given id already exists");
-		}
-		CreateProjectParams params = new CreateProjectParams();
-		String directory = path + "/../map_images/" + md5(projectId) + "/";
-		String fileContent = getFirstValue(data.get("file-content"));
-		if (fileContent == null) {
-			throw new QueryException("file-content is obligatory");
-		}
-		String parserClass = getFirstValue(data.get("parser"));
-		if (parserClass == null) {
-			throw new QueryException("parser is obligatory");
-		}
-		IConverter parser = getModelParser(parserClass);
-
-		params.addUser(user.getLogin(), null);
-		params.async(true);
-		params.parser(parser);
-		params.authenticationToken(authenticationToken);
-		params.autoResize(getFirstValue(data.get("auto-resize")));
-		params.cacheModel(getFirstValue(data.get("cache")));
-		params.description(getFirstValue(data.get("description")));
-		params.images(true);
-		params.notifyEmail(getFirstValue(data.get("notify-email")));
-		params.projectDir(directory);
-		params.projectDisease(getFirstValue(data.get("disease")));
-		params.projectFile(new ByteArrayInputStream(fileContent.getBytes(StandardCharsets.UTF_8)));
-		params.projectId(projectId);
-		params.projectName(getFirstValue(data.get("name")));
-		params.projectOrganism(getFirstValue(data.get("organism")));
-		params.sbgnFormat(getFirstValue(data.get("sbgn")));
-		params.semanticZoom(getFirstValue(data.get("semantic-zoom")));
-		params.version(getFirstValue(data.get("version")));
-
-		getProjectService().createProject(params);
-		return getProject(projectId, token);
-	}
-
-	private String getFirstValue(List<String> list) {
-		if (list == null) {
-			return null;
-		}
-		if (list.size() > 0) {
-			return list.get(0);
-		}
-		return null;
-	}
-
-	/**
-	 * Method that computes md5 hash for a given {@link String}.
-	 * 
-	 * @param data
-	 *          input string
-	 * @return md5 hash for input string
-	 */
-	private String md5(String data) {
-		try {
-			MessageDigest md = MessageDigest.getInstance("MD5");
-			byte[] mdbytes = md.digest(data.getBytes());
-			StringBuffer sb = new StringBuffer();
-			for (int i = 0; i < mdbytes.length; i++) {
-				// CHECKSTYLE:OFF
-				// this magic formula transforms int into hex value
-				sb.append(Integer.toString((mdbytes[i] & 0xff) + 0x100, 16).substring(1));
-				// CHECKSTYLE:ON
-			}
-			return sb.toString();
-		} catch (NoSuchAlgorithmException e) {
-			logger.fatal("Problem with instance of MD5 encoder", e);
-		}
-
-		return null;
-	}
-
-	public ProjectMetaData removeProject(String token, String projectId, String path) throws ObjectNotFoundException, SecurityException {
-		AuthenticationToken authenticationToken = getUserService().getToken(token);
-		Project project = getProjectService().getProjectByProjectId(projectId, authenticationToken);
-		getProjectService().removeProject(project, path, true, authenticationToken);
-		return getProject(projectId, token);
-	}
+  /**
+   * Constant defining size of the array returned by
+   * {@link PathIterator#currentSegment(double[])} method. More nformation can be
+   * found <a href=
+   * "http://docs.oracle.com/javase/7/docs/api/java/awt/geom/PathIterator.html#currentSegment(double[])"
+   * >here</a>
+   */
+  private static final int PATH_ITERATOR_SEGMENT_SIZE = 6;
+
+  /**
+   * Default class logger.
+   */
+  private Logger logger = Logger.getLogger(ProjectRestImpl.class);
+
+  @Autowired
+  private PublicationsRestImpl publicationsRestImpl;
+
+  @Autowired
+  private ILayoutService layoutService;
+
+  @Autowired
+  private IProjectService projectService;
+
+  @Autowired
+  private OverviewImageViewFactory factory;
+
+  public ProjectMetaData getProject(String projectId, String token) throws SecurityException, ObjectNotFoundException {
+    AuthenticationToken authenticationToken = getUserService().getToken(token);
+    Project project = getProjectService().getProjectByProjectId(projectId, authenticationToken);
+    if (project == null) {
+      throw new ObjectNotFoundException("Project with given id doesn't exist");
+    }
+    ProjectMetaData result = createData(project);
+    return result;
+  }
+
+  private ProjectMetaData createData(Project project) {
+    ProjectMetaData result = new ProjectMetaData();
+
+    result.setName(project.getName());
+    result.setProjectId(project.getProjectId());
+    result.setIdObject(project.getId());
+    result.setVersion(project.getVersion());
+    result.setNotifyEmail(project.getNotifyEmail());
+    if (project.getStatus() != null) {
+      result.setStatus(project.getStatus().toString());
+    }
+    result.setProgress(project.getProgress());
+
+    result.setOverviewImageViews(factory.createList(project.getOverviewImages()));
+
+    Set<OverviewImage> set = new HashSet<>();
+    set.addAll(project.getOverviewImages());
+    for (OverviewImage image : project.getOverviewImages()) {
+      for (OverviewLink ol : image.getLinks()) {
+        if (ol instanceof OverviewImageLink) {
+          set.remove(((OverviewImageLink) ol).getLinkedOverviewImage());
+        }
+      }
+    }
+    if (set.size() > 0) {
+      result.setTopOverviewImage(factory.create(set.iterator().next()));
+    } else if (project.getOverviewImages().size() > 0) {
+      logger.warn(
+          "Cannot determine top level image. Taking first one. " + project.getOverviewImages().get(0).getFilename());
+      result.setTopOverviewImage(factory.create(project.getOverviewImages().get(0)));
+    }
+
+    if (project.getOrganism() != null) {
+      result.setOrganism(createAnnotation(project.getOrganism()));
+    }
+    if (project.getDisease() != null) {
+      result.setDisease(createAnnotation(project.getDisease()));
+    }
+
+    return result;
+  }
+
+  /**
+   * @return the factory
+   * @see #factory
+   */
+  public OverviewImageViewFactory getFactory() {
+    return factory;
+  }
+
+  /**
+   * @param factory
+   *          the factory to set
+   * @see #factory
+   */
+  public void setFactory(OverviewImageViewFactory factory) {
+    this.factory = factory;
+  }
+
+  public FileEntry getSource(String token, String projectId) throws SecurityException, QueryException {
+    AuthenticationToken authenticationToken = getUserService().getToken(token);
+    Project project = getProjectService().getProjectByProjectId(projectId, authenticationToken);
+    if (project == null) {
+      throw new ObjectNotFoundException("Project with given id doesn't exist");
+    }
+    return project.getInputData();
+  }
+
+  public FileEntry getModelAsImage(String token, String projectId, String modelId, String handlerClass,
+      String backgroundOverlayId, String overlayIds, String zoomLevel, String polygonString) throws SecurityException,
+      QueryException, IOException, InvalidColorSchemaException, CommandExecutionException, DrawingException {
+    AuthenticationToken authenticationToken = getUserService().getToken(token);
+    User user = getUserService().getUserByToken(authenticationToken);
+
+    Model topModel = getModelService().getLastModelByProjectId(projectId, authenticationToken);
+    if (topModel == null) {
+      throw new ObjectNotFoundException("Project with given id doesn't exist");
+    }
+
+    Model originalModel = topModel.getSubmodelById(modelId);
+
+    if (originalModel == null) {
+      throw new ObjectNotFoundException("Model with given id doesn't exist");
+    }
+
+    Layout overlay = null;
+    if (!backgroundOverlayId.equals("")) {
+      overlay = topModel.getLayoutByIdentifier(Integer.valueOf(backgroundOverlayId));
+
+      if (overlay == null) {
+        throw new ObjectNotFoundException("Unknown overlay in model. Layout.id=" + backgroundOverlayId);
+      }
+    } else {
+      if (topModel.getLayouts().size() > 0) {
+        overlay = topModel.getLayouts().get(0);
+      }
+    }
+
+    Model colorModel = new CopyCommand(originalModel).execute();
+    if (overlay != null) {
+      if (overlay.getInputData() != null) {
+        ColorSchemaReader reader = new ColorSchemaReader();
+        Collection<ColorSchema> schemas = reader.readColorSchema(overlay.getInputData().getFileContent());
+
+        new ColorModelCommand(colorModel, schemas, getUserService().getColorExtractorForUser(user)).execute();
+      } else if (overlay.getTitle().equals(BuildInLayout.CLEAN.getTitle())) {
+        // this might not return true if we change CLEAN.title in future...
+
+        // if it's clean then remove coloring
+        new ClearColorModelCommand(colorModel).execute();
+      } else if (overlay.isHierarchicalView()) {
+        new SetFixedHierarchyLevelCommand(colorModel, overlay.getHierarchyViewLevel()).execute();
+      }
+    }
+
+    Integer level = Configuration.MIN_ZOOM_LEVEL;
+    if (!zoomLevel.equals("")) {
+      level = Integer.valueOf(zoomLevel);
+    }
+
+    // transform polygon
+    CoordinationConverter cc = new CoordinationConverter(colorModel);
+    Double minX = originalModel.getWidth();
+    Double minY = originalModel.getHeight();
+    Double maxX = 0.0;
+    Double maxY = 0.0;
+    Path2D polygon = cc.latLngToPolygon(polygonString);
+
+    PathIterator pathIter = polygon.getPathIterator(null);
+    while (!pathIter.isDone()) {
+      final double[] segment = new double[PATH_ITERATOR_SEGMENT_SIZE];
+      if (pathIter.currentSegment(segment) != PathIterator.SEG_CLOSE) {
+        minX = Math.min(minX, segment[0]);
+        maxX = Math.max(maxX, segment[0]);
+        minY = Math.min(minY, segment[1]);
+        maxY = Math.max(maxY, segment[1]);
+      }
+      pathIter.next();
+    }
+
+    maxX = Math.min(originalModel.getWidth(), maxX);
+    maxY = Math.min(originalModel.getHeight(), maxY);
+    minX = Math.max(0.0, minX);
+    minY = Math.max(0.0, minY);
+
+    Double scale = Math.max(originalModel.getHeight(), originalModel.getWidth()) / (originalModel.getTileSize());
+
+    for (int i = level; i > Configuration.MIN_ZOOM_LEVEL; i--) {
+      scale /= 2;
+    }
+
+    ColorExtractor colorExtractor = getUserService().getColorExtractorForUser(user);
+
+    Params params = new Params().//
+        x(minX).//
+        y(minY).//
+        height((maxY - minY) / scale).//
+        width((maxX - minX) / scale).//
+        level(level - Configuration.MIN_ZOOM_LEVEL).//
+        nested(false).// automatically set nested view as invalid
+        scale(scale).//
+        colorExtractor(colorExtractor).//
+        sbgn(topModel.getProject().isSbgnFormat()).//
+        model(colorModel);
+    if (overlay != null) {
+      params.nested(overlay.isHierarchicalView());
+    }
+    List<Integer> visibleLayoutIds = deserializeIdList(overlayIds);
+    for (Integer integer : visibleLayoutIds) {
+      Map<Object, ColorSchema> map = layoutService.getElementsForLayout(colorModel, integer, authenticationToken);
+      params.addVisibleLayout(map);
+    }
+
+    ImageGenerators imageGenerator = new ImageGenerators();
+    String extension = imageGenerator.getExtension(handlerClass);
+    File file = File.createTempFile("map", "." + extension);
+
+    imageGenerator.generate(handlerClass, params, file.getAbsolutePath());
+
+    FileEntry entry = new UploadedFileEntry();
+    entry.setOriginalFileName("map." + extension);
+    entry.setFileContent(IOUtils.toByteArray(new FileInputStream(file)));
+    file.delete();
+    return entry;
+
+  }
+
+  private List<Integer> deserializeIdList(String overlayIds) {
+    List<Integer> result = new ArrayList<>();
+    String[] tmp = overlayIds.split(",");
+    for (String string : tmp) {
+      if (!string.equals("")) {
+        result.add(Integer.valueOf(string));
+      }
+    }
+    return result;
+  }
+
+  public FileEntry getModelAsModelFile(String token, String projectId, String modelId, String handlerClass,
+      String backgroundOverlayId, String overlayIds, String zoomLevel, String polygonString)
+      throws SecurityException, QueryException, IOException, InvalidColorSchemaException, CommandExecutionException,
+      ConverterException, InconsistentModelException {
+    AuthenticationToken authenticationToken = getUserService().getToken(token);
+
+    Model topModel = getModelService().getLastModelByProjectId(projectId, authenticationToken);
+    if (topModel == null) {
+      throw new ObjectNotFoundException("Project with given id doesn't exist");
+    }
+
+    Model originalModel = topModel.getSubmodelById(modelId);
+
+    if (originalModel == null) {
+      throw new ObjectNotFoundException("Model with given id doesn't exist");
+    }
+
+    CoordinationConverter cc = new CoordinationConverter(originalModel);
+    Path2D polygon = cc.latLngToPolygon(polygonString);
+
+    // create model bounded by the polygon
+    SubModelCommand subModelCommand = new SubModelCommand(originalModel, polygon);
+    Model part = subModelCommand.execute();
+
+    IConverter parser = getModelParser(handlerClass);
+    InputStream is = parser.exportModelToInputStream(part);
+
+    String fileExtension = parser.getFileExtension();
+
+    FileEntry entry = new UploadedFileEntry();
+    entry.setOriginalFileName("model." + fileExtension);
+    entry.setFileContent(IOUtils.toByteArray(is));
+    return entry;
+
+  }
+
+  public Map<String, Object> getStatistics(String projectId, String token)
+      throws SecurityException, ObjectNotFoundException {
+    Map<String, Object> result = new HashMap<String, Object>();
+    AuthenticationToken authenticationToken = getUserService().getToken(token);
+
+    Model model = getModelService().getLastModelByProjectId(projectId, authenticationToken);
+    if (model == null) {
+      throw new ObjectNotFoundException("Project with given id doesn't exist");
+    }
+
+    Map<MiriamType, Integer> elementAnnotations = new HashMap<>();
+    for (MiriamType mt : MiriamType.values()) {
+      elementAnnotations.put(mt, 0);
+    }
+    Set<Model> models = new HashSet<>();
+    models.add(model);
+    models.addAll(model.getSubmodels());
+
+    for (Model model2 : models) {
+      for (Element alias : model2.getElements()) {
+        for (MiriamData md : alias.getMiriamData()) {
+          Integer amount = elementAnnotations.get(md.getDataType());
+          amount += 1;
+          elementAnnotations.put(md.getDataType(), amount);
+        }
+      }
+    }
+    result.put("elementAnnotations", elementAnnotations);
+
+    Map<MiriamType, Integer> reactionAnnotations = new HashMap<>();
+    for (MiriamType mt : MiriamType.values()) {
+      reactionAnnotations.put(mt, 0);
+    }
+    for (Model model2 : models) {
+      for (Reaction reaction : model2.getReactions()) {
+        for (MiriamData md : reaction.getMiriamData()) {
+          Integer amount = reactionAnnotations.get(md.getDataType());
+          amount += 1;
+          reactionAnnotations.put(md.getDataType(), amount);
+        }
+      }
+    }
+
+    result.put("reactionAnnotations", reactionAnnotations);
+
+    result.put("publications", publicationsRestImpl.getPublications(models).size());
+
+    return result;
+  }
+
+  public List<ProjectMetaData> getProjects(String token) throws SecurityException {
+    AuthenticationToken authenticationToken = getUserService().getToken(token);
+    List<Project> projects = getProjectService().getAllProjects(authenticationToken);
+    List<ProjectMetaData> result = new ArrayList<>();
+    for (Project project : projects) {
+      result.add(createData(project));
+    }
+    return result;
+  }
+
+  public ProjectMetaData updateProject(String token, String projectId, Map<String, Object> data)
+      throws SecurityException, QueryException {
+    AuthenticationToken authenticationToken = getUserService().getToken(token);
+    Project project = getProjectService().getProjectByProjectId(projectId, authenticationToken);
+    if (project == null) {
+      throw new ObjectNotFoundException("Project with given id doesn't exist");
+    }
+    boolean canModify = getUserService().userHasPrivilege(authenticationToken, PrivilegeType.ADD_MAP);
+    if (!canModify) {
+      throw new SecurityException("You cannot update projects");
+    }
+    Set<String> fields = data.keySet();
+    for (String fieldName : fields) {
+      Object value = data.get(fieldName);
+      String stringValue = null;
+      if (value instanceof String) {
+        stringValue = (String) value;
+      }
+      if (fieldName.equalsIgnoreCase("version")) {
+        project.setVersion((String) value);
+      } else if (fieldName.equalsIgnoreCase("id")) {
+        try {
+          int id = Integer.parseInt(stringValue);
+          if (id != project.getId()) {
+            throw new QueryException("Invalid id: " + stringValue);
+          }
+        } catch (NumberFormatException e) {
+          throw new QueryException("Invalid id: " + stringValue);
+        }
+      } else if (fieldName.equalsIgnoreCase("projectId")) {
+        if (!project.getProjectId().equalsIgnoreCase(stringValue)) {
+          throw new QueryException("You cannot modify projectId");
+        }
+      } else if (fieldName.equalsIgnoreCase("name")) {
+        project.setName((String) value);
+      } else if (fieldName.equalsIgnoreCase("notifyEmail")) {
+        project.setNotifyEmail(stringValue);
+      } else if (fieldName.equalsIgnoreCase("organism")) {
+        MiriamData organism = updateMiriamData(project.getOrganism(), value);
+        project.setOrganism(organism);
+      } else if (fieldName.equalsIgnoreCase("disease")) {
+        MiriamData disease = updateMiriamData(project.getDisease(), value);
+        project.setDisease(disease);
+      } else {
+        throw new QueryException("Unknown field: " + fieldName);
+      }
+    }
+    getProjectService().updateProject(project);
+    return getProject(projectId, token);
+  }
+
+  private MiriamData updateMiriamData(MiriamData organism, Object res) {
+    if (res == null) {
+      return null;
+    }
+    if (organism == null) {
+      organism = new MiriamData();
+    }
+
+    if (res instanceof Map) {
+      @SuppressWarnings("unchecked")
+      Map<String, Object> map = (Map<String, Object>) res;
+      organism.setDataType(MiriamType.valueOf((String) map.get("type")));
+      organism.setResource((String) map.get("resource"));
+      return organism;
+    } else {
+      throw new InvalidArgumentException("invalid miriamdData: " + res);
+    }
+  }
+
+  public ProjectMetaData addProject(String token, String projectId, MultiValueMap<String, String> data, String path)
+      throws SecurityException, QueryException, IOException {
+    AuthenticationToken authenticationToken = getUserService().getToken(token);
+    User user = getUserService().getUserByToken(authenticationToken);
+    Project project = getProjectService().getProjectByProjectId(projectId, authenticationToken);
+    if (project != null) {
+      throw new ObjectExistsException("Project with given id already exists");
+    }
+    CreateProjectParams params = new CreateProjectParams();
+    String directory = path + "/../map_images/" + md5(projectId) + "/";
+    String fileContent = getFirstValue(data.get("file-content"));
+    if (fileContent == null) {
+      throw new QueryException("file-content is obligatory");
+    }
+    String parserClass = getFirstValue(data.get("parser"));
+    if (parserClass == null) {
+      throw new QueryException("parser is obligatory");
+    }
+    IConverter parser = getModelParser(parserClass);
+
+    params.addUser(user.getLogin(), null);
+    params.async(true);
+    params.parser(parser);
+    params.authenticationToken(authenticationToken);
+    params.autoResize(getFirstValue(data.get("auto-resize")));
+    params.cacheModel(getFirstValue(data.get("cache")));
+    params.description(getFirstValue(data.get("description")));
+    params.images(true);
+    params.notifyEmail(getFirstValue(data.get("notify-email")));
+    params.projectDir(directory);
+    params.projectDisease(getFirstValue(data.get("disease")));
+    params.projectFile(new ByteArrayInputStream(fileContent.getBytes(StandardCharsets.UTF_8)));
+    params.projectId(projectId);
+    params.projectName(getFirstValue(data.get("name")));
+    params.projectOrganism(getFirstValue(data.get("organism")));
+    params.sbgnFormat(getFirstValue(data.get("sbgn")));
+    params.semanticZoom(getFirstValue(data.get("semantic-zoom")));
+    params.version(getFirstValue(data.get("version")));
+    params.annotations(getFirstValue(data.get("annotate")));
+    if (params.isUpdateAnnotations()) {
+      params.annotatorsMap(projectService.createClassAnnotatorTree(user));
+    }
+    params.analyzeAnnotations(getFirstValue(data.get("verify-annotations")));
+    if (params.isAnalyzeAnnotations()) {
+      params.requiredAnnotations(projectService.createClassAnnotatorTree(user));
+      params.validAnnotations(projectService.createClassAnnotatorTree(user));
+    }
+
+    getProjectService().createProject(params);
+    return getProject(projectId, token);
+  }
+
+  private String getFirstValue(List<String> list) {
+    if (list == null) {
+      return null;
+    }
+    if (list.size() > 0) {
+      return list.get(0);
+    }
+    return null;
+  }
+
+  /**
+   * Method that computes md5 hash for a given {@link String}.
+   * 
+   * @param data
+   *          input string
+   * @return md5 hash for input string
+   */
+  private String md5(String data) {
+    try {
+      MessageDigest md = MessageDigest.getInstance("MD5");
+      byte[] mdbytes = md.digest(data.getBytes());
+      StringBuffer sb = new StringBuffer();
+      for (int i = 0; i < mdbytes.length; i++) {
+        // CHECKSTYLE:OFF
+        // this magic formula transforms int into hex value
+        sb.append(Integer.toString((mdbytes[i] & 0xff) + 0x100, 16).substring(1));
+        // CHECKSTYLE:ON
+      }
+      return sb.toString();
+    } catch (NoSuchAlgorithmException e) {
+      logger.fatal("Problem with instance of MD5 encoder", e);
+    }
+
+    return null;
+  }
+
+  public ProjectMetaData removeProject(String token, String projectId, String path)
+      throws ObjectNotFoundException, SecurityException {
+    AuthenticationToken authenticationToken = getUserService().getToken(token);
+    Project project = getProjectService().getProjectByProjectId(projectId, authenticationToken);
+    getProjectService().removeProject(project, path, true, authenticationToken);
+    return getProject(projectId, token);
+  }
 
 }
diff --git a/service/src/main/java/lcsb/mapviewer/services/utils/CreateProjectParams.java b/service/src/main/java/lcsb/mapviewer/services/utils/CreateProjectParams.java
index 69b792a9bb8d1ed9d4a8e1641c76927df4afb7a6..a1f3ab33bcb611c39b4a409d0dbcec2429ec1a0e 100644
--- a/service/src/main/java/lcsb/mapviewer/services/utils/CreateProjectParams.java
+++ b/service/src/main/java/lcsb/mapviewer/services/utils/CreateProjectParams.java
@@ -31,737 +31,740 @@ import lcsb.mapviewer.services.view.AuthenticationToken;
  */
 public class CreateProjectParams {
 
-	/**
-	 * User defined project identifier.
-	 */
-	private String																					 projectId;
-
-	/**
-	 * Name of the project.
-	 */
-	private String																					 projectName;
-
-	/**
-	 * Disease associated to the project.
-	 */
-	private String																					 disease;
-
-	/**
-	 * Organism associated to the project.
-	 */
-	private String																					 organism;
-
-	/**
-	 * Path to a file used as a model.
-	 */
-	private String																					 projectFile;
-
-	private IConverter																			 parser;
-
-	/**
-	 * Is the project a complex multi-file project.
-	 */
-	private boolean																					 complex;
-	private boolean																					 semanticZoom;
-
-	/**
-	 * List of zip entries in the complex model definition.
-	 */
-	private List<ZipEntryFile>															 zipEntries							= new ArrayList<ZipEntryFile>();
-
-	/**
-	 * Should the elements be annotated by the external resources.
-	 */
-	private boolean																					 updateAnnotations			= false;
-
-	/**
-	 * Do we want to generate images for all available layers.
-	 */
-	private boolean																					 images									= false;
-
-	/**
-	 * Should the map be autoresized after processing (to trim unnecessary
-	 * margins).
-	 */
-	private boolean																					 autoResize							= true;
-
-	/**
-	 * Should the data from external resources but linked to model be cached.
-	 */
-	private boolean																					 cacheModel							= true;
-
-	/**
-	 * Should the process of creation of the project be asynchronous (in separate
-	 * thread).
-	 */
-	private boolean																					 async									= false;
-
-	/**
-	 * Should the map be displayed in SBGN format.
-	 */
-	private boolean																					 sbgnFormat							= false;
-
-	/**
-	 * Is the {@link lcsb.mapviewer.services.utils.data.BuildInLayout#NORMAL}
-	 * default {@link lcsb.mapviewer.model.map.layout.Layout Layout} when
-	 * generating new project.
-	 */
-	private boolean																					 networkLayoutAsDefault	= false;
-
-	/**
-	 * Do we want to analyze annotations after processing of the map. If yes then
-	 * in the email with summary of the generation process information about
-	 * improper annotations will be sent.
-	 */
-	private boolean																					 analyzeAnnotations			= false;
-
-	/**
-	 * Email address that should be notified after everything is done.
-	 */
-	private String																					 notifyEmail						= null;
-
-	/**
-	 * Description of the project.
-	 */
-	private String																					 description						= "";
-
-	/**
-	 * Version of the map.
-	 */
-	private String																					 version								= "0";
-
-	/**
-	 * Users that should have access to the map.
-	 */
-	private List<String[]>																	 users									= new ArrayList<String[]>();
-
-	/**
-	 * Directory with the static images that will be stored on server. This
-	 * directory is relative and it's a simple uniqe name within folder with
-	 * images.
-	 */
-	private String																					 projectDir;
-
-	private AuthenticationToken															 authenticationToken;
-
-	/**
-	 * Map that contains informnation what kind of annotators should be used for
-	 * specific class.
-	 */
-	private Map<Class<?>, List<String>>											 annotatorsMap					= null;
-
-	/**
-	 * Map that contains information which {@link MiriamType miriam types} are
-	 * valid for which class.
-	 */
-	private Map<Class<? extends BioEntity>, Set<MiriamType>> validAnnotations				= null;
-
-	/**
-	 * Map that contains information which {@link MiriamType miriam types} are
-	 * obigatory for which class.
-	 */
-	private Map<Class<? extends BioEntity>, Set<MiriamType>> requiredAnnotations		= null;
-
-	/**
-	 * @param projectId
-	 *          the projectId to set
-	 * @return object with all parameters
-	 * @see #projectId
-	 */
-	public CreateProjectParams projectId(String projectId) {
-		this.projectId = projectId;
-		return this;
-	}
-	
-	public CreateProjectParams parser(IConverter parser) {
-		this.parser = parser;
-		return this;
-	}
-	
-	
-	
-
-	/**
-	 * @param notifyEmail
-	 *          the notifyEmail to set
-	 * @return object with all parameters
-	 * @see #notifyEmail
-	 */
-	public CreateProjectParams notifyEmail(String notifyEmail) {
-		this.notifyEmail = notifyEmail;
-		return this;
-	}
-
-	/**
-	 * @param projectFile
-	 *          the projectFile to set
-	 * @return object with all parameters
-	 * @see #projectFile
-	 */
-	public CreateProjectParams projectFile(String projectFile) {
-		this.projectFile = projectFile;
-		return this;
-	}
-
-	/**
-	 * @param autoResize
-	 *          the autoResize to set
-	 * @return object with all parameters
-	 * @see #autoResize
-	 */
-	public CreateProjectParams autoResize(boolean autoResize) {
-		this.autoResize = autoResize;
-		return this;
-	}
-
-	public CreateProjectParams autoResize(String value) {
-		return this.autoResize("true".equalsIgnoreCase(value));
-	}
-
-	/**
-	 * Sets input stream from which projects should be generated.
-	 * 
-	 * @param is
-	 *          inputstream with the data of the project to be generated
-	 * @return object with all parameters
-	 * @throws IOException
-	 *           thrown if there are some problem with the stream
-	 */
-	public CreateProjectParams projectFile(InputStream is) throws IOException {
-		File temp = File.createTempFile("model", ".xml");
-		IOUtils.copy(is, new FileOutputStream(temp));
-		this.projectFile = temp.getAbsolutePath();
-		return this;
-	}
-
-	/**
-	 * Sets file from which projects should be generated.
-	 * 
-	 * @param file
-	 *          file with the data of the project to be generated
-	 * @return object with all parameters
-	 */
-	public CreateProjectParams projectFile(File file) {
-		this.projectFile = file.getAbsolutePath();
-		return this;
-	}
-
-	/**
-	 * @param async
-	 *          the async to set
-	 * @return object with all parameters
-	 * @see #async
-	 */
-	public CreateProjectParams async(boolean async) {
-		this.async = async;
-		return this;
-	}
-
-	/**
-	 * @param analyzeAnnotations
-	 *          the analyzeAnnotations to set
-	 * @return object with all parameters
-	 * @see #analyzeAnnotations
-	 */
-	public CreateProjectParams analyzeAnnotations(boolean analyzeAnnotations) {
-		this.analyzeAnnotations = analyzeAnnotations;
-		return this;
-	}
-
-	/**
-	 * @param updateAnnotations
-	 *          the updateAnnotations to set
-	 * @return object with all parameters
-	 * @see #updateAnnotations
-	 */
-	public CreateProjectParams annotations(boolean updateAnnotations) {
-		this.updateAnnotations = updateAnnotations;
-		return this;
-	}
-
-	/**
-	 * @param images
-	 *          the images to set
-	 * @return object with all parameters
-	 * @see #images
-	 */
-	public CreateProjectParams images(boolean images) {
-		this.images = images;
-		return this;
-	}
-
-	/**
-	 * @param description
-	 *          the description to set
-	 * @return object with all parameters
-	 * @see #description
-	 */
-	public CreateProjectParams description(String description) {
-		this.description = description;
-		return this;
-	}
-
-	/**
-	 * @param version
-	 *          the version to set
-	 * @return object with all parameters
-	 * @see #version
-	 */
-	public CreateProjectParams version(String version) {
-		this.version = version;
-		return this;
-	}
-
-	/**
-	 * Adds a user to the list of users that should have access to the project
-	 * from the beginning.
-	 * 
-	 * @param login
-	 *          login of the user
-	 * @param password
-	 *          password (in case user doesn't exist yet)
-	 * @return object with all parameters
-	 * @return
-	 */
-	public CreateProjectParams addUser(String login, String password) {
-		this.users.add(new String[] { login, password });
-		return this;
-	}
-
-	/**
-	 * @return the users
-	 * @see #users
-	 */
-	public List<String[]> getUsers() {
-		return users;
-	}
-
-	/**
-	 * @return the version
-	 * @see #version
-	 */
-	public String getVersion() {
-		return version;
-	}
-
-	/**
-	 * @return the description
-	 * @see #description
-	 */
-	public String getDescription() {
-		return description;
-	}
-
-	/**
-	 * @return the notifyEmail
-	 * @see #notifyEmail
-	 */
-	public String getNotifyEmail() {
-		return notifyEmail;
-	}
-
-	/**
-	 * @return the analyzeAnnotations
-	 * @see #analyzeAnnotations
-	 */
-	public boolean isAnalyzeAnnotations() {
-		return analyzeAnnotations;
-	}
-
-	/**
-	 * @return the async
-	 * @see #async
-	 */
-	public boolean isAsync() {
-		return async;
-	}
-
-	/**
-	 * @return the autoResize
-	 * @see #autoResize
-	 */
-	public boolean isAutoResize() {
-		return autoResize;
-	}
-
-	/**
-	 * @return the images
-	 * @see #images
-	 */
-	public boolean isImages() {
-		return images;
-	}
-
-	/**
-	 * @return the updateAnnotations
-	 * @see #updateAnnotations
-	 */
-	public boolean isUpdateAnnotations() {
-		return updateAnnotations;
-	}
-
-	/**
-	 * @return the projectFile
-	 * @see #projectFile
-	 */
-	public String getProjectFile() {
-		return projectFile;
-	}
-
-	/**
-	 * @return the projectId
-	 * @see #projectId
-	 */
-	public String getProjectId() {
-		return projectId;
-	}
-
-	/**
-	 * @return the cacheModel
-	 * @see #cacheModel
-	 */
-	public boolean isCacheModel() {
-		return cacheModel;
-	}
-
-	/**
-	 * @param cacheModel
-	 *          the cacheModel to set
-	 * @see #cacheModel
-	 * @return object with all parameters
-	 */
-	public CreateProjectParams cacheModel(boolean cacheModel) {
-		this.cacheModel = cacheModel;
-		return this;
-	}
-
-	public CreateProjectParams cacheModel(String value) {
-		return this.cacheModel("true".equalsIgnoreCase(value));
-	}
-
-	/**
-	 * @return the submodels
-	 * @see #zipEntries
-	 */
-	public List<ZipEntryFile> getZipEntries() {
-		return zipEntries;
-	}
-
-	/**
-	 * @param entry
-	 *          the submodel to add
-	 * @see #zipEntries
-	 * @return object with all parameters
-	 */
-	public CreateProjectParams addZipEntry(ZipEntryFile entry) {
-		if (entry != null) {
-			this.zipEntries.add(entry);
-		}
-		return this;
-	}
-
-	/**
-	 * @return the complex
-	 * @see #complex
-	 */
-	public boolean isComplex() {
-		return complex;
-	}
-
-	/**
-	 * @return the sbgnFormat
-	 * @see #sbgnFormat
-	 */
-	public boolean isSbgnFormat() {
-		return sbgnFormat;
-	}
-
-	/**
-	 * @param sbgnFormat
-	 *          the sbgnFormat to set
-	 * @see #sbgnFormat
-	 */
-	public CreateProjectParams sbgnFormat(boolean sbgnFormat) {
-		this.sbgnFormat = sbgnFormat;
-		return this;
-	}
-
-	public CreateProjectParams sbgnFormat(String value) {
-		return this.sbgnFormat("true".equalsIgnoreCase(value));
-	}
-
-	/**
-	 * @param complex
-	 *          the complex to set
-	 * @see #complex
-	 * @return object with all parameters
-	 */
-	public CreateProjectParams complex(boolean complex) {
-		this.complex = complex;
-		return this;
-	}
-
-	/**
-	 * Creates {@link #annotatorsMap}.
-	 * 
-	 * @param annotatorsTree
-	 *          tree containing information about annotators for given classes
-	 */
-	public void annotatorsMap(TreeNode annotatorsTree) {
-		Map<Class<?>, List<String>> map = new HashMap<Class<?>, List<String>>();
-		Queue<TreeNode> queue = new LinkedList<TreeNode>();
-		queue.add(annotatorsTree);
-		while (!queue.isEmpty()) {
-			TreeNode node = queue.poll();
-
-			Set<String> set = new HashSet<String>();
-
-			TreeNode parent = node;
-			while (parent != null) {
-				set.addAll(((AnnotatedObjectTreeRow) parent.getData()).getUsedAnnotators());
-				parent = parent.getParent();
-			}
-			List<String> list = new ArrayList<String>();
-			list.addAll(set);
-			map.put(((AnnotatedObjectTreeRow) node.getData()).getClazz(), list);
-
-			for (TreeNode node2 : node.getChildren()) {
-				queue.add(node2);
-			}
-		}
-		annotatorsMap = map;
-	}
-
-	/**
-	 * @return the annotatorsMap
-	 * @see #annotatorsMap
-	 */
-	public Map<Class<?>, List<String>> getAnnotatorsMap() {
-		return annotatorsMap;
-	}
-
-	/**
-	 * @param annotatorsMap
-	 *          the annotatorsMap to set
-	 * @see #annotatorsMap
-	 */
-	public void setAnnotatorsMap(Map<Class<?>, List<String>> annotatorsMap) {
-		this.annotatorsMap = annotatorsMap;
-	}
-
-	/**
-	 * Creates {@link #validAnnotations}.
-	 * 
-	 * @param annotatorsTree
-	 *          tree containing information about valid {@link MiriamType miriam
-	 *          types}
-	 */
-	@SuppressWarnings("unchecked")
-	public void validAnnotations(TreeNode annotatorsTree) {
-		Map<Class<? extends BioEntity>, Set<MiriamType>> map = new HashMap<Class<? extends BioEntity>, Set<MiriamType>>();
-		Queue<TreeNode> queue = new LinkedList<TreeNode>();
-		queue.add(annotatorsTree);
-		while (!queue.isEmpty()) {
-			TreeNode node = queue.poll();
-			Set<MiriamType> set = new HashSet<MiriamType>();
-
-			TreeNode parent = node;
-			while (parent != null) {
-				set.addAll(((AnnotatedObjectTreeRow) parent.getData()).getValidAnnotations());
-				parent = parent.getParent();
-			}
-			map.put((Class<? extends BioEntity>) ((AnnotatedObjectTreeRow) node.getData()).getClazz(), set);
-
-			for (TreeNode node2 : node.getChildren()) {
-				queue.add(node2);
-			}
-		}
-		validAnnotations = map;
-	}
-
-	/**
-	 * Creates {@link #requiredAnnotations}.
-	 * 
-	 * @param annotatorsTree
-	 *          tree containing information about required {@link MiriamType
-	 *          miriam types}
-	 */
-	@SuppressWarnings("unchecked")
-	public void requiredAnnotations(TreeNode annotatorsTree) {
-		Map<Class<? extends BioEntity>, Set<MiriamType>> map = new HashMap<Class<? extends BioEntity>, Set<MiriamType>>();
-		Queue<TreeNode> queue = new LinkedList<TreeNode>();
-		queue.add(annotatorsTree);
-		while (!queue.isEmpty()) {
-			TreeNode node = queue.poll();
-			boolean valid = ((AnnotatedObjectTreeRow) node.getData()).getRequire();
-			Set<MiriamType> set = new HashSet<MiriamType>();
-
-			TreeNode parent = node;
-			while (parent != null) {
-				set.addAll(((AnnotatedObjectTreeRow) parent.getData()).getRequiredAnnotations());
-				if (((AnnotatedObjectTreeRow) parent.getData()).getRequire()) {
-					valid = true;
-				}
-				parent = parent.getParent();
-			}
-			if (!valid) {
-				set = null;
-			}
-			map.put((Class<? extends BioEntity>) ((AnnotatedObjectTreeRow) node.getData()).getClazz(), set);
-
-			for (TreeNode node2 : node.getChildren()) {
-				queue.add(node2);
-			}
-		}
-		requiredAnnotations = map;
-	}
-
-	/**
-	 * Returns {@link #validAnnotations}.
-	 * 
-	 * @return {@link #validAnnotations}.
-	 */
-	public Map<Class<? extends BioEntity>, Set<MiriamType>> getValidAnnotations() {
-		return validAnnotations;
-	}
-
-	/**
-	 * Returns {@link #requiredAnnotations}.
-	 * 
-	 * @return {@link #requiredAnnotations}.
-	 */
-	public Map<Class<? extends BioEntity>, Set<MiriamType>> getRequiredAnnotations() {
-		return requiredAnnotations;
-	}
-
-	/**
-	 * Sets {@link #projectDir}.
-	 * 
-	 * @param directory
-	 *          new {@link #projectDir} value
-	 * @return instance of this class with new value set
-	 */
-	public CreateProjectParams projectDir(String directory) {
-		this.projectDir = directory;
-		return this;
-	}
-
-	/**
-	 * @return the projectDir
-	 * @see #projectDir
-	 */
-	public String getProjectDir() {
-		return projectDir;
-	}
-
-	/**
-	 * 
-	 * @param projectName
-	 *          new {@link #projectName}
-	 * @return instance of this class with new value set
-	 */
-	public CreateProjectParams projectName(String projectName) {
-		this.projectName = projectName;
-		return this;
-	}
-
-	/**
-	 * @return the projectName
-	 * @see #projectName
-	 */
-	public String getProjectName() {
-		return projectName;
-	}
-
-	/**
-	 * @param value
-	 *          the networkLayoutAsDefault to set
-	 * @see #networkLayoutAsDefault
-	 * @return instance of this class with new value set
-	 */
-	public CreateProjectParams networkLayoutAsDefault(boolean value) {
-		this.networkLayoutAsDefault = value;
-		return this;
-
-	}
-
-	/**
-	 * @return the networkLayoutAsDefault
-	 * @see #networkLayoutAsDefault
-	 */
-	public boolean isNetworkLayoutAsDefault() {
-		return networkLayoutAsDefault;
-	}
-
-	/**
-	 * @return disease MESH code.
-	 */
-	public String getDisease() {
-		return disease;
-	}
-
-	/**
-	 * @param disease
-	 *          the code of the disease.
-	 * @return updated params object.
-	 */
-	public CreateProjectParams projectDisease(String disease) {
-		this.disease = disease;
-		return this;
-	}
-
-	/**
-	 * @return the organism
-	 * @see #organism
-	 */
-	public String getOrganism() {
-		return organism;
-	}
-
-	/**
-	 * @param organism
-	 *          the organism to set
-	 * @return updated params object.
-	 */
-	public CreateProjectParams projectOrganism(String organism) {
-		this.organism = organism;
-		return this;
-	}
-
-	/**
-	 * @return the authenticationToken
-	 * @see #authenticationToken
-	 */
-	public AuthenticationToken getAuthenticationToken() {
-		return authenticationToken;
-	}
-
-	/**
-	 * @param authenticationToken
-	 *          the authenticationToken to set
-	 * @see #authenticationToken
-	 */
-	public CreateProjectParams authenticationToken(AuthenticationToken authenticationToken) {
-		this.authenticationToken = authenticationToken;
-
-		return this;
-	}
-
-	public CreateProjectParams semanticZoom(boolean semanticZoom) {
-		this.semanticZoom = semanticZoom;
-		return this;
-	}
-
-	public CreateProjectParams semanticZoom(String value) {
-		return this.semanticZoom("true".equals(value));
-	}
-
-	public boolean isSemanticZoom() {
-		return this.semanticZoom;
-	}
-
-	public IConverter getParser() {
-		return this.parser ;
-	}
+  /**
+   * User defined project identifier.
+   */
+  private String projectId;
+
+  /**
+   * Name of the project.
+   */
+  private String projectName;
+
+  /**
+   * Disease associated to the project.
+   */
+  private String disease;
+
+  /**
+   * Organism associated to the project.
+   */
+  private String organism;
+
+  /**
+   * Path to a file used as a model.
+   */
+  private String projectFile;
+
+  private IConverter parser;
+
+  /**
+   * Is the project a complex multi-file project.
+   */
+  private boolean complex;
+  private boolean semanticZoom;
+
+  /**
+   * List of zip entries in the complex model definition.
+   */
+  private List<ZipEntryFile> zipEntries = new ArrayList<ZipEntryFile>();
+
+  /**
+   * Should the elements be annotated by the external resources.
+   */
+  private boolean updateAnnotations = false;
+
+  /**
+   * Do we want to generate images for all available layers.
+   */
+  private boolean images = false;
+
+  /**
+   * Should the map be autoresized after processing (to trim unnecessary margins).
+   */
+  private boolean autoResize = true;
+
+  /**
+   * Should the data from external resources but linked to model be cached.
+   */
+  private boolean cacheModel = true;
+
+  /**
+   * Should the process of creation of the project be asynchronous (in separate
+   * thread).
+   */
+  private boolean async = false;
+
+  /**
+   * Should the map be displayed in SBGN format.
+   */
+  private boolean sbgnFormat = false;
+
+  /**
+   * Is the {@link lcsb.mapviewer.services.utils.data.BuildInLayout#NORMAL}
+   * default {@link lcsb.mapviewer.model.map.layout.Layout Layout} when generating
+   * new project.
+   */
+  private boolean networkLayoutAsDefault = false;
+
+  /**
+   * Do we want to analyze annotations after processing of the map. If yes then in
+   * the email with summary of the generation process information about improper
+   * annotations will be sent.
+   */
+  private boolean analyzeAnnotations = false;
+
+  /**
+   * Email address that should be notified after everything is done.
+   */
+  private String notifyEmail = null;
+
+  /**
+   * Description of the project.
+   */
+  private String description = "";
+
+  /**
+   * Version of the map.
+   */
+  private String version = "0";
+
+  /**
+   * Users that should have access to the map.
+   */
+  private List<String[]> users = new ArrayList<String[]>();
+
+  /**
+   * Directory with the static images that will be stored on server. This
+   * directory is relative and it's a simple uniqe name within folder with images.
+   */
+  private String projectDir;
+
+  private AuthenticationToken authenticationToken;
+
+  /**
+   * Map that contains informnation what kind of annotators should be used for
+   * specific class.
+   */
+  private Map<Class<?>, List<String>> annotatorsMap = null;
+
+  /**
+   * Map that contains information which {@link MiriamType miriam types} are valid
+   * for which class.
+   */
+  private Map<Class<? extends BioEntity>, Set<MiriamType>> validAnnotations = null;
+
+  /**
+   * Map that contains information which {@link MiriamType miriam types} are
+   * obigatory for which class.
+   */
+  private Map<Class<? extends BioEntity>, Set<MiriamType>> requiredAnnotations = null;
+
+  /**
+   * @param projectId
+   *          the projectId to set
+   * @return object with all parameters
+   * @see #projectId
+   */
+  public CreateProjectParams projectId(String projectId) {
+    this.projectId = projectId;
+    return this;
+  }
+
+  public CreateProjectParams parser(IConverter parser) {
+    this.parser = parser;
+    return this;
+  }
+
+  /**
+   * @param notifyEmail
+   *          the notifyEmail to set
+   * @return object with all parameters
+   * @see #notifyEmail
+   */
+  public CreateProjectParams notifyEmail(String notifyEmail) {
+    this.notifyEmail = notifyEmail;
+    return this;
+  }
+
+  /**
+   * @param projectFile
+   *          the projectFile to set
+   * @return object with all parameters
+   * @see #projectFile
+   */
+  public CreateProjectParams projectFile(String projectFile) {
+    this.projectFile = projectFile;
+    return this;
+  }
+
+  /**
+   * @param autoResize
+   *          the autoResize to set
+   * @return object with all parameters
+   * @see #autoResize
+   */
+  public CreateProjectParams autoResize(boolean autoResize) {
+    this.autoResize = autoResize;
+    return this;
+  }
+
+  public CreateProjectParams autoResize(String value) {
+    return this.autoResize("true".equalsIgnoreCase(value));
+  }
+
+  /**
+   * Sets input stream from which projects should be generated.
+   * 
+   * @param is
+   *          inputstream with the data of the project to be generated
+   * @return object with all parameters
+   * @throws IOException
+   *           thrown if there are some problem with the stream
+   */
+  public CreateProjectParams projectFile(InputStream is) throws IOException {
+    File temp = File.createTempFile("model", ".xml");
+    IOUtils.copy(is, new FileOutputStream(temp));
+    this.projectFile = temp.getAbsolutePath();
+    return this;
+  }
+
+  /**
+   * Sets file from which projects should be generated.
+   * 
+   * @param file
+   *          file with the data of the project to be generated
+   * @return object with all parameters
+   */
+  public CreateProjectParams projectFile(File file) {
+    this.projectFile = file.getAbsolutePath();
+    return this;
+  }
+
+  /**
+   * @param async
+   *          the async to set
+   * @return object with all parameters
+   * @see #async
+   */
+  public CreateProjectParams async(boolean async) {
+    this.async = async;
+    return this;
+  }
+
+  /**
+   * @param analyzeAnnotations
+   *          the analyzeAnnotations to set
+   * @return object with all parameters
+   * @see #analyzeAnnotations
+   */
+  public CreateProjectParams analyzeAnnotations(boolean analyzeAnnotations) {
+    this.analyzeAnnotations = analyzeAnnotations;
+    return this;
+  }
+
+  /**
+   * @param updateAnnotations
+   *          the updateAnnotations to set
+   * @return object with all parameters
+   * @see #updateAnnotations
+   */
+  public CreateProjectParams annotations(boolean updateAnnotations) {
+    this.updateAnnotations = updateAnnotations;
+    return this;
+  }
+
+  /**
+   * @param images
+   *          the images to set
+   * @return object with all parameters
+   * @see #images
+   */
+  public CreateProjectParams images(boolean images) {
+    this.images = images;
+    return this;
+  }
+
+  /**
+   * @param description
+   *          the description to set
+   * @return object with all parameters
+   * @see #description
+   */
+  public CreateProjectParams description(String description) {
+    this.description = description;
+    return this;
+  }
+
+  /**
+   * @param version
+   *          the version to set
+   * @return object with all parameters
+   * @see #version
+   */
+  public CreateProjectParams version(String version) {
+    this.version = version;
+    return this;
+  }
+
+  /**
+   * Adds a user to the list of users that should have access to the project from
+   * the beginning.
+   * 
+   * @param login
+   *          login of the user
+   * @param password
+   *          password (in case user doesn't exist yet)
+   * @return object with all parameters
+   * @return
+   */
+  public CreateProjectParams addUser(String login, String password) {
+    this.users.add(new String[] { login, password });
+    return this;
+  }
+
+  /**
+   * @return the users
+   * @see #users
+   */
+  public List<String[]> getUsers() {
+    return users;
+  }
+
+  /**
+   * @return the version
+   * @see #version
+   */
+  public String getVersion() {
+    return version;
+  }
+
+  /**
+   * @return the description
+   * @see #description
+   */
+  public String getDescription() {
+    return description;
+  }
+
+  /**
+   * @return the notifyEmail
+   * @see #notifyEmail
+   */
+  public String getNotifyEmail() {
+    return notifyEmail;
+  }
+
+  /**
+   * @return the analyzeAnnotations
+   * @see #analyzeAnnotations
+   */
+  public boolean isAnalyzeAnnotations() {
+    return analyzeAnnotations;
+  }
+
+  /**
+   * @return the async
+   * @see #async
+   */
+  public boolean isAsync() {
+    return async;
+  }
+
+  /**
+   * @return the autoResize
+   * @see #autoResize
+   */
+  public boolean isAutoResize() {
+    return autoResize;
+  }
+
+  /**
+   * @return the images
+   * @see #images
+   */
+  public boolean isImages() {
+    return images;
+  }
+
+  /**
+   * @return the updateAnnotations
+   * @see #updateAnnotations
+   */
+  public boolean isUpdateAnnotations() {
+    return updateAnnotations;
+  }
+
+  /**
+   * @return the projectFile
+   * @see #projectFile
+   */
+  public String getProjectFile() {
+    return projectFile;
+  }
+
+  /**
+   * @return the projectId
+   * @see #projectId
+   */
+  public String getProjectId() {
+    return projectId;
+  }
+
+  /**
+   * @return the cacheModel
+   * @see #cacheModel
+   */
+  public boolean isCacheModel() {
+    return cacheModel;
+  }
+
+  /**
+   * @param cacheModel
+   *          the cacheModel to set
+   * @see #cacheModel
+   * @return object with all parameters
+   */
+  public CreateProjectParams cacheModel(boolean cacheModel) {
+    this.cacheModel = cacheModel;
+    return this;
+  }
+
+  public CreateProjectParams cacheModel(String value) {
+    return this.cacheModel("true".equalsIgnoreCase(value));
+  }
+
+  /**
+   * @return the submodels
+   * @see #zipEntries
+   */
+  public List<ZipEntryFile> getZipEntries() {
+    return zipEntries;
+  }
+
+  /**
+   * @param entry
+   *          the submodel to add
+   * @see #zipEntries
+   * @return object with all parameters
+   */
+  public CreateProjectParams addZipEntry(ZipEntryFile entry) {
+    if (entry != null) {
+      this.zipEntries.add(entry);
+    }
+    return this;
+  }
+
+  /**
+   * @return the complex
+   * @see #complex
+   */
+  public boolean isComplex() {
+    return complex;
+  }
+
+  /**
+   * @return the sbgnFormat
+   * @see #sbgnFormat
+   */
+  public boolean isSbgnFormat() {
+    return sbgnFormat;
+  }
+
+  /**
+   * @param sbgnFormat
+   *          the sbgnFormat to set
+   * @see #sbgnFormat
+   */
+  public CreateProjectParams sbgnFormat(boolean sbgnFormat) {
+    this.sbgnFormat = sbgnFormat;
+    return this;
+  }
+
+  public CreateProjectParams sbgnFormat(String value) {
+    return this.sbgnFormat("true".equalsIgnoreCase(value));
+  }
+
+  /**
+   * @param complex
+   *          the complex to set
+   * @see #complex
+   * @return object with all parameters
+   */
+  public CreateProjectParams complex(boolean complex) {
+    this.complex = complex;
+    return this;
+  }
+
+  /**
+   * Creates {@link #annotatorsMap}.
+   * 
+   * @param annotatorsTree
+   *          tree containing information about annotators for given classes
+   */
+  public void annotatorsMap(TreeNode annotatorsTree) {
+    Map<Class<?>, List<String>> map = new HashMap<Class<?>, List<String>>();
+    Queue<TreeNode> queue = new LinkedList<TreeNode>();
+    queue.add(annotatorsTree);
+    while (!queue.isEmpty()) {
+      TreeNode node = queue.poll();
+
+      Set<String> set = new HashSet<String>();
+
+      TreeNode parent = node;
+      while (parent != null) {
+        set.addAll(((AnnotatedObjectTreeRow) parent.getData()).getUsedAnnotators());
+        parent = parent.getParent();
+      }
+      List<String> list = new ArrayList<String>();
+      list.addAll(set);
+      map.put(((AnnotatedObjectTreeRow) node.getData()).getClazz(), list);
+
+      for (TreeNode node2 : node.getChildren()) {
+        queue.add(node2);
+      }
+    }
+    annotatorsMap = map;
+  }
+
+  /**
+   * @return the annotatorsMap
+   * @see #annotatorsMap
+   */
+  public Map<Class<?>, List<String>> getAnnotatorsMap() {
+    return annotatorsMap;
+  }
+
+  /**
+   * @param annotatorsMap
+   *          the annotatorsMap to set
+   * @see #annotatorsMap
+   */
+  public void setAnnotatorsMap(Map<Class<?>, List<String>> annotatorsMap) {
+    this.annotatorsMap = annotatorsMap;
+  }
+
+  /**
+   * Creates {@link #validAnnotations}.
+   * 
+   * @param annotatorsTree
+   *          tree containing information about valid {@link MiriamType miriam
+   *          types}
+   */
+  @SuppressWarnings("unchecked")
+  public void validAnnotations(TreeNode annotatorsTree) {
+    Map<Class<? extends BioEntity>, Set<MiriamType>> map = new HashMap<Class<? extends BioEntity>, Set<MiriamType>>();
+    Queue<TreeNode> queue = new LinkedList<TreeNode>();
+    queue.add(annotatorsTree);
+    while (!queue.isEmpty()) {
+      TreeNode node = queue.poll();
+      Set<MiriamType> set = new HashSet<MiriamType>();
+
+      TreeNode parent = node;
+      while (parent != null) {
+        set.addAll(((AnnotatedObjectTreeRow) parent.getData()).getValidAnnotations());
+        parent = parent.getParent();
+      }
+      map.put((Class<? extends BioEntity>) ((AnnotatedObjectTreeRow) node.getData()).getClazz(), set);
+
+      for (TreeNode node2 : node.getChildren()) {
+        queue.add(node2);
+      }
+    }
+    validAnnotations = map;
+  }
+
+  /**
+   * Creates {@link #requiredAnnotations}.
+   * 
+   * @param annotatorsTree
+   *          tree containing information about required {@link MiriamType miriam
+   *          types}
+   */
+  @SuppressWarnings("unchecked")
+  public void requiredAnnotations(TreeNode annotatorsTree) {
+    Map<Class<? extends BioEntity>, Set<MiriamType>> map = new HashMap<Class<? extends BioEntity>, Set<MiriamType>>();
+    Queue<TreeNode> queue = new LinkedList<TreeNode>();
+    queue.add(annotatorsTree);
+    while (!queue.isEmpty()) {
+      TreeNode node = queue.poll();
+      boolean valid = ((AnnotatedObjectTreeRow) node.getData()).getRequire();
+      Set<MiriamType> set = new HashSet<MiriamType>();
+
+      TreeNode parent = node;
+      while (parent != null) {
+        set.addAll(((AnnotatedObjectTreeRow) parent.getData()).getRequiredAnnotations());
+        if (((AnnotatedObjectTreeRow) parent.getData()).getRequire()) {
+          valid = true;
+        }
+        parent = parent.getParent();
+      }
+      if (!valid) {
+        set = null;
+      }
+      map.put((Class<? extends BioEntity>) ((AnnotatedObjectTreeRow) node.getData()).getClazz(), set);
+
+      for (TreeNode node2 : node.getChildren()) {
+        queue.add(node2);
+      }
+    }
+    requiredAnnotations = map;
+  }
+
+  /**
+   * Returns {@link #validAnnotations}.
+   * 
+   * @return {@link #validAnnotations}.
+   */
+  public Map<Class<? extends BioEntity>, Set<MiriamType>> getValidAnnotations() {
+    return validAnnotations;
+  }
+
+  /**
+   * Returns {@link #requiredAnnotations}.
+   * 
+   * @return {@link #requiredAnnotations}.
+   */
+  public Map<Class<? extends BioEntity>, Set<MiriamType>> getRequiredAnnotations() {
+    return requiredAnnotations;
+  }
+
+  /**
+   * Sets {@link #projectDir}.
+   * 
+   * @param directory
+   *          new {@link #projectDir} value
+   * @return instance of this class with new value set
+   */
+  public CreateProjectParams projectDir(String directory) {
+    this.projectDir = directory;
+    return this;
+  }
+
+  /**
+   * @return the projectDir
+   * @see #projectDir
+   */
+  public String getProjectDir() {
+    return projectDir;
+  }
+
+  /**
+   * 
+   * @param projectName
+   *          new {@link #projectName}
+   * @return instance of this class with new value set
+   */
+  public CreateProjectParams projectName(String projectName) {
+    this.projectName = projectName;
+    return this;
+  }
+
+  /**
+   * @return the projectName
+   * @see #projectName
+   */
+  public String getProjectName() {
+    return projectName;
+  }
+
+  /**
+   * @param value
+   *          the networkLayoutAsDefault to set
+   * @see #networkLayoutAsDefault
+   * @return instance of this class with new value set
+   */
+  public CreateProjectParams networkLayoutAsDefault(boolean value) {
+    this.networkLayoutAsDefault = value;
+    return this;
+
+  }
+
+  /**
+   * @return the networkLayoutAsDefault
+   * @see #networkLayoutAsDefault
+   */
+  public boolean isNetworkLayoutAsDefault() {
+    return networkLayoutAsDefault;
+  }
+
+  /**
+   * @return disease MESH code.
+   */
+  public String getDisease() {
+    return disease;
+  }
+
+  /**
+   * @param disease
+   *          the code of the disease.
+   * @return updated params object.
+   */
+  public CreateProjectParams projectDisease(String disease) {
+    this.disease = disease;
+    return this;
+  }
+
+  /**
+   * @return the organism
+   * @see #organism
+   */
+  public String getOrganism() {
+    return organism;
+  }
+
+  /**
+   * @param organism
+   *          the organism to set
+   * @return updated params object.
+   */
+  public CreateProjectParams projectOrganism(String organism) {
+    this.organism = organism;
+    return this;
+  }
+
+  /**
+   * @return the authenticationToken
+   * @see #authenticationToken
+   */
+  public AuthenticationToken getAuthenticationToken() {
+    return authenticationToken;
+  }
+
+  /**
+   * @param authenticationToken
+   *          the authenticationToken to set
+   * @see #authenticationToken
+   */
+  public CreateProjectParams authenticationToken(AuthenticationToken authenticationToken) {
+    this.authenticationToken = authenticationToken;
+
+    return this;
+  }
+
+  public CreateProjectParams semanticZoom(boolean semanticZoom) {
+    this.semanticZoom = semanticZoom;
+    return this;
+  }
+
+  public CreateProjectParams semanticZoom(String value) {
+    return this.semanticZoom("true".equals(value));
+  }
+
+  public boolean isSemanticZoom() {
+    return this.semanticZoom;
+  }
+
+  public IConverter getParser() {
+    return this.parser;
+  }
+
+  public CreateProjectParams annotations(String value) {
+    return this.annotations("true".equalsIgnoreCase(value));
+  }
+
+  public CreateProjectParams analyzeAnnotations(String value) {
+    return this.analyzeAnnotations("true".equalsIgnoreCase(value));
+  }
 
 }