diff --git a/service/src/test/java/lcsb/mapviewer/services/impl/ProjectServiceTest.java b/service/src/test/java/lcsb/mapviewer/services/impl/ProjectServiceTest.java
index 173b6102c26150c9d7dab9af764d11a6b30d3afb..40d94a3fc6a3ef5a24ce2282fb0d9dd4020db7a2 100644
--- a/service/src/test/java/lcsb/mapviewer/services/impl/ProjectServiceTest.java
+++ b/service/src/test/java/lcsb/mapviewer/services/impl/ProjectServiceTest.java
@@ -1,890 +1,896 @@
-package lcsb.mapviewer.services.impl;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Queue;
-import java.util.Set;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-
-import org.apache.log4j.Logger;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.primefaces.model.TreeNode;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.test.annotation.Rollback;
-
-import lcsb.mapviewer.commands.CopyCommand;
-import lcsb.mapviewer.common.Configuration;
-import lcsb.mapviewer.converter.ComplexZipConverter;
-import lcsb.mapviewer.converter.ComplexZipConverterParams;
-import lcsb.mapviewer.converter.model.celldesigner.CellDesignerXmlParser;
-import lcsb.mapviewer.converter.zip.ModelZipEntryFile;
-import lcsb.mapviewer.converter.zip.ZipEntryFile;
-import lcsb.mapviewer.converter.zip.ZipEntryFileFactory;
-import lcsb.mapviewer.model.Project;
-import lcsb.mapviewer.model.ProjectStatus;
-import lcsb.mapviewer.model.map.BioEntity;
-import lcsb.mapviewer.model.map.MiriamType;
-import lcsb.mapviewer.model.map.layout.Layout;
-import lcsb.mapviewer.model.map.model.Model;
-import lcsb.mapviewer.model.map.model.ModelSubmodelConnection;
-import lcsb.mapviewer.model.map.model.SubmodelType;
-import lcsb.mapviewer.model.map.species.Element;
-import lcsb.mapviewer.model.map.species.Protein;
-import lcsb.mapviewer.model.user.ObjectPrivilege;
-import lcsb.mapviewer.model.user.PrivilegeType;
-import lcsb.mapviewer.model.user.User;
-import lcsb.mapviewer.model.user.UserAnnotationSchema;
-import lcsb.mapviewer.model.user.UserClassAnnotators;
-import lcsb.mapviewer.model.user.UserClassValidAnnotations;
-import lcsb.mapviewer.persist.dao.map.species.ElementDao;
-import lcsb.mapviewer.services.SecurityException;
-import lcsb.mapviewer.services.ServiceTestFunctions;
-import lcsb.mapviewer.services.UserAccessException;
-import lcsb.mapviewer.services.overlay.AnnotatedObjectTreeRow;
-import lcsb.mapviewer.services.utils.CreateProjectParams;
-import lcsb.mapviewer.services.utils.data.BuildInLayout;
-import lcsb.mapviewer.services.view.AuthenticationToken;
-import lcsb.mapviewer.services.view.ProjectView;
-
-@Rollback(true)
-public class ProjectServiceTest extends ServiceTestFunctions {
-	Logger							 logger				= Logger.getLogger(ProjectServiceTest.class);
-
-	ZipEntryFileFactory	 zefFactory		= new ZipEntryFileFactory();
-
-	private final String tmpResultDir	= "tmp/";
-	String							 projectId		= "Some_id";
-
-	@Autowired
-	ElementDao					 aliasDao;
-
-	// assume that we have admin account with all the privileges
-	AuthenticationToken	 adminToken;
-
-	@Before
-	public void setUp() throws Exception {
-		adminToken = userService.login("admin", "admin");
-	}
-
-	@After
-	public void tearDown() throws Exception {
-	}
-
-	@Test
-	public void testGetProjectWithoutAccessToEverything() {
-		try {
-			createUser();
-			AuthenticationToken token = userService.login(user.getLogin(), "passwd");
-			List<Project> projects = projectService.getAllProjects(token);
-			assertNotNull(projects);
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void test() {
-		try {
-			List<Project> projects = projectService.getAllProjects(adminToken);
-
-			Project project = new Project();
-			project.setProjectId(projectId);
-			projectDao.add(project);
-			projectDao.evict(project);
-
-			List<Project> projects2 = projectService.getAllProjects(adminToken);
-
-			assertEquals(projects.size() + 1, projects2.size());
-
-			for (Project tmpProject : projects2) {
-				if (!projects.contains(tmpProject)) {
-					assertEquals(projectId, tmpProject.getProjectId());
-				}
-			}
-
-			Project project2 = projectDao.getProjectByProjectId(projectId);
-			assertNotNull(project2);
-			assertFalse(project2.equals(project));
-			assertEquals(project.getId(), project2.getId());
-
-			projectDao.delete(project2);
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testRemove() throws Exception {
-
-		try {
-			String project_id = "Some_id";
-			Project project = new Project();
-			project.setProjectId(project_id);
-			projectDao.add(project);
-
-			List<ProjectView> projects2 = projectService.getAllProjectViews(adminToken);
-			ProjectView row = null;
-			for (ProjectView projectRow : projects2) {
-				if (projectRow.getIdObject() == project.getId()) {
-					row = projectRow;
-				}
-			}
-			assertNotNull(row);
-
-			User user = new User();
-			user.setLogin("x");
-			userDao.add(user);
-			userDao.evict(user);
-
-			int userId = user.getId();
-
-			user = userService.getUserById(userId);
-
-			userDao.evict(user);
-
-			userService.setUserPrivilege(user, new ObjectPrivilege(project, 1, PrivilegeType.VIEW_PROJECT, user));
-
-			user = userService.getUserById(userId);
-			int newAmount = user.getPrivileges().size();
-
-			userDao.evict(user);
-
-			projectService.removeProject(row, tmpResultDir, false, adminToken);
-
-			user = userService.getUserById(userId);
-
-			assertEquals("After removing project number of privileges didn't drop down", newAmount - 1, user.getPrivileges().size());
-
-			userDao.delete(user);
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testRemoveUserAfterRemoveProject() throws Exception {
-
-		try {
-			String projectId = "Some_id";
-			Project project = new Project();
-			project.setProjectId(projectId);
-			projectDao.add(project);
-
-			List<ProjectView> projects2 = projectService.getAllProjectViews(adminToken);
-			ProjectView row = null;
-			for (ProjectView projectRow : projects2) {
-				if (projectRow.getIdObject() == project.getId()) {
-					row = projectRow;
-				}
-			}
-			assertNotNull(row);
-
-			User user = new User();
-			user.setLogin("x");
-			userDao.add(user);
-			userDao.evict(user);
-
-			int userId = user.getId();
-
-			userService.setUserPrivilege(user, new ObjectPrivilege(project, 1, PrivilegeType.VIEW_PROJECT, user));
-
-			user = userService.getUserById(userId);
-
-			long counter = logDao.getCount();
-			projectService.removeProject(row, tmpResultDir, false, adminToken);
-			long counter2 = logDao.getCount();
-			assertTrue("Logs didn't appear after removing project", counter < counter2);
-
-			user = userService.getUserById(userId);
-			userDao.delete(user);
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testUpdater() throws Exception {
-		try {
-			String project_id = "test_id";
-			projectService.createProject(new CreateProjectParams().//
-					projectId(project_id).//
-					version("").//
-					projectFile("testFiles/centeredAnchorInModifier.xml").//
-					annotations(true).//
-					images(true).//
-					async(false).//
-					projectDir(tmpResultDir).//
-					addUser("gawi", "gawi").//
-					analyzeAnnotations(true));
-			AuthenticationToken token = userService.login("gawi", "gawi");
-			Project project = projectService.getProjectByProjectId(project_id, token);
-			assertEquals(ProjectStatus.DONE, project.getStatus());
-			projectService.removeProject(project, null, false, adminToken);
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testCreateComplex() throws Exception {
-		String projectId = "test_id";
-		try {
-			ZipEntryFile entry1 = new ModelZipEntryFile("main.xml", "main", true, false, SubmodelType.UNKNOWN);
-			ZipEntryFile entry2 = new ModelZipEntryFile("s1.xml", "s1", false, false, SubmodelType.UNKNOWN);
-			ZipEntryFile entry3 = new ModelZipEntryFile("s2.xml", "s2", false, false, SubmodelType.UNKNOWN);
-			ZipEntryFile entry4 = new ModelZipEntryFile("s3.xml", "s3", false, false, SubmodelType.UNKNOWN);
-			ZipEntryFile entry5 = new ModelZipEntryFile("mapping.xml", "mapping", false, true, SubmodelType.UNKNOWN);
-			projectService.createProject(new CreateProjectParams().//
-					projectId(projectId).//
-					version("").//
-					complex(true).//
-					projectFile("testFiles/complexModel/complex_model.zip").//
-					addZipEntry(entry1).//
-					addZipEntry(entry2).//
-					addZipEntry(entry3).//
-					addZipEntry(entry4).//
-					addZipEntry(entry5).//
-					annotations(true).//
-					semanticZoom(true).//
-					images(true).//
-					async(false).//
-					projectDir(tmpResultDir).//
-					addUser("gawi", "gawi").//
-					analyzeAnnotations(true));
-			AuthenticationToken token = userService.login("gawi", "gawi");
-			Project project = projectService.getProjectByProjectId(projectId, token);
-
-			Model model = modelService.getLastModelByProjectId(projectId, token);
-			assertNotNull(model);
-			assertEquals("main", model.getName());
-			assertEquals(3, model.getSubmodelConnections().size());
-
-			Model s1Model = null;
-			Model s2Model = null;
-			Model s3Model = null;
-
-			for (ModelSubmodelConnection submodel : model.getSubmodelConnections()) {
-				if (submodel.getName().equals("s1")) {
-					s1Model = submodel.getSubmodel().getModel();
-				}
-				if (submodel.getName().equals("s2")) {
-					s2Model = submodel.getSubmodel().getModel();
-				}
-				if (submodel.getName().equals("s3")) {
-					s3Model = submodel.getSubmodel().getModel();
-				}
-			}
-			assertNotNull(s1Model);
-			assertNotNull(s2Model);
-			assertNotNull(s3Model);
-
-			Element al1 = model.getElementByElementId("sa1");
-			assertNotNull(al1.getSubmodel());
-			assertEquals(SubmodelType.DOWNSTREAM_TARGETS, al1.getSubmodel().getType());
-			assertEquals(s1Model, al1.getSubmodel().getSubmodel().getModel());
-
-			Element al2 = model.getElementByElementId("sa2");
-			assertNull(al2.getSubmodel());
-
-			Element al4 = model.getElementByElementId("sa4");
-			assertNotNull(al4.getSubmodel());
-			assertEquals(SubmodelType.PATHWAY, al4.getSubmodel().getType());
-			assertEquals(s2Model, al4.getSubmodel().getSubmodel().getModel());
-
-			Element s1_al1 = s1Model.getElementByElementId("sa1");
-			assertNotNull(s1_al1.getSubmodel());
-			assertEquals(SubmodelType.DOWNSTREAM_TARGETS, s1_al1.getSubmodel().getType());
-			assertEquals(s3Model, s1_al1.getSubmodel().getSubmodel().getModel());
-
-			assertEquals(ProjectStatus.DONE, project.getStatus());
-
-			// now check layouts
-			for (Layout l : s2Model.getLayouts()) {
-				assertNotNull(l.getParentLayout());
-			}
-
-			projectService.removeProject(project, null, false, adminToken);
-
-			// and now check layouts (check if every submodel have them, and point
-			// into different directory)
-
-			// there are 2 levels
-			int semanticOverlays = 2;
-			// -1 is due to pathways and compartments that is not there
-			int overlays = BuildInLayout.values().length + semanticOverlays - 1;
-			assertEquals(overlays, model.getLayouts().size());
-			assertEquals(overlays, s1Model.getLayouts().size());
-			assertEquals(overlays, s2Model.getLayouts().size());
-			assertEquals(overlays, s3Model.getLayouts().size());
-			Set<String> directories = new HashSet<String>();
-			directories.add(model.getLayouts().get(0).getDirectory());
-			directories.add(s1Model.getLayouts().get(0).getDirectory());
-			directories.add(s2Model.getLayouts().get(0).getDirectory());
-			directories.add(s3Model.getLayouts().get(0).getDirectory());
-			assertEquals(4, directories.size());
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		} finally {
-			Project project = projectService.getProjectByProjectId(projectId, adminToken);
-			if (project != null) {
-				projectService.removeProject(project, null, false, adminToken);
-			}
-		}
-	}
-
-	@Test
-	public void testGenerateImages() throws Exception {
-		File f = createTempDirectory();
-		String path = f.getAbsolutePath() + "/" + tmpResultDir;
-		try {
-			Model model = getModelForFile("testFiles/sample.xml", false);
-
-			model.addLayout(new Layout(BuildInLayout.NORMAL.getTitle(), path + "/normal", false));
-			model.addLayout(new Layout(BuildInLayout.NESTED.getTitle(), path + "/nested", false));
-
-			CreateProjectParams params = new CreateProjectParams().images(true).//
-					projectDir(tmpResultDir);
-
-			ProjectService pService = new ProjectService();
-
-			pService.createImages(model, params);
-
-			File tmp = new File(path + "/normal");
-			assertTrue(tmp.exists());
-
-			tmp = new File(path + "/nested");
-			assertTrue(tmp.exists());
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		} finally {
-			f.delete();
-		}
-
-	}
-
-	@Test
-	public void testGenerateImagesInSubmodels() throws Exception {
-		File f = createTempDirectory();
-		String path = f.getAbsolutePath() + "/" + tmpResultDir;
-		try {
-			Model model = getModelForFile("testFiles/sample.xml", false);
-
-			Model model2 = getModelForFile("testFiles/sample.xml", false);
-
-			model2.addLayout(new Layout(BuildInLayout.NORMAL.getTitle(), path + "/normal_A", false));
-			model2.addLayout(new Layout(BuildInLayout.NESTED.getTitle(), path + "/nested_B", false));
-
-			model.addSubmodelConnection(new ModelSubmodelConnection(model2, SubmodelType.UNKNOWN, "name"));
-
-			CreateProjectParams params = new CreateProjectParams().images(true).//
-					projectDir(tmpResultDir);
-
-			ProjectService pService = new ProjectService();
-
-			pService.createImages(model, params);
-
-			File tmp = new File(path + "/normal_A");
-			assertTrue(tmp.exists());
-
-			tmp = new File(path + "/nested_B");
-			assertTrue(tmp.exists());
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		} finally {
-			f.delete();
-		}
-
-	}
-
-	@Test
-	public void testCopyComplexWithCompartments() throws Exception {
-		try {
-			String projectId = "Some_id";
-			ZipEntryFile entry1 = new ModelZipEntryFile("main.xml", "main", true, false, SubmodelType.UNKNOWN);
-			ZipEntryFile entry2 = new ModelZipEntryFile("s1.xml", "s1", false, false, SubmodelType.UNKNOWN);
-			ZipEntryFile entry3 = new ModelZipEntryFile("s2.xml", "s2", false, false, SubmodelType.UNKNOWN);
-			ZipEntryFile entry4 = new ModelZipEntryFile("s3.xml", "s3", false, false, SubmodelType.UNKNOWN);
-			ZipEntryFile entry5 = new ModelZipEntryFile("mapping.xml", "mapping", false, true, SubmodelType.UNKNOWN);
-
-			CreateProjectParams params = new CreateProjectParams().//
-					projectId(projectId).//
-					version("").//
-					complex(true).//
-					projectFile("testFiles/complexModel/complex_model_with_compartment.zip").//
-					addZipEntry(entry1).//
-					addZipEntry(entry2).//
-					addZipEntry(entry3).//
-					addZipEntry(entry4).//
-					addZipEntry(entry5).//
-					annotations(false).//
-					images(false).//
-					async(false).//
-					projectDir(tmpResultDir).//
-					analyzeAnnotations(false);
-
-			ComplexZipConverter parser = new ComplexZipConverter(CellDesignerXmlParser.class);
-			ComplexZipConverterParams complexParams;
-			complexParams = new ComplexZipConverterParams().zipFile(params.getProjectFile());
-			for (ZipEntryFile entry : params.getZipEntries()) {
-				complexParams.entry(entry);
-			}
-			Model model = parser.createModel(complexParams);
-
-			assertNotNull(model);
-			assertEquals("main", model.getName());
-			assertEquals(3, model.getSubmodelConnections().size());
-
-			int oldSize = 0;
-			for (Model m : model.getSubmodels()) {
-				oldSize += m.getParentModels().size();
-			}
-
-			new CopyCommand(model).execute();
-
-			int newSize = 0;
-			for (Model m : model.getSubmodels()) {
-				newSize += m.getParentModels().size();
-			}
-			assertEquals("Submodels doesn't match after copying", oldSize, newSize);
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testAnnotatorTree() throws Exception {
-		try {
-			TreeNode tree = projectService.createClassAnnotatorTree(null);
-			assertNotNull(tree);
-
-			AnnotatedObjectTreeRow dataNode = (AnnotatedObjectTreeRow) tree.getData();
-
-			assertEquals(BioEntity.class, dataNode.getClazz());
-
-			Queue<TreeNode> nodes = new LinkedList<TreeNode>();
-			nodes.add(tree);
-			boolean annotatorsFound = false;
-			while (!nodes.isEmpty()) {
-				TreeNode node = nodes.poll();
-				dataNode = (AnnotatedObjectTreeRow) node.getData();
-				if (dataNode.getValidAnnotators().size() > 0) {
-					annotatorsFound = true;
-				}
-				for (TreeNode n : node.getChildren()) {
-					nodes.add(n);
-				}
-			}
-			assertTrue(annotatorsFound);
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-
-	}
-
-	@Test
-	public void testEmptyAnnotatorTreeForUser() throws Exception {
-		try {
-			super.createUser();
-			UserAnnotationSchema schema = new UserAnnotationSchema();
-			user.setAnnotationSchema(schema);
-			userDao.update(user);
-
-			TreeNode tree = projectService.createClassAnnotatorTree(user);
-			assertNotNull(tree);
-
-			AnnotatedObjectTreeRow dataNode = (AnnotatedObjectTreeRow) tree.getData();
-
-			assertEquals(BioEntity.class, dataNode.getClazz());
-
-			Queue<TreeNode> nodes = new LinkedList<TreeNode>();
-			nodes.add(tree);
-			boolean annotatorsFound = false;
-			while (!nodes.isEmpty()) {
-				TreeNode node = nodes.poll();
-				dataNode = (AnnotatedObjectTreeRow) node.getData();
-				assertEquals("Annotators found for class: " + dataNode.getClazz(), 0, dataNode.getUsedAnnotators().size());
-				if (dataNode.getValidAnnotators().size() > 0) {
-					annotatorsFound = true;
-				}
-				for (TreeNode n : node.getChildren()) {
-					nodes.add(n);
-				}
-			}
-			assertTrue(annotatorsFound);
-
-			userDao.delete(user);
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testAnnotatorTreeForUser() throws Exception {
-		try {
-			super.createUser();
-			UserAnnotationSchema schema = new UserAnnotationSchema();
-			schema.addClassAnnotator(new UserClassAnnotators(Protein.class, modelAnnotator.getAvailableAnnotatorNames(Protein.class)));
-			user.setAnnotationSchema(schema);
-			userDao.update(user);
-
-			TreeNode tree = projectService.createClassAnnotatorTree(user);
-			assertNotNull(tree);
-
-			AnnotatedObjectTreeRow dataNode = (AnnotatedObjectTreeRow) tree.getData();
-
-			assertEquals(BioEntity.class, dataNode.getClazz());
-
-			Queue<TreeNode> nodes = new LinkedList<>();
-			nodes.add(tree);
-			boolean annotatorsFound = false;
-			while (!nodes.isEmpty()) {
-				TreeNode node = nodes.poll();
-				dataNode = (AnnotatedObjectTreeRow) node.getData();
-				if (dataNode.getUsedAnnotators().size() > 0) {
-					annotatorsFound = true;
-				}
-				for (TreeNode n : node.getChildren()) {
-					nodes.add(n);
-				}
-			}
-			assertTrue(annotatorsFound);
-
-			userDao.delete(user);
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-
-	}
-
-	@Test
-	public void testEmptyValidMiriamTreeForUser() throws Exception {
-		try {
-			super.createUser();
-			UserAnnotationSchema schema = new UserAnnotationSchema();
-			user.setAnnotationSchema(schema);
-			userDao.update(user);
-
-			TreeNode tree = projectService.createClassAnnotatorTree(user);
-			assertNotNull(tree);
-
-			AnnotatedObjectTreeRow dataNode = (AnnotatedObjectTreeRow) tree.getData();
-
-			assertEquals(BioEntity.class, dataNode.getClazz());
-
-			Queue<TreeNode> nodes = new LinkedList<TreeNode>();
-			nodes.add(tree);
-			boolean annotatorsFound = false;
-			while (!nodes.isEmpty()) {
-				TreeNode node = nodes.poll();
-				dataNode = (AnnotatedObjectTreeRow) node.getData();
-				assertEquals("Valid miriam found for class: " + dataNode.getClazz(), 0, dataNode.getValidAnnotations().size());
-				assertEquals("Required miriam found for class: " + dataNode.getClazz(), 0, dataNode.getRequiredAnnotations().size());
-				if (dataNode.getMissingValidAnnotations().size() > 0 && dataNode.getMissingRequiredAnnotations().size() > 0) {
-					annotatorsFound = true;
-				}
-				for (TreeNode n : node.getChildren()) {
-					nodes.add(n);
-				}
-			}
-			assertTrue(annotatorsFound);
-
-			userDao.delete(user);
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testValidMiriamTreeForUser() throws Exception {
-		try {
-			super.createUser();
-			UserAnnotationSchema schema = new UserAnnotationSchema();
-			schema.addClassValidAnnotations(new UserClassValidAnnotations(Protein.class, MiriamType.values()));
-			user.setAnnotationSchema(schema);
-			userDao.update(user);
-			userDao.flush();
-
-			TreeNode tree = projectService.createClassAnnotatorTree(user);
-			assertNotNull(tree);
-
-			AnnotatedObjectTreeRow dataNode = (AnnotatedObjectTreeRow) tree.getData();
-
-			assertEquals(BioEntity.class, dataNode.getClazz());
-
-			Queue<TreeNode> nodes = new LinkedList<>();
-			nodes.add(tree);
-			boolean annotatorsFound = false;
-			while (!nodes.isEmpty()) {
-				TreeNode node = nodes.poll();
-				dataNode = (AnnotatedObjectTreeRow) node.getData();
-				if (dataNode.getValidAnnotations().size() > 0) {
-					annotatorsFound = true;
-				}
-				for (TreeNode n : node.getChildren()) {
-					nodes.add(n);
-				}
-			}
-			assertTrue(annotatorsFound);
-
-			userDao.delete(user);
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-
-	}
-
-	@Test
-	public void testCreateComplexWithDataMining() throws Exception {
-		String name = "Some_id";
-		try {
-			String filename = "testFiles/complexModel/complex_model_with_data_mining.zip";
-			Project project = createComplexProject(name, filename);
-
-			Model model = modelService.getLastModelByProjectId(name, adminToken);
-			assertNotNull(model);
-			assertEquals("main", model.getName());
-			assertEquals(ProjectStatus.DONE, project.getStatus());
-			boolean dmFound = false;
-			for (Element element : model.getElements()) {
-				if (element.getDataMining().size() > 0) {
-					dmFound = true;
-				}
-			}
-			assertTrue("Cannot find data mining information for the model", dmFound);
-			projectService.removeProject(project, null, false, adminToken);
-			AuthenticationToken token = userService.login(Configuration.ANONYMOUS_LOGIN, null);
-			assertNull(projectService.getProjectByProjectId(name, token));
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	protected Project createComplexProject(String projectId, String filename) throws IOException, SecurityException {
-		CreateProjectParams params = new CreateProjectParams();
-
-		ZipFile zipFile = new ZipFile(filename);
-		Enumeration<? extends ZipEntry> entries = zipFile.entries();
-		while (entries.hasMoreElements()) {
-			ZipEntry entry = entries.nextElement();
-			ZipEntryFile e = zefFactory.createZipEntryFile(entry, zipFile);
-			params.addZipEntry(e);
-		}
-		zipFile.close();
-
-		projectService.createProject(params.//
-				projectId(projectId).//
-				version("").//
-				complex(true).//
-				projectFile(filename).//
-				annotations(true).//
-				images(false).//
-				async(false).//
-				projectDir(tmpResultDir).//
-				addUser("admin", "admin").//
-				analyzeAnnotations(true));
-		AuthenticationToken token = userService.login("admin", "admin");
-		Project project = projectService.getProjectByProjectId(projectId, token);
-		return project;
-	}
-
-	@Test
-	public void testCreateComplexWithImages() throws Exception {
-		try {
-			String name = "Some_id";
-			String filename = "testFiles/complexModel/complex_model_with_images.zip";
-			Project project = createComplexProject(name, filename);
-
-			Model model = modelService.getLastModelByProjectId(name, adminToken);
-			assertNotNull(model);
-			assertEquals("main", model.getName());
-			assertEquals(ProjectStatus.DONE, project.getStatus());
-			assertEquals("Cannot find overview images the model", 2, project.getOverviewImages().size());
-			assertEquals("Number of layouts doesn't match", BuildInLayout.values().length - 1, model.getLayouts().size());
-			assertEquals(BuildInLayout.NESTED.getTitle(), model.getLayouts().get(0).getTitle());
-			assertEquals(BuildInLayout.NORMAL.getTitle(), model.getLayouts().get(1).getTitle());
-			projectService.removeProject(project, null, false, adminToken);
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testCreateComplexWithLayoutOrder() throws Exception {
-		try {
-			String name = "Some_id";
-			String filename = "testFiles/complexModel/complex_model_with_images.zip";
-			CreateProjectParams params = new CreateProjectParams();
-
-			ZipFile zipFile = new ZipFile(filename);
-			Enumeration<? extends ZipEntry> entries = zipFile.entries();
-			while (entries.hasMoreElements()) {
-				ZipEntry entry = entries.nextElement();
-				params.addZipEntry(zefFactory.createZipEntryFile(entry, zipFile));
-			}
-			zipFile.close();
-
-			projectService.createProject(params.//
-					projectId(projectId).//
-					version("").//
-					complex(true).//
-					projectFile(filename).//
-					annotations(true).//
-					images(false).//
-					async(false).//
-					networkLayoutAsDefault(true).//
-					projectDir(tmpResultDir).//
-					addUser("admin", "admin").//
-					analyzeAnnotations(true));
-			Project project = projectService.getProjectByProjectId(projectId, adminToken);
-
-			Model model = modelService.getLastModelByProjectId(name, adminToken);
-			assertNotNull(model);
-			assertEquals("main", model.getName());
-			assertEquals(ProjectStatus.DONE, project.getStatus());
-			assertEquals("Cannot find overview images the model", 2, project.getOverviewImages().size());
-			assertEquals("Number of layouts doesn't match", BuildInLayout.values().length - 1, model.getLayouts().size());
-			assertEquals(BuildInLayout.NESTED.getTitle(), model.getLayouts().get(1).getTitle());
-			assertEquals(BuildInLayout.NORMAL.getTitle(), model.getLayouts().get(0).getTitle());
-			projectService.removeProject(project, null, false, adminToken);
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test(timeout = 15000)
-	public void testCreateComplexWithLayouts() throws Exception {
-		String projectId = "Some_id";
-		try {
-			String filename = "testFiles/complexModel/complex_model_with_layouts.zip";
-			Project project = createComplexProject(projectId, filename);
-
-			Model model = modelService.getLastModelByProjectId(projectId, adminToken);
-			assertNotNull(model);
-			assertEquals("main", model.getName());
-			assertEquals(ProjectStatus.DONE, project.getStatus());
-			assertEquals("Number of layouts doesn't match", BuildInLayout.values().length, model.getLayouts().size());
-			boolean additionalFound = false;
-
-			for (Layout layout : model.getLayouts()) {
-				if ("example name".equals(layout.getTitle())) {
-					additionalFound = true;
-					assertEquals("layout description", layout.getDescription());
-					assertTrue(layout.getDirectory().contains("example"));
-				}
-			}
-			assertTrue("Cannot find layout with predefined name from file", additionalFound);
-			projectService.removeProject(project, null, false, adminToken);
-			assertNull(projectService.getProjectByProjectId(projectId, adminToken));
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testCreateComplexWithSumbaps() throws Exception {
-		try {
-			String name = "Some_id";
-			String filename = "testFiles/complexModel/complex_model_with_submaps.zip";
-			Project project = createComplexProject(name, filename);
-
-			Model model = modelService.getLastModelByProjectId(name, adminToken);
-			assertNotNull(model);
-			assertEquals("main", model.getName());
-			assertEquals(ProjectStatus.DONE, project.getStatus());
-			assertEquals("Number of layouts doesn't match", BuildInLayout.values().length - 1, model.getLayouts().size());
-			projectService.removeProject(project, null, false, adminToken);
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testCreateEmptyComplex() throws Exception {
-		try {
-			String name = "Some_id";
-			String filename = "testFiles/complexModel/empty_complex_model.zip";
-			Project project = createComplexProject(name, filename);
-
-			Model model = modelService.getLastModelByProjectId(name, adminToken);
-			assertNotNull(model);
-			assertEquals(ProjectStatus.DONE, project.getStatus());
-			projectService.removeProject(project, null, false, adminToken);
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testCreateEmptyComplex2() throws Exception {
-		try {
-			String name = "Some_id";
-			String filename = "testFiles/complexModel/empty_complex_model2.zip";
-			Project project = createComplexProject(name, filename);
-
-			Model model = modelService.getLastModelByProjectId(name, adminToken);
-			assertNotNull(model);
-			assertEquals(ProjectStatus.DONE, project.getStatus());
-			projectService.removeProject(project, null, false, adminToken);
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testCreateEmptyComplex3() throws Exception {
-		try {
-			String name = "Some_id";
-			String filename = "testFiles/complexModel/empty_complex_model3.zip";
-			Project project = createComplexProject(name, filename);
-
-			Model model = modelService.getLastModelByProjectId(name, adminToken);
-			assertNotNull(model);
-			assertEquals(ProjectStatus.DONE, project.getStatus());
-			projectService.removeProject(project, null, false, adminToken);
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-}
+package lcsb.mapviewer.services.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Queue;
+import java.util.Set;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.apache.log4j.Logger;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.primefaces.model.TreeNode;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.annotation.Rollback;
+
+import lcsb.mapviewer.commands.CopyCommand;
+import lcsb.mapviewer.common.Configuration;
+import lcsb.mapviewer.converter.ComplexZipConverter;
+import lcsb.mapviewer.converter.ComplexZipConverterParams;
+import lcsb.mapviewer.converter.model.celldesigner.CellDesignerXmlParser;
+import lcsb.mapviewer.converter.zip.ModelZipEntryFile;
+import lcsb.mapviewer.converter.zip.ZipEntryFile;
+import lcsb.mapviewer.converter.zip.ZipEntryFileFactory;
+import lcsb.mapviewer.model.Project;
+import lcsb.mapviewer.model.ProjectStatus;
+import lcsb.mapviewer.model.map.BioEntity;
+import lcsb.mapviewer.model.map.MiriamType;
+import lcsb.mapviewer.model.map.layout.Layout;
+import lcsb.mapviewer.model.map.model.Model;
+import lcsb.mapviewer.model.map.model.ModelSubmodelConnection;
+import lcsb.mapviewer.model.map.model.SubmodelType;
+import lcsb.mapviewer.model.map.species.Element;
+import lcsb.mapviewer.model.map.species.Protein;
+import lcsb.mapviewer.model.user.ObjectPrivilege;
+import lcsb.mapviewer.model.user.PrivilegeType;
+import lcsb.mapviewer.model.user.User;
+import lcsb.mapviewer.model.user.UserAnnotationSchema;
+import lcsb.mapviewer.model.user.UserClassAnnotators;
+import lcsb.mapviewer.model.user.UserClassValidAnnotations;
+import lcsb.mapviewer.persist.dao.map.species.ElementDao;
+import lcsb.mapviewer.services.SecurityException;
+import lcsb.mapviewer.services.ServiceTestFunctions;
+import lcsb.mapviewer.services.overlay.AnnotatedObjectTreeRow;
+import lcsb.mapviewer.services.utils.CreateProjectParams;
+import lcsb.mapviewer.services.utils.data.BuildInLayout;
+import lcsb.mapviewer.services.view.AuthenticationToken;
+import lcsb.mapviewer.services.view.ProjectView;
+
+@Rollback(true)
+public class ProjectServiceTest extends ServiceTestFunctions {
+  Logger logger = Logger.getLogger(ProjectServiceTest.class);
+
+  ZipEntryFileFactory zefFactory = new ZipEntryFileFactory();
+
+  private final String tmpResultDir = "tmp/";
+  String projectId = "Some_id";
+
+  @Autowired
+  ElementDao aliasDao;
+
+  // assume that we have admin account with all the privileges
+  AuthenticationToken adminToken;
+
+  @Before
+  public void setUp() throws Exception {
+    adminToken = userService.login("admin", "admin");
+  }
+
+  @After
+  public void tearDown() throws Exception {
+  }
+
+  @Test
+  public void testGetProjectWithoutAccessToEverything() {
+    try {
+      createUser();
+      AuthenticationToken token = userService.login(user.getLogin(), "passwd");
+      List<Project> projects = projectService.getAllProjects(token);
+      assertNotNull(projects);
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void test() {
+    try {
+      List<Project> projects = projectService.getAllProjects(adminToken);
+
+      Project project = new Project();
+      project.setProjectId(projectId);
+      projectDao.add(project);
+      projectDao.evict(project);
+
+      List<Project> projects2 = projectService.getAllProjects(adminToken);
+
+      assertEquals(projects.size() + 1, projects2.size());
+
+      for (Project tmpProject : projects2) {
+        if (!projects.contains(tmpProject)) {
+          assertEquals(projectId, tmpProject.getProjectId());
+        }
+      }
+
+      Project project2 = projectDao.getProjectByProjectId(projectId);
+      assertNotNull(project2);
+      assertFalse(project2.equals(project));
+      assertEquals(project.getId(), project2.getId());
+
+      projectDao.delete(project2);
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testRemove() throws Exception {
+
+    try {
+      String project_id = "Some_id";
+      Project project = new Project();
+      project.setProjectId(project_id);
+      projectDao.add(project);
+
+      List<ProjectView> projects2 = projectService.getAllProjectViews(adminToken);
+      ProjectView row = null;
+      for (ProjectView projectRow : projects2) {
+        if (projectRow.getIdObject() == project.getId()) {
+          row = projectRow;
+        }
+      }
+      assertNotNull(row);
+
+      User user = new User();
+      user.setLogin("x");
+      userDao.add(user);
+      userDao.evict(user);
+
+      int userId = user.getId();
+
+      user = userService.getUserById(userId);
+
+      userDao.evict(user);
+
+      userService.setUserPrivilege(user, new ObjectPrivilege(project, 1, PrivilegeType.VIEW_PROJECT, user));
+
+      user = userService.getUserById(userId);
+      int newAmount = user.getPrivileges().size();
+
+      userDao.evict(user);
+
+      projectService.removeProject(row, tmpResultDir, false, adminToken);
+
+      user = userService.getUserById(userId);
+
+      assertEquals("After removing project number of privileges didn't drop down", newAmount - 1,
+          user.getPrivileges().size());
+
+      userDao.delete(user);
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testRemoveUserAfterRemoveProject() throws Exception {
+
+    try {
+      String projectId = "Some_id";
+      Project project = new Project();
+      project.setProjectId(projectId);
+      projectDao.add(project);
+
+      List<ProjectView> projects2 = projectService.getAllProjectViews(adminToken);
+      ProjectView row = null;
+      for (ProjectView projectRow : projects2) {
+        if (projectRow.getIdObject() == project.getId()) {
+          row = projectRow;
+        }
+      }
+      assertNotNull(row);
+
+      User user = new User();
+      user.setLogin("x");
+      userDao.add(user);
+      userDao.evict(user);
+
+      int userId = user.getId();
+
+      userService.setUserPrivilege(user, new ObjectPrivilege(project, 1, PrivilegeType.VIEW_PROJECT, user));
+
+      user = userService.getUserById(userId);
+
+      long counter = logDao.getCount();
+      projectService.removeProject(row, tmpResultDir, false, adminToken);
+      long counter2 = logDao.getCount();
+      assertTrue("Logs didn't appear after removing project", counter < counter2);
+
+      user = userService.getUserById(userId);
+      userDao.delete(user);
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testUpdater() throws Exception {
+    try {
+      String project_id = "test_id";
+      projectService.createProject(new CreateProjectParams().//
+          authenticationToken(adminToken).//
+          projectId(project_id).//
+          version("").//
+          projectFile("testFiles/centeredAnchorInModifier.xml").//
+          annotations(true).//
+          images(true).//
+          async(false).//
+          projectDir(tmpResultDir).//
+          addUser("gawi", "gawi").//
+          analyzeAnnotations(true));
+      AuthenticationToken token = userService.login("gawi", "gawi");
+      Project project = projectService.getProjectByProjectId(project_id, token);
+      assertEquals(ProjectStatus.DONE, project.getStatus());
+      projectService.removeProject(project, null, false, adminToken);
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testCreateComplex() throws Exception {
+    String projectId = "test_id";
+    try {
+      ZipEntryFile entry1 = new ModelZipEntryFile("main.xml", "main", true, false, SubmodelType.UNKNOWN);
+      ZipEntryFile entry2 = new ModelZipEntryFile("s1.xml", "s1", false, false, SubmodelType.UNKNOWN);
+      ZipEntryFile entry3 = new ModelZipEntryFile("s2.xml", "s2", false, false, SubmodelType.UNKNOWN);
+      ZipEntryFile entry4 = new ModelZipEntryFile("s3.xml", "s3", false, false, SubmodelType.UNKNOWN);
+      ZipEntryFile entry5 = new ModelZipEntryFile("mapping.xml", "mapping", false, true, SubmodelType.UNKNOWN);
+      projectService.createProject(new CreateProjectParams().//
+          authenticationToken(adminToken).//
+          projectId(projectId).//
+          version("").//
+          complex(true).//
+          projectFile("testFiles/complexModel/complex_model.zip").//
+          addZipEntry(entry1).//
+          addZipEntry(entry2).//
+          addZipEntry(entry3).//
+          addZipEntry(entry4).//
+          addZipEntry(entry5).//
+          annotations(true).//
+          semanticZoom(true).//
+          images(true).//
+          async(false).//
+          projectDir(tmpResultDir).//
+          addUser("gawi", "gawi").//
+          analyzeAnnotations(true));
+      AuthenticationToken token = userService.login("gawi", "gawi");
+      Project project = projectService.getProjectByProjectId(projectId, token);
+
+      Model model = modelService.getLastModelByProjectId(projectId, token);
+      assertNotNull(model);
+      assertEquals("main", model.getName());
+      assertEquals(3, model.getSubmodelConnections().size());
+
+      Model s1Model = null;
+      Model s2Model = null;
+      Model s3Model = null;
+
+      for (ModelSubmodelConnection submodel : model.getSubmodelConnections()) {
+        if (submodel.getName().equals("s1")) {
+          s1Model = submodel.getSubmodel().getModel();
+        }
+        if (submodel.getName().equals("s2")) {
+          s2Model = submodel.getSubmodel().getModel();
+        }
+        if (submodel.getName().equals("s3")) {
+          s3Model = submodel.getSubmodel().getModel();
+        }
+      }
+      assertNotNull(s1Model);
+      assertNotNull(s2Model);
+      assertNotNull(s3Model);
+
+      Element al1 = model.getElementByElementId("sa1");
+      assertNotNull(al1.getSubmodel());
+      assertEquals(SubmodelType.DOWNSTREAM_TARGETS, al1.getSubmodel().getType());
+      assertEquals(s1Model, al1.getSubmodel().getSubmodel().getModel());
+
+      Element al2 = model.getElementByElementId("sa2");
+      assertNull(al2.getSubmodel());
+
+      Element al4 = model.getElementByElementId("sa4");
+      assertNotNull(al4.getSubmodel());
+      assertEquals(SubmodelType.PATHWAY, al4.getSubmodel().getType());
+      assertEquals(s2Model, al4.getSubmodel().getSubmodel().getModel());
+
+      Element s1_al1 = s1Model.getElementByElementId("sa1");
+      assertNotNull(s1_al1.getSubmodel());
+      assertEquals(SubmodelType.DOWNSTREAM_TARGETS, s1_al1.getSubmodel().getType());
+      assertEquals(s3Model, s1_al1.getSubmodel().getSubmodel().getModel());
+
+      assertEquals(ProjectStatus.DONE, project.getStatus());
+
+      // now check layouts
+      for (Layout l : s2Model.getLayouts()) {
+        assertNotNull(l.getParentLayout());
+      }
+
+      projectService.removeProject(project, null, false, adminToken);
+
+      // and now check layouts (check if every submodel have them, and point
+      // into different directory)
+
+      // there are 2 levels
+      int semanticOverlays = 2;
+      // -1 is due to pathways and compartments that is not there
+      int overlays = BuildInLayout.values().length + semanticOverlays - 1;
+      assertEquals(overlays, model.getLayouts().size());
+      assertEquals(overlays, s1Model.getLayouts().size());
+      assertEquals(overlays, s2Model.getLayouts().size());
+      assertEquals(overlays, s3Model.getLayouts().size());
+      Set<String> directories = new HashSet<String>();
+      directories.add(model.getLayouts().get(0).getDirectory());
+      directories.add(s1Model.getLayouts().get(0).getDirectory());
+      directories.add(s2Model.getLayouts().get(0).getDirectory());
+      directories.add(s3Model.getLayouts().get(0).getDirectory());
+      assertEquals(4, directories.size());
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    } finally {
+      Project project = projectService.getProjectByProjectId(projectId, adminToken);
+      if (project != null) {
+        projectService.removeProject(project, null, false, adminToken);
+      }
+    }
+  }
+
+  @Test
+  public void testGenerateImages() throws Exception {
+    File f = createTempDirectory();
+    String path = f.getAbsolutePath() + "/" + tmpResultDir;
+    try {
+      Model model = getModelForFile("testFiles/sample.xml", false);
+
+      model.addLayout(new Layout(BuildInLayout.NORMAL.getTitle(), path + "/normal", false));
+      model.addLayout(new Layout(BuildInLayout.NESTED.getTitle(), path + "/nested", false));
+
+      CreateProjectParams params = new CreateProjectParams().images(true).//
+          projectDir(tmpResultDir);
+
+      ProjectService pService = new ProjectService();
+
+      pService.createImages(model, params);
+
+      File tmp = new File(path + "/normal");
+      assertTrue(tmp.exists());
+
+      tmp = new File(path + "/nested");
+      assertTrue(tmp.exists());
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    } finally {
+      f.delete();
+    }
+
+  }
+
+  @Test
+  public void testGenerateImagesInSubmodels() throws Exception {
+    File f = createTempDirectory();
+    String path = f.getAbsolutePath() + "/" + tmpResultDir;
+    try {
+      Model model = getModelForFile("testFiles/sample.xml", false);
+
+      Model model2 = getModelForFile("testFiles/sample.xml", false);
+
+      model2.addLayout(new Layout(BuildInLayout.NORMAL.getTitle(), path + "/normal_A", false));
+      model2.addLayout(new Layout(BuildInLayout.NESTED.getTitle(), path + "/nested_B", false));
+
+      model.addSubmodelConnection(new ModelSubmodelConnection(model2, SubmodelType.UNKNOWN, "name"));
+
+      CreateProjectParams params = new CreateProjectParams().images(true).//
+          projectDir(tmpResultDir);
+
+      ProjectService pService = new ProjectService();
+
+      pService.createImages(model, params);
+
+      File tmp = new File(path + "/normal_A");
+      assertTrue(tmp.exists());
+
+      tmp = new File(path + "/nested_B");
+      assertTrue(tmp.exists());
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    } finally {
+      f.delete();
+    }
+
+  }
+
+  @Test
+  public void testCopyComplexWithCompartments() throws Exception {
+    try {
+      String projectId = "Some_id";
+      ZipEntryFile entry1 = new ModelZipEntryFile("main.xml", "main", true, false, SubmodelType.UNKNOWN);
+      ZipEntryFile entry2 = new ModelZipEntryFile("s1.xml", "s1", false, false, SubmodelType.UNKNOWN);
+      ZipEntryFile entry3 = new ModelZipEntryFile("s2.xml", "s2", false, false, SubmodelType.UNKNOWN);
+      ZipEntryFile entry4 = new ModelZipEntryFile("s3.xml", "s3", false, false, SubmodelType.UNKNOWN);
+      ZipEntryFile entry5 = new ModelZipEntryFile("mapping.xml", "mapping", false, true, SubmodelType.UNKNOWN);
+
+      CreateProjectParams params = new CreateProjectParams().//
+          projectId(projectId).//
+          version("").//
+          complex(true).//
+          projectFile("testFiles/complexModel/complex_model_with_compartment.zip").//
+          addZipEntry(entry1).//
+          addZipEntry(entry2).//
+          addZipEntry(entry3).//
+          addZipEntry(entry4).//
+          addZipEntry(entry5).//
+          annotations(false).//
+          images(false).//
+          async(false).//
+          projectDir(tmpResultDir).//
+          analyzeAnnotations(false);
+
+      ComplexZipConverter parser = new ComplexZipConverter(CellDesignerXmlParser.class);
+      ComplexZipConverterParams complexParams;
+      complexParams = new ComplexZipConverterParams().zipFile(params.getProjectFile());
+      for (ZipEntryFile entry : params.getZipEntries()) {
+        complexParams.entry(entry);
+      }
+      Model model = parser.createModel(complexParams);
+
+      assertNotNull(model);
+      assertEquals("main", model.getName());
+      assertEquals(3, model.getSubmodelConnections().size());
+
+      int oldSize = 0;
+      for (Model m : model.getSubmodels()) {
+        oldSize += m.getParentModels().size();
+      }
+
+      new CopyCommand(model).execute();
+
+      int newSize = 0;
+      for (Model m : model.getSubmodels()) {
+        newSize += m.getParentModels().size();
+      }
+      assertEquals("Submodels doesn't match after copying", oldSize, newSize);
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testAnnotatorTree() throws Exception {
+    try {
+      TreeNode tree = projectService.createClassAnnotatorTree(null);
+      assertNotNull(tree);
+
+      AnnotatedObjectTreeRow dataNode = (AnnotatedObjectTreeRow) tree.getData();
+
+      assertEquals(BioEntity.class, dataNode.getClazz());
+
+      Queue<TreeNode> nodes = new LinkedList<TreeNode>();
+      nodes.add(tree);
+      boolean annotatorsFound = false;
+      while (!nodes.isEmpty()) {
+        TreeNode node = nodes.poll();
+        dataNode = (AnnotatedObjectTreeRow) node.getData();
+        if (dataNode.getValidAnnotators().size() > 0) {
+          annotatorsFound = true;
+        }
+        for (TreeNode n : node.getChildren()) {
+          nodes.add(n);
+        }
+      }
+      assertTrue(annotatorsFound);
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+
+  }
+
+  @Test
+  public void testEmptyAnnotatorTreeForUser() throws Exception {
+    try {
+      super.createUser();
+      UserAnnotationSchema schema = new UserAnnotationSchema();
+      user.setAnnotationSchema(schema);
+      userDao.update(user);
+
+      TreeNode tree = projectService.createClassAnnotatorTree(user);
+      assertNotNull(tree);
+
+      AnnotatedObjectTreeRow dataNode = (AnnotatedObjectTreeRow) tree.getData();
+
+      assertEquals(BioEntity.class, dataNode.getClazz());
+
+      Queue<TreeNode> nodes = new LinkedList<TreeNode>();
+      nodes.add(tree);
+      boolean annotatorsFound = false;
+      while (!nodes.isEmpty()) {
+        TreeNode node = nodes.poll();
+        dataNode = (AnnotatedObjectTreeRow) node.getData();
+        assertEquals("Annotators found for class: " + dataNode.getClazz(), 0, dataNode.getUsedAnnotators().size());
+        if (dataNode.getValidAnnotators().size() > 0) {
+          annotatorsFound = true;
+        }
+        for (TreeNode n : node.getChildren()) {
+          nodes.add(n);
+        }
+      }
+      assertTrue(annotatorsFound);
+
+      userDao.delete(user);
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testAnnotatorTreeForUser() throws Exception {
+    try {
+      super.createUser();
+      UserAnnotationSchema schema = new UserAnnotationSchema();
+      schema.addClassAnnotator(
+          new UserClassAnnotators(Protein.class, modelAnnotator.getAvailableAnnotatorNames(Protein.class)));
+      user.setAnnotationSchema(schema);
+      userDao.update(user);
+
+      TreeNode tree = projectService.createClassAnnotatorTree(user);
+      assertNotNull(tree);
+
+      AnnotatedObjectTreeRow dataNode = (AnnotatedObjectTreeRow) tree.getData();
+
+      assertEquals(BioEntity.class, dataNode.getClazz());
+
+      Queue<TreeNode> nodes = new LinkedList<>();
+      nodes.add(tree);
+      boolean annotatorsFound = false;
+      while (!nodes.isEmpty()) {
+        TreeNode node = nodes.poll();
+        dataNode = (AnnotatedObjectTreeRow) node.getData();
+        if (dataNode.getUsedAnnotators().size() > 0) {
+          annotatorsFound = true;
+        }
+        for (TreeNode n : node.getChildren()) {
+          nodes.add(n);
+        }
+      }
+      assertTrue(annotatorsFound);
+
+      userDao.delete(user);
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+
+  }
+
+  @Test
+  public void testEmptyValidMiriamTreeForUser() throws Exception {
+    try {
+      super.createUser();
+      UserAnnotationSchema schema = new UserAnnotationSchema();
+      user.setAnnotationSchema(schema);
+      userDao.update(user);
+
+      TreeNode tree = projectService.createClassAnnotatorTree(user);
+      assertNotNull(tree);
+
+      AnnotatedObjectTreeRow dataNode = (AnnotatedObjectTreeRow) tree.getData();
+
+      assertEquals(BioEntity.class, dataNode.getClazz());
+
+      Queue<TreeNode> nodes = new LinkedList<TreeNode>();
+      nodes.add(tree);
+      boolean annotatorsFound = false;
+      while (!nodes.isEmpty()) {
+        TreeNode node = nodes.poll();
+        dataNode = (AnnotatedObjectTreeRow) node.getData();
+        assertEquals("Valid miriam found for class: " + dataNode.getClazz(), 0, dataNode.getValidAnnotations().size());
+        assertEquals("Required miriam found for class: " + dataNode.getClazz(), 0,
+            dataNode.getRequiredAnnotations().size());
+        if (dataNode.getMissingValidAnnotations().size() > 0 && dataNode.getMissingRequiredAnnotations().size() > 0) {
+          annotatorsFound = true;
+        }
+        for (TreeNode n : node.getChildren()) {
+          nodes.add(n);
+        }
+      }
+      assertTrue(annotatorsFound);
+
+      userDao.delete(user);
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testValidMiriamTreeForUser() throws Exception {
+    try {
+      super.createUser();
+      UserAnnotationSchema schema = new UserAnnotationSchema();
+      schema.addClassValidAnnotations(new UserClassValidAnnotations(Protein.class, MiriamType.values()));
+      user.setAnnotationSchema(schema);
+      userDao.update(user);
+      userDao.flush();
+
+      TreeNode tree = projectService.createClassAnnotatorTree(user);
+      assertNotNull(tree);
+
+      AnnotatedObjectTreeRow dataNode = (AnnotatedObjectTreeRow) tree.getData();
+
+      assertEquals(BioEntity.class, dataNode.getClazz());
+
+      Queue<TreeNode> nodes = new LinkedList<>();
+      nodes.add(tree);
+      boolean annotatorsFound = false;
+      while (!nodes.isEmpty()) {
+        TreeNode node = nodes.poll();
+        dataNode = (AnnotatedObjectTreeRow) node.getData();
+        if (dataNode.getValidAnnotations().size() > 0) {
+          annotatorsFound = true;
+        }
+        for (TreeNode n : node.getChildren()) {
+          nodes.add(n);
+        }
+      }
+      assertTrue(annotatorsFound);
+
+      userDao.delete(user);
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+
+  }
+
+  @Test
+  public void testCreateComplexWithDataMining() throws Exception {
+    String name = "Some_id";
+    try {
+      String filename = "testFiles/complexModel/complex_model_with_data_mining.zip";
+      Project project = createComplexProject(name, filename);
+
+      Model model = modelService.getLastModelByProjectId(name, adminToken);
+      assertNotNull(model);
+      assertEquals("main", model.getName());
+      assertEquals(ProjectStatus.DONE, project.getStatus());
+      boolean dmFound = false;
+      for (Element element : model.getElements()) {
+        if (element.getDataMining().size() > 0) {
+          dmFound = true;
+        }
+      }
+      assertTrue("Cannot find data mining information for the model", dmFound);
+      projectService.removeProject(project, null, false, adminToken);
+      AuthenticationToken token = userService.login(Configuration.ANONYMOUS_LOGIN, null);
+      assertNull(projectService.getProjectByProjectId(name, token));
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  protected Project createComplexProject(String projectId, String filename) throws IOException, SecurityException {
+    CreateProjectParams params = new CreateProjectParams();
+
+    ZipFile zipFile = new ZipFile(filename);
+    Enumeration<? extends ZipEntry> entries = zipFile.entries();
+    while (entries.hasMoreElements()) {
+      ZipEntry entry = entries.nextElement();
+      ZipEntryFile e = zefFactory.createZipEntryFile(entry, zipFile);
+      params.addZipEntry(e);
+    }
+    zipFile.close();
+
+    projectService.createProject(params.//
+        authenticationToken(adminToken).//
+        projectId(projectId).//
+        version("").//
+        complex(true).//
+        projectFile(filename).//
+        annotations(true).//
+        images(false).//
+        async(false).//
+        projectDir(tmpResultDir).//
+        addUser("admin", "admin").//
+        analyzeAnnotations(true));
+    AuthenticationToken token = userService.login("admin", "admin");
+    Project project = projectService.getProjectByProjectId(projectId, token);
+    return project;
+  }
+
+  @Test
+  public void testCreateComplexWithImages() throws Exception {
+    try {
+      String name = "Some_id";
+      String filename = "testFiles/complexModel/complex_model_with_images.zip";
+      Project project = createComplexProject(name, filename);
+
+      Model model = modelService.getLastModelByProjectId(name, adminToken);
+      assertNotNull(model);
+      assertEquals("main", model.getName());
+      assertEquals(ProjectStatus.DONE, project.getStatus());
+      assertEquals("Cannot find overview images the model", 2, project.getOverviewImages().size());
+      assertEquals("Number of layouts doesn't match", BuildInLayout.values().length - 1, model.getLayouts().size());
+      assertEquals(BuildInLayout.NESTED.getTitle(), model.getLayouts().get(0).getTitle());
+      assertEquals(BuildInLayout.NORMAL.getTitle(), model.getLayouts().get(1).getTitle());
+      projectService.removeProject(project, null, false, adminToken);
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testCreateComplexWithLayoutOrder() throws Exception {
+    try {
+      String name = "Some_id";
+      String filename = "testFiles/complexModel/complex_model_with_images.zip";
+      CreateProjectParams params = new CreateProjectParams();
+
+      ZipFile zipFile = new ZipFile(filename);
+      Enumeration<? extends ZipEntry> entries = zipFile.entries();
+      while (entries.hasMoreElements()) {
+        ZipEntry entry = entries.nextElement();
+        params.addZipEntry(zefFactory.createZipEntryFile(entry, zipFile));
+      }
+      zipFile.close();
+
+      projectService.createProject(params.//
+          authenticationToken(adminToken).//
+          projectId(projectId).//
+          version("").//
+          complex(true).//
+          projectFile(filename).//
+          annotations(true).//
+          images(false).//
+          async(false).//
+          networkLayoutAsDefault(true).//
+          projectDir(tmpResultDir).//
+          addUser("admin", "admin").//
+          analyzeAnnotations(true));
+      Project project = projectService.getProjectByProjectId(projectId, adminToken);
+
+      Model model = modelService.getLastModelByProjectId(name, adminToken);
+      assertNotNull(model);
+      assertEquals("main", model.getName());
+      assertEquals(ProjectStatus.DONE, project.getStatus());
+      assertEquals("Cannot find overview images the model", 2, project.getOverviewImages().size());
+      assertEquals("Number of layouts doesn't match", BuildInLayout.values().length - 1, model.getLayouts().size());
+      assertEquals(BuildInLayout.NESTED.getTitle(), model.getLayouts().get(1).getTitle());
+      assertEquals(BuildInLayout.NORMAL.getTitle(), model.getLayouts().get(0).getTitle());
+      projectService.removeProject(project, null, false, adminToken);
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test(timeout = 15000)
+  public void testCreateComplexWithLayouts() throws Exception {
+    String projectId = "Some_id";
+    try {
+      String filename = "testFiles/complexModel/complex_model_with_layouts.zip";
+      Project project = createComplexProject(projectId, filename);
+
+      Model model = modelService.getLastModelByProjectId(projectId, adminToken);
+      assertNotNull(model);
+      assertEquals("main", model.getName());
+      assertEquals(ProjectStatus.DONE, project.getStatus());
+      assertEquals("Number of layouts doesn't match", BuildInLayout.values().length, model.getLayouts().size());
+      boolean additionalFound = false;
+
+      for (Layout layout : model.getLayouts()) {
+        if ("example name".equals(layout.getTitle())) {
+          additionalFound = true;
+          assertEquals("layout description", layout.getDescription());
+          assertTrue(layout.getDirectory().contains("example"));
+        }
+      }
+      assertTrue("Cannot find layout with predefined name from file", additionalFound);
+      projectService.removeProject(project, null, false, adminToken);
+      assertNull(projectService.getProjectByProjectId(projectId, adminToken));
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testCreateComplexWithSumbaps() throws Exception {
+    try {
+      String name = "Some_id";
+      String filename = "testFiles/complexModel/complex_model_with_submaps.zip";
+      Project project = createComplexProject(name, filename);
+
+      Model model = modelService.getLastModelByProjectId(name, adminToken);
+      assertNotNull(model);
+      assertEquals("main", model.getName());
+      assertEquals(ProjectStatus.DONE, project.getStatus());
+      assertEquals("Number of layouts doesn't match", BuildInLayout.values().length - 1, model.getLayouts().size());
+      projectService.removeProject(project, null, false, adminToken);
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testCreateEmptyComplex() throws Exception {
+    try {
+      String name = "Some_id";
+      String filename = "testFiles/complexModel/empty_complex_model.zip";
+      Project project = createComplexProject(name, filename);
+
+      Model model = modelService.getLastModelByProjectId(name, adminToken);
+      assertNotNull(model);
+      assertEquals(ProjectStatus.DONE, project.getStatus());
+      projectService.removeProject(project, null, false, adminToken);
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testCreateEmptyComplex2() throws Exception {
+    try {
+      String name = "Some_id";
+      String filename = "testFiles/complexModel/empty_complex_model2.zip";
+      Project project = createComplexProject(name, filename);
+
+      Model model = modelService.getLastModelByProjectId(name, adminToken);
+      assertNotNull(model);
+      assertEquals(ProjectStatus.DONE, project.getStatus());
+      projectService.removeProject(project, null, false, adminToken);
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testCreateEmptyComplex3() throws Exception {
+    try {
+      String name = "Some_id";
+      String filename = "testFiles/complexModel/empty_complex_model3.zip";
+      Project project = createComplexProject(name, filename);
+
+      Model model = modelService.getLastModelByProjectId(name, adminToken);
+      assertNotNull(model);
+      assertEquals(ProjectStatus.DONE, project.getStatus());
+      projectService.removeProject(project, null, false, adminToken);
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+}