diff --git a/converter/src/main/java/lcsb/mapviewer/converter/ComplexZipConverter.java b/converter/src/main/java/lcsb/mapviewer/converter/ComplexZipConverter.java
index e2640f0b3ecfafcf9d143f661a8d4dd6807b37c1..12f391a07b0474df7bfcbeda5e93ab8ccbc328e1 100644
--- a/converter/src/main/java/lcsb/mapviewer/converter/ComplexZipConverter.java
+++ b/converter/src/main/java/lcsb/mapviewer/converter/ComplexZipConverter.java
@@ -114,6 +114,8 @@ public class ComplexZipConverter {
         ZipEntry entry = entries.nextElement();
         if (!entry.isDirectory()) {
           ZipEntryFile zef = params.getEntry(entry.getName());
+          logger.debug(entry.getName());
+          logger.debug(zef);
           if (zef instanceof ModelZipEntryFile) {
             ModelZipEntryFile modelEntryFile = (ModelZipEntryFile) zef;
             InputStream is = zipFile.getInputStream(entry);
@@ -133,7 +135,7 @@ public class ComplexZipConverter {
             // imageEntries.add((ImageZipEntryFile) zef);
           } else if (zef instanceof DataMiningZipEntryFile) {
             dataMiningSets.add(dataMiningZipEntryToDataMiningSet(zipFile, entry, (DataMiningZipEntryFile) zef));
-          } else {
+          } else if (!isIgnoredFile(entry.getName())) {
             throw new NotImplementedException("Unknwon entry type: " + zef.getClass());
           }
         }
@@ -181,6 +183,19 @@ public class ComplexZipConverter {
     }
   }
 
+  protected boolean isIgnoredFile(String name) {
+    if (name == null) {
+      return true;
+    } else if (name.isEmpty()) {
+      return true;
+    } else if (name.startsWith(".DS_Store")) {
+      return true;
+    } else if (name.startsWith("__MACOSX")) {
+      return true;
+    }
+    return false;
+  }
+
   /**
    * Process a single reaction in mapping file (transfomring reaction into
    * connection between submodels).
@@ -278,13 +293,12 @@ public class ComplexZipConverter {
 
     String root = null;
     String mapping = null;
-    logger.debug(params.getFilenames());
     while (entries.hasMoreElements()) {
       ZipEntry entry = entries.nextElement();
       if (!entry.isDirectory()) {
         String name = entry.getName();
         ZipEntryFile zef = params.getEntry(name);
-        if (zef == null) {
+        if (zef == null && !isIgnoredFile(name)) {
           throw new InvalidArgumentException("No information found in params about file: " + name);
         }
         if (zef instanceof ModelZipEntryFile) {
diff --git a/converter/src/test/java/lcsb/mapviewer/converter/ComplexZipConverterTest.java b/converter/src/test/java/lcsb/mapviewer/converter/ComplexZipConverterTest.java
index 6d8f7acb690f1c8cda2b868de108b1c462ae506a..4d768d5aa99d4578a1ffe8b58f9b0efd74d7c9e1 100644
--- a/converter/src/test/java/lcsb/mapviewer/converter/ComplexZipConverterTest.java
+++ b/converter/src/test/java/lcsb/mapviewer/converter/ComplexZipConverterTest.java
@@ -1,8 +1,10 @@
 package lcsb.mapviewer.converter;
 
 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 static org.junit.Assert.fail;
 
 import java.io.File;
@@ -35,461 +37,494 @@ import lcsb.mapviewer.model.map.species.Species;
 
 public class ComplexZipConverterTest {
 
-	@SuppressWarnings("unused")
-	private static Logger logger = Logger.getLogger(ComplexZipConverterTest.class);
-
-	private abstract class AbstractConverter implements IConverter {
-
-	}
-
-	private interface InterfaceConverter extends IConverter {
-
-	}
-
-	public static class MockConverter implements IConverter {
-
-		@Override
-		public Model createModel(ConverterParams params) {
-			Model result = new ModelFullIndexed(null);
-
-			Species sa1 = new GenericProtein("sa1");
-			result.addElement(sa1);
-
-			Species sa2 = new GenericProtein("sa2");
-			result.addElement(sa2);
-
-			Species sa3 = new GenericProtein("sa3");
-			result.addElement(sa3);
-
-			Species sa4 = new Phenotype("sa4");
-			result.addElement(sa4);
-
-			Complex ca1 = new Complex("ca1");
-			ca1.setName("main");
-			result.addElement(ca1);
-			Species sa5 = new GenericProtein("sa5");
-			sa5.setName("sa1");
-			result.addElement(sa5);
-			ca1.addSpecies(sa5);
-			Species sa6 = new Phenotype("sa6");
-			sa6.setName("sa4");
-			result.addElement(sa6);
-			ca1.addSpecies(sa6);
-
-			Complex ca2 = new Complex("ca2");
-			ca2.setName("s1");
-			result.addElement(ca2);
-			Species sa7 = new GenericProtein("sa7");
-			sa7.setName("sa1");
-			result.addElement(sa7);
-			ca2.addSpecies(sa7);
-
-			Complex ca3 = new Complex("cs3");
-			ca3.setName("s2");
-			result.addElement(ca3);
-
-			Complex ca4 = new Complex("cs4");
-			ca4.setName("s3");
-			result.addElement(ca4);
-
-			Reaction r1 = new TransportReaction("re1");
-			r1.addReactant(new Reactant(sa5));
-			r1.addProduct(new Product(sa7));
-			result.addReaction(r1);
-
-			Reaction r2 = new TransportReaction("re2");
-			r2.addReactant(new Reactant(sa6));
-			r2.addProduct(new Product(ca3));
-			result.addReaction(r2);
-
-			Reaction r3 = new TransportReaction("re3");
-			r3.addReactant(new Reactant(sa7));
-			r3.addProduct(new Product(ca4));
-			result.addReaction(r3);
-			return result;
-		}
-
-		@Override
-		public InputStream exportModelToInputStream(Model model) throws InconsistentModelException {
-			// TODO Auto-generated method stub
-			return null;
-		}
-
-		@Override
-		public File exportModelToFile(Model model, String filePath) throws InconsistentModelException {
-			// TODO Auto-generated method stub
-			return null;
-		}
-
-		@Override
-		public String getCommonName() {
-			// TODO Auto-generated method stub
-			return null;
-		}
-
-		@Override
-		public MimeType getMimeType() {
-			// TODO Auto-generated method stub
-			return null;
-		}
-
-		@Override
-		public String getFileExtension() {
-			// TODO Auto-generated method stub
-			return null;
-		}
-
-	}
-
-	@Before
-	public void setUp() throws Exception {
-	}
-
-	@After
-	public void tearDown() throws Exception {
-	}
-
-	@Test
-	public void testConstructor() throws Exception {
-		try {
-			new ComplexZipConverter(AbstractConverter.class);
-			fail("Exception expected");
-
-		} catch (InvalidClassException e) {
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-
-	}
-
-	@Test
-	public void testConstructor2() throws Exception {
-		try {
-			new ComplexZipConverter(InterfaceConverter.class);
-			fail("Exception expected");
-
-		} catch (InvalidClassException e) {
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-
-	}
-
-	@Test
-	public void testConstructor3() throws Exception {
-		try {
-			new ComplexZipConverter(MockConverter.class);
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-
-	}
-
-	@Test
-	public void testParamsOk() throws Exception {
-		try {
-			ComplexZipConverter converter = new ComplexZipConverter(MockConverter.class);
-			ComplexZipConverterParams params = new ComplexZipConverterParams();
-			params.zipFile(new ZipFile("testFiles/complex_model.zip"));
-			params.entry(new ModelZipEntryFile("main.xml", "main", true, false, null));
-			params.entry(new ModelZipEntryFile("s1.xml", "s1", false, false, SubmodelType.DOWNSTREAM_TARGETS));
-			params.entry(new ModelZipEntryFile("s2.xml", "s2", false, false, SubmodelType.PATHWAY));
-			params.entry(new ModelZipEntryFile("s3.xml", "s3", false, false, SubmodelType.UNKNOWN));
-			params.entry(new ModelZipEntryFile("mapping.xml", null, false, true, null));
-			Model model = converter.createModel(params);
-			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());
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-
-	}
-
-	@Test
-	public void testChangeModelZipEntry() throws Exception {
-		try {
-			ComplexZipConverter converter = new ComplexZipConverter(MockConverter.class);
-			ComplexZipConverterParams params = new ComplexZipConverterParams();
-			params.zipFile(new ZipFile("testFiles/complex_model.zip"));
-			params.entry(new ModelZipEntryFile("main.xml", "main", true, false, null));
-			params.entry(new ModelZipEntryFile("s1.xml", "s12", false, false, SubmodelType.DOWNSTREAM_TARGETS));
-			params.entry(new ModelZipEntryFile("s2.xml", "s2", false, false, SubmodelType.PATHWAY));
-			params.entry(new ModelZipEntryFile("s3.xml", "s3", false, false, SubmodelType.UNKNOWN));
-			params.entry(new ModelZipEntryFile("mapping.xml", null, false, true, null));
-			Model model = converter.createModel(params);
-			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("s12")) {
-					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());
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-
-	}
-
-	@Test
-	public void testParamsMissing() throws Exception {
-		try {
-			ComplexZipConverter converter = new ComplexZipConverter(MockConverter.class);
-			ComplexZipConverterParams params = new ComplexZipConverterParams();
-			params.zipFile(new ZipFile("testFiles/complex_model.zip"));
-			params.entry(new ModelZipEntryFile("main.xml", "main", true, false, null));
-			params.entry(new ModelZipEntryFile("s1.xml", "s1", false, false, SubmodelType.DOWNSTREAM_TARGETS));
-			params.entry(new ModelZipEntryFile("s3.xml", "s3", false, false, SubmodelType.UNKNOWN));
-			params.entry(new ModelZipEntryFile("mapping.xml", null, false, true, null));
-			try {
-				converter.createModel(params);
-				fail("Exception expected");
-			} catch (InvalidArgumentException e) {
-
-			}
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-
-	}
-
-	@Test
-	public void testParamsInvalid1() throws Exception {
-		try {
-			// two mains
-			ComplexZipConverter converter = new ComplexZipConverter(MockConverter.class);
-			ComplexZipConverterParams params = new ComplexZipConverterParams();
-			params.zipFile(new ZipFile("testFiles/complex_model.zip"));
-			params.entry(new ModelZipEntryFile("main.xml", "main", true, false, null));
-			params.entry(new ModelZipEntryFile("s1.xml", "s1", true, false, SubmodelType.DOWNSTREAM_TARGETS));
-			params.entry(new ModelZipEntryFile("s2.xml", "s2", false, false, SubmodelType.PATHWAY));
-			params.entry(new ModelZipEntryFile("s3.xml", "s3", false, false, SubmodelType.UNKNOWN));
-			params.entry(new ModelZipEntryFile("mapping.xml", null, false, true, null));
-			try {
-				converter.createModel(params);
-				fail("Exception expected");
-			} catch (InvalidArgumentException e) {
-
-			}
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-
-	}
-
-	@Test
-	public void testParamsInvalid2() throws Exception {
-		try {
-			// zero mains
-			ComplexZipConverter converter = new ComplexZipConverter(MockConverter.class);
-			ComplexZipConverterParams params = new ComplexZipConverterParams();
-			params.zipFile(new ZipFile("testFiles/complex_model.zip"));
-			params.entry(new ModelZipEntryFile("main.xml", "main", false, false, null));
-			params.entry(new ModelZipEntryFile("s1.xml", "s1", false, false, SubmodelType.DOWNSTREAM_TARGETS));
-			params.entry(new ModelZipEntryFile("s2.xml", "s2", false, false, SubmodelType.PATHWAY));
-			params.entry(new ModelZipEntryFile("s3.xml", "s3", false, false, SubmodelType.UNKNOWN));
-			params.entry(new ModelZipEntryFile("mapping.xml", null, false, true, null));
-			try {
-				converter.createModel(params);
-				fail("Exception expected");
-			} catch (InvalidArgumentException e) {
-
-			}
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-
-	}
-
-	@Test
-	public void testParamsInvalid3() throws Exception {
-		try {
-			// two mappings
-			ComplexZipConverter converter = new ComplexZipConverter(MockConverter.class);
-			ComplexZipConverterParams params = new ComplexZipConverterParams();
-			params.zipFile(new ZipFile("testFiles/complex_model.zip"));
-			params.entry(new ModelZipEntryFile("main.xml", "main", true, false, null));
-			params.entry(new ModelZipEntryFile("s1.xml", "s1", false, true, SubmodelType.DOWNSTREAM_TARGETS));
-			params.entry(new ModelZipEntryFile("s2.xml", "s2", false, false, SubmodelType.PATHWAY));
-			params.entry(new ModelZipEntryFile("s3.xml", "s3", false, false, SubmodelType.UNKNOWN));
-			params.entry(new ModelZipEntryFile("mapping.xml", null, false, true, null));
-			try {
-				converter.createModel(params);
-				fail("Exception expected");
-			} catch (InvalidArgumentException e) {
-
-			}
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-
-	}
-
-	@Test
-	public void testParamsMissingMapping() throws Exception {
-		try {
-			// zero mappings (should be ok)
-			ComplexZipConverter converter = new ComplexZipConverter(MockConverter.class);
-			ComplexZipConverterParams params = new ComplexZipConverterParams();
-			params.zipFile(new ZipFile("testFiles/complex_model.zip"));
-			params.entry(new ModelZipEntryFile("main.xml", "main", true, false, null));
-			params.entry(new ModelZipEntryFile("s1.xml", "s1", false, false, SubmodelType.DOWNSTREAM_TARGETS));
-			params.entry(new ModelZipEntryFile("s2.xml", "s2", false, false, SubmodelType.PATHWAY));
-			params.entry(new ModelZipEntryFile("s3.xml", "s3", false, false, SubmodelType.UNKNOWN));
-			params.entry(new ModelZipEntryFile("mapping.xml", "", false, false, null));
-			Model model = converter.createModel(params);
-
-			assertNotNull(model);
-
-			assertEquals(4, model.getSubmodelConnections().size());
-
-			for (ModelSubmodelConnection submodel : model.getSubmodelConnections()) {
-				if (submodel.getName().equals("s1")) {
-					assertEquals(SubmodelType.DOWNSTREAM_TARGETS, submodel.getType());
-				} else if (submodel.getName().equals("s2")) {
-					assertEquals(SubmodelType.PATHWAY, submodel.getType());
-				} else if (submodel.getName().equals("s3")) {
-					assertEquals(SubmodelType.UNKNOWN, submodel.getType());
-				} else if (submodel.getName().equals("mapping")) {
-					assertEquals(SubmodelType.UNKNOWN, submodel.getType());
-				}
-			}
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-
-	}
-
-	@Test
-	public void testTooManyParams() throws Exception {
-		try {
-			// zero mappings (should be ok)
-			ComplexZipConverter converter = new ComplexZipConverter(MockConverter.class);
-			ComplexZipConverterParams params = new ComplexZipConverterParams();
-			params.zipFile(new ZipFile("testFiles/complex_model.zip"));
-			params.entry(new ModelZipEntryFile("main.xml", "main", true, false, null));
-			params.entry(new ModelZipEntryFile("s1.xml", "s1", false, false, SubmodelType.DOWNSTREAM_TARGETS));
-			params.entry(new ModelZipEntryFile("s2.xml", "s2", false, false, SubmodelType.PATHWAY));
-			params.entry(new ModelZipEntryFile("s3.xml", "s3", false, false, SubmodelType.UNKNOWN));
-			params.entry(new ModelZipEntryFile("mapping.xml", "", false, false, null));
-			params.entry(new ModelZipEntryFile("blabla.xml", "s3", false, false, SubmodelType.UNKNOWN));
-			try {
-				converter.createModel(params);
-				fail("Exception expected");
-			} catch (InvalidArgumentException e) {
-
-			}
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testInvalidMappingFile() throws Exception {
-		try {
-			// zero mappings (should be ok)
-			ComplexZipConverter converter = new ComplexZipConverter(MockConverter.class);
-			ComplexZipConverterParams params = new ComplexZipConverterParams();
-			params.zipFile(new ZipFile("testFiles/invalid_mapping.zip"));
-			params.entry(new ModelZipEntryFile("main.xml", "main", true, false, null));
-			params.entry(new ModelZipEntryFile("mapping.xml", null, false, true, null));
-			try {
-				converter.createModel(params);
-				fail("Exception expected");
-			} catch (InvalidArgumentException e) {
-
-			}
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
+  @SuppressWarnings("unused")
+  private static Logger logger = Logger.getLogger(ComplexZipConverterTest.class);
+
+  private abstract class AbstractConverter implements IConverter {
+
+  }
+
+  private interface InterfaceConverter extends IConverter {
+
+  }
+
+  public static class MockConverter implements IConverter {
+
+    @Override
+    public Model createModel(ConverterParams params) {
+      Model result = new ModelFullIndexed(null);
+
+      Species sa1 = new GenericProtein("sa1");
+      result.addElement(sa1);
+
+      Species sa2 = new GenericProtein("sa2");
+      result.addElement(sa2);
+
+      Species sa3 = new GenericProtein("sa3");
+      result.addElement(sa3);
+
+      Species sa4 = new Phenotype("sa4");
+      result.addElement(sa4);
+
+      Complex ca1 = new Complex("ca1");
+      ca1.setName("main");
+      result.addElement(ca1);
+      Species sa5 = new GenericProtein("sa5");
+      sa5.setName("sa1");
+      result.addElement(sa5);
+      ca1.addSpecies(sa5);
+      Species sa6 = new Phenotype("sa6");
+      sa6.setName("sa4");
+      result.addElement(sa6);
+      ca1.addSpecies(sa6);
+
+      Complex ca2 = new Complex("ca2");
+      ca2.setName("s1");
+      result.addElement(ca2);
+      Species sa7 = new GenericProtein("sa7");
+      sa7.setName("sa1");
+      result.addElement(sa7);
+      ca2.addSpecies(sa7);
+
+      Complex ca3 = new Complex("cs3");
+      ca3.setName("s2");
+      result.addElement(ca3);
+
+      Complex ca4 = new Complex("cs4");
+      ca4.setName("s3");
+      result.addElement(ca4);
+
+      Reaction r1 = new TransportReaction("re1");
+      r1.addReactant(new Reactant(sa5));
+      r1.addProduct(new Product(sa7));
+      result.addReaction(r1);
+
+      Reaction r2 = new TransportReaction("re2");
+      r2.addReactant(new Reactant(sa6));
+      r2.addProduct(new Product(ca3));
+      result.addReaction(r2);
+
+      Reaction r3 = new TransportReaction("re3");
+      r3.addReactant(new Reactant(sa7));
+      r3.addProduct(new Product(ca4));
+      result.addReaction(r3);
+      return result;
+    }
+
+    @Override
+    public InputStream exportModelToInputStream(Model model) throws InconsistentModelException {
+      // TODO Auto-generated method stub
+      return null;
+    }
+
+    @Override
+    public File exportModelToFile(Model model, String filePath) throws InconsistentModelException {
+      // TODO Auto-generated method stub
+      return null;
+    }
+
+    @Override
+    public String getCommonName() {
+      // TODO Auto-generated method stub
+      return null;
+    }
+
+    @Override
+    public MimeType getMimeType() {
+      // TODO Auto-generated method stub
+      return null;
+    }
+
+    @Override
+    public String getFileExtension() {
+      // TODO Auto-generated method stub
+      return null;
+    }
+
+  }
+
+  @Before
+  public void setUp() throws Exception {
+  }
+
+  @After
+  public void tearDown() throws Exception {
+  }
+
+  @Test
+  public void testConstructor() throws Exception {
+    try {
+      new ComplexZipConverter(AbstractConverter.class);
+      fail("Exception expected");
+
+    } catch (InvalidClassException e) {
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+
+  }
+
+  @Test
+  public void testConstructor2() throws Exception {
+    try {
+      new ComplexZipConverter(InterfaceConverter.class);
+      fail("Exception expected");
+
+    } catch (InvalidClassException e) {
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+
+  }
+
+  @Test
+  public void testConstructor3() throws Exception {
+    try {
+      new ComplexZipConverter(MockConverter.class);
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+
+  }
+
+  @Test
+  public void testParamsOk() throws Exception {
+    try {
+      ComplexZipConverter converter = new ComplexZipConverter(MockConverter.class);
+      ComplexZipConverterParams params = new ComplexZipConverterParams();
+      params.zipFile(new ZipFile("testFiles/complex_model.zip"));
+      params.entry(new ModelZipEntryFile("main.xml", "main", true, false, null));
+      params.entry(new ModelZipEntryFile("s1.xml", "s1", false, false, SubmodelType.DOWNSTREAM_TARGETS));
+      params.entry(new ModelZipEntryFile("s2.xml", "s2", false, false, SubmodelType.PATHWAY));
+      params.entry(new ModelZipEntryFile("s3.xml", "s3", false, false, SubmodelType.UNKNOWN));
+      params.entry(new ModelZipEntryFile("mapping.xml", null, false, true, null));
+      Model model = converter.createModel(params);
+      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());
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+
+  }
+
+  @Test
+  public void testChangeModelZipEntry() throws Exception {
+    try {
+      ComplexZipConverter converter = new ComplexZipConverter(MockConverter.class);
+      ComplexZipConverterParams params = new ComplexZipConverterParams();
+      params.zipFile(new ZipFile("testFiles/complex_model.zip"));
+      params.entry(new ModelZipEntryFile("main.xml", "main", true, false, null));
+      params.entry(new ModelZipEntryFile("s1.xml", "s12", false, false, SubmodelType.DOWNSTREAM_TARGETS));
+      params.entry(new ModelZipEntryFile("s2.xml", "s2", false, false, SubmodelType.PATHWAY));
+      params.entry(new ModelZipEntryFile("s3.xml", "s3", false, false, SubmodelType.UNKNOWN));
+      params.entry(new ModelZipEntryFile("mapping.xml", null, false, true, null));
+      Model model = converter.createModel(params);
+      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("s12")) {
+          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());
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+
+  }
+
+  @Test
+  public void testParamsMissing() throws Exception {
+    try {
+      ComplexZipConverter converter = new ComplexZipConverter(MockConverter.class);
+      ComplexZipConverterParams params = new ComplexZipConverterParams();
+      params.zipFile(new ZipFile("testFiles/complex_model.zip"));
+      params.entry(new ModelZipEntryFile("main.xml", "main", true, false, null));
+      params.entry(new ModelZipEntryFile("s1.xml", "s1", false, false, SubmodelType.DOWNSTREAM_TARGETS));
+      params.entry(new ModelZipEntryFile("s3.xml", "s3", false, false, SubmodelType.UNKNOWN));
+      params.entry(new ModelZipEntryFile("mapping.xml", null, false, true, null));
+      try {
+        converter.createModel(params);
+        fail("Exception expected");
+      } catch (InvalidArgumentException e) {
+
+      }
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+
+  }
+
+  @Test
+  public void testParamsInvalid1() throws Exception {
+    try {
+      // two mains
+      ComplexZipConverter converter = new ComplexZipConverter(MockConverter.class);
+      ComplexZipConverterParams params = new ComplexZipConverterParams();
+      params.zipFile(new ZipFile("testFiles/complex_model.zip"));
+      params.entry(new ModelZipEntryFile("main.xml", "main", true, false, null));
+      params.entry(new ModelZipEntryFile("s1.xml", "s1", true, false, SubmodelType.DOWNSTREAM_TARGETS));
+      params.entry(new ModelZipEntryFile("s2.xml", "s2", false, false, SubmodelType.PATHWAY));
+      params.entry(new ModelZipEntryFile("s3.xml", "s3", false, false, SubmodelType.UNKNOWN));
+      params.entry(new ModelZipEntryFile("mapping.xml", null, false, true, null));
+      try {
+        converter.createModel(params);
+        fail("Exception expected");
+      } catch (InvalidArgumentException e) {
+
+      }
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+
+  }
+
+  @Test
+  public void testParamsInvalid2() throws Exception {
+    try {
+      // zero mains
+      ComplexZipConverter converter = new ComplexZipConverter(MockConverter.class);
+      ComplexZipConverterParams params = new ComplexZipConverterParams();
+      params.zipFile(new ZipFile("testFiles/complex_model.zip"));
+      params.entry(new ModelZipEntryFile("main.xml", "main", false, false, null));
+      params.entry(new ModelZipEntryFile("s1.xml", "s1", false, false, SubmodelType.DOWNSTREAM_TARGETS));
+      params.entry(new ModelZipEntryFile("s2.xml", "s2", false, false, SubmodelType.PATHWAY));
+      params.entry(new ModelZipEntryFile("s3.xml", "s3", false, false, SubmodelType.UNKNOWN));
+      params.entry(new ModelZipEntryFile("mapping.xml", null, false, true, null));
+      try {
+        converter.createModel(params);
+        fail("Exception expected");
+      } catch (InvalidArgumentException e) {
+
+      }
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+
+  }
+
+  @Test
+  public void testParamsInvalid3() throws Exception {
+    try {
+      // two mappings
+      ComplexZipConverter converter = new ComplexZipConverter(MockConverter.class);
+      ComplexZipConverterParams params = new ComplexZipConverterParams();
+      params.zipFile(new ZipFile("testFiles/complex_model.zip"));
+      params.entry(new ModelZipEntryFile("main.xml", "main", true, false, null));
+      params.entry(new ModelZipEntryFile("s1.xml", "s1", false, true, SubmodelType.DOWNSTREAM_TARGETS));
+      params.entry(new ModelZipEntryFile("s2.xml", "s2", false, false, SubmodelType.PATHWAY));
+      params.entry(new ModelZipEntryFile("s3.xml", "s3", false, false, SubmodelType.UNKNOWN));
+      params.entry(new ModelZipEntryFile("mapping.xml", null, false, true, null));
+      try {
+        converter.createModel(params);
+        fail("Exception expected");
+      } catch (InvalidArgumentException e) {
+
+      }
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+
+  }
+
+  @Test
+  public void testParamsMissingMapping() throws Exception {
+    try {
+      // zero mappings (should be ok)
+      ComplexZipConverter converter = new ComplexZipConverter(MockConverter.class);
+      ComplexZipConverterParams params = new ComplexZipConverterParams();
+      params.zipFile(new ZipFile("testFiles/complex_model.zip"));
+      params.entry(new ModelZipEntryFile("main.xml", "main", true, false, null));
+      params.entry(new ModelZipEntryFile("s1.xml", "s1", false, false, SubmodelType.DOWNSTREAM_TARGETS));
+      params.entry(new ModelZipEntryFile("s2.xml", "s2", false, false, SubmodelType.PATHWAY));
+      params.entry(new ModelZipEntryFile("s3.xml", "s3", false, false, SubmodelType.UNKNOWN));
+      params.entry(new ModelZipEntryFile("mapping.xml", "", false, false, null));
+      Model model = converter.createModel(params);
+
+      assertNotNull(model);
+
+      assertEquals(4, model.getSubmodelConnections().size());
+
+      for (ModelSubmodelConnection submodel : model.getSubmodelConnections()) {
+        if (submodel.getName().equals("s1")) {
+          assertEquals(SubmodelType.DOWNSTREAM_TARGETS, submodel.getType());
+        } else if (submodel.getName().equals("s2")) {
+          assertEquals(SubmodelType.PATHWAY, submodel.getType());
+        } else if (submodel.getName().equals("s3")) {
+          assertEquals(SubmodelType.UNKNOWN, submodel.getType());
+        } else if (submodel.getName().equals("mapping")) {
+          assertEquals(SubmodelType.UNKNOWN, submodel.getType());
+        }
+      }
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+
+  }
+
+  @Test
+  public void testTooManyParams() throws Exception {
+    try {
+      // zero mappings (should be ok)
+      ComplexZipConverter converter = new ComplexZipConverter(MockConverter.class);
+      ComplexZipConverterParams params = new ComplexZipConverterParams();
+      params.zipFile(new ZipFile("testFiles/complex_model.zip"));
+      params.entry(new ModelZipEntryFile("main.xml", "main", true, false, null));
+      params.entry(new ModelZipEntryFile("s1.xml", "s1", false, false, SubmodelType.DOWNSTREAM_TARGETS));
+      params.entry(new ModelZipEntryFile("s2.xml", "s2", false, false, SubmodelType.PATHWAY));
+      params.entry(new ModelZipEntryFile("s3.xml", "s3", false, false, SubmodelType.UNKNOWN));
+      params.entry(new ModelZipEntryFile("mapping.xml", "", false, false, null));
+      params.entry(new ModelZipEntryFile("blabla.xml", "s3", false, false, SubmodelType.UNKNOWN));
+      try {
+        converter.createModel(params);
+        fail("Exception expected");
+      } catch (InvalidArgumentException e) {
+
+      }
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testInvalidMappingFile() throws Exception {
+    try {
+      // zero mappings (should be ok)
+      ComplexZipConverter converter = new ComplexZipConverter(MockConverter.class);
+      ComplexZipConverterParams params = new ComplexZipConverterParams();
+      params.zipFile(new ZipFile("testFiles/invalid_mapping.zip"));
+      params.entry(new ModelZipEntryFile("main.xml", "main", true, false, null));
+      params.entry(new ModelZipEntryFile("mapping.xml", null, false, true, null));
+      try {
+        converter.createModel(params);
+        fail("Exception expected");
+      } catch (InvalidArgumentException e) {
+
+      }
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testIsIgnoredFileForMac() throws Exception {
+    try {
+      ComplexZipConverter converter = new ComplexZipConverter(MockConverter.class);
+      assertTrue(converter.isIgnoredFile("__MACOSX/.desc"));
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testIsIgnoredFileForOldMacEntries() throws Exception {
+    try {
+      ComplexZipConverter converter = new ComplexZipConverter(MockConverter.class);
+      assertTrue(converter.isIgnoredFile(".DS_Store/.desc"));
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testIsIgnoredFileForValidFiles() throws Exception {
+    try {
+      ComplexZipConverter converter = new ComplexZipConverter(MockConverter.class);
+      assertFalse(converter.isIgnoredFile("mapping.xml"));
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
 
 }
diff --git a/frontend-js/src/main/js/gui/admin/AddProjectDialog.js b/frontend-js/src/main/js/gui/admin/AddProjectDialog.js
index 64679faba0f0d005725549c27637b2b8674edd21..d9eb87fa1d9a5df2e2082ba39e432538396b986d 100644
--- a/frontend-js/src/main/js/gui/admin/AddProjectDialog.js
+++ b/frontend-js/src/main/js/gui/admin/AddProjectDialog.js
@@ -159,7 +159,7 @@ AddProjectDialog.prototype.createGeneralTabContent = function () {
     name: "project-file"
   });
   fileInput.addEventListener("change", function () {
-    return self.callListeners("onFileUpload", fileInput.files[0]);
+    return self.callListeners("onFileUpload", fileInput.files[0]).then(null, GuiConnector.alert);
   }, false);
   self.addListener("onFileUpload", function (e) {
     var file = e.arg;
@@ -936,6 +936,8 @@ AddProjectDialog.prototype.createZipEntry = function (jsZipEntry, zipObject) {
         data.description = "";
       }
     });
+  } else if (this.isIgnoredZipEntry(filename)) {
+    type = undefined;
   } else if (filename.indexOf("\\") === -1 && filename.indexOf("/") === -1) {
     type = "MAP";
     data.root = true;
@@ -972,7 +974,11 @@ AddProjectDialog.prototype.createZipEntry = function (jsZipEntry, zipObject) {
   }
 
   return processingPromise.then(function () {
-    return new ZipEntry({filename: filename, type: type, data: data});
+    if (type !== undefined) {
+      return new ZipEntry({filename: filename, type: type, data: data});
+    } else {
+      return null;
+    }
   });
 };
 
@@ -986,6 +992,15 @@ AddProjectDialog.prototype.setZipEntries = function (entries) {
 
 };
 
+AddProjectDialog.prototype.isIgnoredZipEntry = function (filename) {
+  var lowercaseString = filename.toLowerCase();
+  if (lowercaseString.startsWith("__macosx") || lowercaseString.startsWith(".ds_store")) {
+    return true;
+  } else {
+    return false;
+  }
+};
+
 AddProjectDialog.prototype.getEntryByFilename = function (filename) {
   var self = this;
   var entries = self.getZipEntries();
diff --git a/frontend-js/src/test/js/gui/admin/AddProjectDialog-test.js b/frontend-js/src/test/js/gui/admin/AddProjectDialog-test.js
index 97133089ed9a036b5aff78fde3454033eca57107..f76d54a2d73f8d2c9ffd53312fc935a7d159137d 100644
--- a/frontend-js/src/test/js/gui/admin/AddProjectDialog-test.js
+++ b/frontend-js/src/test/js/gui/admin/AddProjectDialog-test.js
@@ -172,7 +172,7 @@ describe('AddProjectDialog', function () {
         dialog.setProjectId("(invalid id)");
         return dialog.checkValidity().then(function () {
           assert.notOk("Expected validity to reject");
-        }).catch(function(error){
+        }).catch(function (error) {
           assert.ok(error instanceof ValidationError);
         });
       }).then().finally(function () {
@@ -198,4 +198,38 @@ describe('AddProjectDialog', function () {
     });
   });
 
+  describe('isIgnoredZipEntry', function () {
+    it('valid entry', function () {
+      var dialog = new AddProjectDialog({
+        element: testDiv,
+        customMap: null
+      });
+
+      assert.notOk(dialog.isIgnoredZipEntry("images/a.png"));
+      assert.notOk(dialog.isIgnoredZipEntry("main.xml"));
+      return dialog.destroy();
+    });
+    it('invalid MAC OS entry', function () {
+      var dialog = new AddProjectDialog({
+        element: testDiv,
+        customMap: null
+      });
+
+      // noinspection SpellCheckingInspection
+      assert.ok(dialog.isIgnoredZipEntry("__MACOSX/.desc"));
+      assert.ok(dialog.isIgnoredZipEntry("__macosx/.desc"));
+      return dialog.destroy();
+    });
+    it('invalid old MAC OS entry', function () {
+      var dialog = new AddProjectDialog({
+        element: testDiv,
+        customMap: null
+      });
+
+      assert.ok(dialog.isIgnoredZipEntry(".DS_Store/.desc"));
+      assert.ok(dialog.isIgnoredZipEntry(".ds_store/.desc"));
+      return dialog.destroy();
+    });
+  });
+
 });
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/model/Model.java b/model/src/main/java/lcsb/mapviewer/model/map/model/Model.java
index 8a2bb71c2e8b3afdb4e8146548fa511a5fe72864..1fd990051d085ab60b4805162da30871cabcecac 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/model/Model.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/model/Model.java
@@ -616,4 +616,6 @@ public interface Model {
   void addFunction(SbmlFunction sbmlFunction);
 
   SbmlArgument getFunctionById(String id);
+
+  void removeReactions(Collection<Reaction> reactions);
 }
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/model/ModelFullIndexed.java b/model/src/main/java/lcsb/mapviewer/model/map/model/ModelFullIndexed.java
index 4d2d833420676c82b172552749a3ab298e50c014..893134e99c718bcccc81398d58152bf607d86a64 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/model/ModelFullIndexed.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/model/ModelFullIndexed.java
@@ -734,4 +734,13 @@ public class ModelFullIndexed implements Model {
     }
     return null;
   }
+
+  @Override
+  public void removeReactions(Collection<Reaction> reactions) {
+    Set<Reaction> reactionsToRemove = new HashSet<>();
+    reactionsToRemove.addAll(reactions);
+    for (Reaction reaction : reactionsToRemove) {
+      removeReaction(reaction);
+    }
+  }
 }
diff --git a/service/src/test/java/lcsb/mapviewer/services/impl/ExporterServiceTest.java b/service/src/test/java/lcsb/mapviewer/services/impl/ExporterServiceTest.java
index ad2bd21b548a27e2cf1ea9f15fa5b55b87ac04b4..e65556f1044b7cf57849214923809461a2670647 100644
--- a/service/src/test/java/lcsb/mapviewer/services/impl/ExporterServiceTest.java
+++ b/service/src/test/java/lcsb/mapviewer/services/impl/ExporterServiceTest.java
@@ -35,495 +35,506 @@ import lcsb.mapviewer.services.utils.data.ExportFileType;
 import lcsb.mapviewer.services.view.PubmedAnnotatedElementsView;
 
 public class ExporterServiceTest extends ServiceTestFunctions {
-	Logger					 logger	= Logger.getLogger(ExporterServiceTest.class);
-	@Autowired
-	IExporterService exporter2;
-
-	ExporterService	 exporter;
-
-	@Before
-	public void setUp() throws Exception {
-		exporter = (ExporterService) exporter2;
-	}
-
-	@After
-	public void tearDown() throws Exception {
-	}
-
-	@Test
-	public void testGetExportSpeciesStringForTabSeparatedFile() throws Exception {
-		try {
-			Model model = getModelForFile("testFiles/export_with_artifitial_comp.xml", false);
-			ExportColumn columns[] = { ExportColumn.NAME, ExportColumn.ID, ExportColumn.COMPONENT_NAME, ExportColumn.COMPARTMENT_NAME, ExportColumn.TYPE };
-
-			ExporterParameters params = new IExporterService.ExporterParameters().model(model).column(columns).fileType(ExportFileType.TAB_SEPARATED);
-
-			// full export (all elements)
-			String string = exporter.getExportSpeciesString(params);
-			String lines[] = string.split("\n");
-			assertTrue("Not enough elements in the result file", lines.length > 1);
-
-			String response = lines[0];
-			String textColumns[] = response.split("\t");
-			assertEquals(5, textColumns.length);
-
-			// only proteins for self-made modules
-			new CreateHierarchyCommand(model, 8, 80).execute();
-			string = exporter.getExportSpeciesString(params.type(GenericProtein.class));
-			lines = string.split("\n");
-			assertTrue(lines.length > 1);
-
-			boolean differenceBetweenComponentCompartmnet = false;
-			int lineCount = 0;
-			for (String string2 : lines) {
-				if (lineCount == 0) {
-					textColumns = string2.split("\t");
-					assertEquals(ExportColumn.TYPE.getTitle(), textColumns[4]);
-				} else {
-					textColumns = string2.split("\t");
-					assertEquals(GenericProtein.class.getSimpleName(), textColumns[4]);
-					if (!textColumns[2].equalsIgnoreCase(textColumns[3])) {
-						differenceBetweenComponentCompartmnet = true;
-					}
-				}
-				lineCount++;
-			}
-			assertTrue(differenceBetweenComponentCompartmnet);
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testDuplicatesInGetExportSpeciesString() throws Exception {
-		try {
-			Model model = getModelForFile("testFiles/export_duplicate_elements.xml", false);
-			ExportColumn columns[] = { ExportColumn.NAME, ExportColumn.COMPONENT_NAME, ExportColumn.TYPE };
-
-			ExporterParameters params = new IExporterService.ExporterParameters().model(model).column(columns).fileType(ExportFileType.TAB_SEPARATED);
-
-			// full export (all elements)
-			String string = exporter.getExportSpeciesString(params);
-
-			String lines[] = string.split("\n");
-			Set<String> uniqueNames = new HashSet<String>();
-			for (String string2 : lines) {
-				uniqueNames.add(string2);
-			}
-			assertEquals(uniqueNames.size(), lines.length);
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testGetExportStringForOneSpecies_Complex() {
-		try {
-			Model model = getModelForFile("testFiles/export/hsp70.xml", true);
-
-			Species alias = (Species) model.getElementByElementId("csa1");
-			ExportColumn columns[] = { ExportColumn.NAME };
-
-			ExporterParameters params = new IExporterService.ExporterParameters().model(model).//
-					column(columns).//
-					complexElementsName(false).//
-					fileType(ExportFileType.TAB_SEPARATED);
-
-			List<String> elements = exporter.getExportStringForOneSpecies(alias, params);
-			assertTrue(elements.contains("HSP70:chaperon"));
-
-			// now the results are concatenated children
-			params.complexElementsName(true);
-
-			elements = exporter.getExportStringForOneSpecies(alias, params);
-			assertTrue(elements.size() > 0);
-			String string = elements.get(0);
-			assertFalse(string.equals("HSP70:chaperon"));
-			assertTrue(string.contains("HSP70"));
-			assertTrue(string.contains("STUB1"));
-			assertTrue(string.contains("DNAJB2"));
-			assertTrue(string.contains("BAG1"));
-
-			// and now check complexes with mix of proteins and molecules
-			alias = (Species) model.getElementByElementId("csa3");
-
-			elements = exporter.getExportStringForOneSpecies(alias, params);
-			assertTrue(elements.size() > 0);
-			string = elements.get(0);
-			assertTrue(string.contains("UBA1"));
-			assertTrue(string.contains("UBA6"));
-			assertTrue(string.contains("AMP"));
-
-			elements = exporter.getExportStringForOneSpecies(alias, params.type(Protein.class));
-			assertTrue(elements.size() > 0);
-			string = elements.get(0);
-			assertTrue(string.contains("UBA1"));
-			assertTrue(string.contains("UBA6"));
-			assertFalse(string.contains("AMP"));
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			fail("Exception occured");
-		}
-	}
-
-	@Test
-	public void testGetExportStringForOneReaction() throws Exception {
-		try {
-			Model model = getModelForFile("testFiles/export/reaction.xml", false);
-			Set<Compartment> aliases = new HashSet<>();
-			for (Compartment alias : model.getCompartments()) {
-				if (alias.getName().equalsIgnoreCase("Dopamine loaded synaptic vesicle"))
-					aliases.add(alias);
-			}
-
-			Reaction reaction = model.getReactionByReactionId("re2");
-
-			ExporterParameters params = new IExporterService.ExporterParameters().model(model).//
-					fileType(ExportFileType.SIF).//
-					type(Protein.class).//
-					type(Complex.class).//
-					fileType(ExportFileType.SIF).//
-					complexElementsName(false).//
-					excluded(aliases);
-
-			String string = exporter.getExportSingleInteractionString(reaction, params).get(0);
-			assertNotNull(string);
-			assertTrue(string.contains("Calcium channel:RIMBP:RIM:MUNC13:RAB"));
-			assertTrue(string.contains("CSP:Hsc70:SGT"));
-			assertTrue(string.contains("SNCA"));
-			assertTrue(string.contains("trans-SNARE complex"));
-			assertFalse(string.contains("VAMP2"));
-
-			params = new IExporterService.ExporterParameters().model(model).fileType(ExportFileType.SIF).type(Complex.class).type(Protein.class);
-			string = exporter.getExportSingleInteractionString(reaction, params).get(0);
-			assertTrue(string.contains("VAMP2"));
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-
-	}
-
-	@Test
-	public void testGetExportStringForOneReactionInGeneral() {
-		try {
-			Model model = getModelForFile("testFiles/export/reaction.xml", true);
-			Reaction reaction = model.getReactionByReactionId("re2");
-			ExporterParameters params = new IExporterService.ExporterParameters().model(model).//
-					fileType(ExportFileType.SIF).//
-					complexElementsName(false).//
-					type(Complex.class).type(Protein.class);
-			String string = exporter.getExportSingleInteractionString(reaction, params).get(0);
-			assertNotNull(string);
-			assertTrue(string.contains("Calcium channel:RIMBP:RIM:MUNC13:RAB"));
-			assertTrue(string.contains("CSP:Hsc70:SGT"));
-			assertTrue(string.contains("SNCA"));
-			assertTrue(string.contains("trans-SNARE complex"));
-			assertTrue(string.contains("SNAP25"));
-			assertFalse(string.contains("RAB3A"));
-
-			params.complexElementsName(true);
-			string = exporter.getExportSingleInteractionString(reaction, params).get(0);
-			assertFalse(string.contains("trans-SNARE complex"));
-			assertTrue(string.contains("RAB3A"));
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			fail("Exception occured");
-		}
-
-	}
-
-	@Test
-	public void testGetExportStringForOneReactionInGeneralWithOnlyOneElement() throws Exception {
-		try {
-			Model model = getModelForFile("testFiles/export/reaction.xml", false);
-			Reaction reaction = model.getReactionByReactionId("re11");
-			model.getReactions().clear();
-			model.addReaction(reaction);
-			Set<Compartment> aliases = new HashSet<Compartment>();
-			aliases.add((Compartment) model.getElementByElementId("ca1"));
-			ExporterParameters params = new IExporterService.ExporterParameters()
-					.model(model).fileType(ExportFileType.SIF).included("dopamine loaded synaptic vesicle");
-			assertEquals(0, exporter.getExportSingleInteractionString(reaction, params).size());
-
-			params = new IExporterService.ExporterParameters().model(model).fileType(ExportFileType.SIF);
-			assertEquals(1, exporter.getExportSingleInteractionString(reaction, params).size());
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testGetExportSingleInteractionString_text() {
-		try {
-			Model model = getModelForFile("testFiles/export_with_artifitial_comp.xml", false);
-			for (Reaction reaction : model.getReactions()) {
-				String str = exporter
-						.getExportSingleInteractionString(
-								reaction, new IExporterService.ExporterParameters().fileType(ExportFileType.TAB_SEPARATED).type(Species.class))
-						.get(0);
-
-				List<String> strings = new ArrayList<String>();
-				strings.add(ReactionLineData.getByReactionType(reaction.getClass()).getCellDesignerString());
-				strings.add(reaction.getIdReaction());
-				for (ReactionNode node : reaction.getReactionNodes()) {
-					strings.add(node.getElement().getName());
-
-				}
-				for (String string : strings) {
-					assertTrue("Description \"" + str + "\" doesn't contain " + string + ". reactionId=" + reaction.getIdReaction(), str.contains(string));
-				}
-			}
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			fail("Exception occured");
-		}
-	}
-
-	@Test
-	public void testGetExportComponentAndCompartments() throws Exception {
-		try {
-			Model model = getModelForFile("testFiles/export/export_model.xml", false);
-			new CreateHierarchyCommand(model, 7, 80).execute();
-			ExporterParameters params = new IExporterService.ExporterParameters()
-					.model(model).fileType(ExportFileType.TAB_SEPARATED).column(ExportColumn.NAME).column(ExportColumn.COMPONENT_NAME)
-					.column(ExportColumn.COMPARTMENT_NAME);
-
-			List<String> list = exporter.getExportStringForOneSpecies((Species) model.getElementByElementId("sa1"), params);
-			String desc = list.get(0);
-			String compartment = desc.split("\t")[2];
-			assertEquals("c1", compartment);
-			String component = desc.split("\t")[1];
-			assertEquals("Test3", component);
-
-			list = exporter.getExportStringForOneSpecies((Species) model.getElementByElementId("sa2"), params);
-			desc = null;
-			for (String string : list) {
-				if (string.contains("Test 1")) {
-					desc = string;
-				}
-			}
-			compartment = desc.split("\t")[2];
-			assertEquals("c2", compartment);
-			component = desc.split("\t")[1];
-			assertEquals("Test 1", component);
-
-			for (String string : list) {
-				if (string.contains("Test2")) {
-					desc = string;
-				}
-			}
-			compartment = desc.split("\t")[2];
-			assertEquals("c2", compartment);
-			component = desc.split("\t")[1];
-			assertEquals("Test2", component);
-
-			for (String string : list) {
-				if (string.contains("Test3")) {
-					desc = string;
-				}
-			}
-			compartment = desc.split("\t")[2];
-			assertEquals("c2", compartment);
-			component = desc.split("\t")[1];
-			assertEquals("Test3", component);
-
-			list = exporter.getExportStringForOneSpecies((Species) model.getElementByElementId("sa3"), params);
-			boolean ok = false;
-			for (String string : list) {
-				if (string.split("\t")[2].equals("null") && string.split("\t")[1].equals("Test2")) {
-					ok = true;
-				}
-			}
-			assertTrue(ok);
-
-			list = exporter.getExportStringForOneSpecies((Species) model.getElementByElementId("sa4"), params);
-			desc = list.get(0);
-			compartment = desc.split("\t")[2];
-			assertEquals("null", compartment);
-			component = desc.split("\t")[1];
-			assertEquals("Test3", component);
-
-			list = exporter.getExportStringForOneSpecies((Species) model.getElementByElementId("sa5"), params);
-			desc = list.get(0);
-			compartment = desc.split("\t")[2];
-			assertEquals("c3", compartment);
-			component = desc.split("\t")[1];
-			assertEquals("null", component);
-
-			list = exporter.getExportStringForOneSpecies((Species) model.getElementByElementId("sa6"), params);
-			desc = list.get(0);
-			compartment = desc.split("\t")[2];
-			assertEquals("null", compartment);
-			component = desc.split("\t")[1];
-			assertEquals("null", component);
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testGetExportSpeciesStringForTabSeparatedFile2() throws Exception {
-		try {
-			Model model = getModelForFile("testFiles/export_with_artifitial_comp.xml", false);
-			ExportColumn columns[] = { ExportColumn.NAME, ExportColumn.ID, ExportColumn.COMPONENT_NAME, ExportColumn.COMPARTMENT_NAME, ExportColumn.TYPE };
-
-			ExporterParameters params = new IExporterService.ExporterParameters()
-					.model(model).column(columns).fileType(ExportFileType.TAB_SEPARATED).type(Object.class);
-
-			// full export (all elements)
-			String string = exporter.getExportSpeciesString(params);
-			String lines[] = string.split("\n");
-			assertTrue("Not enough elements in the result file", lines.length > 1);
-
-			String response = lines[0];
-			String textColumns[] = response.split("\t");
-			assertEquals(columns.length, textColumns.length);
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testGetExportCompartmentsString() throws Exception {
-		try {
-			Model model = getModelForFile("testFiles/export/export_compartments.xml", false);
-
-			ExporterParameters params = new IExporterService.ExporterParameters().model(model).fileType(ExportFileType.TAB_SEPARATED).type(Object.class);
-
-			// full export (all compartments)
-			String string = exporter.getExportCompartmentsString(params);
-			String lines[] = string.split("\n");
-			assertTrue("Not enough elements in the result file", lines.length >= 2);
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testAllExportColumnsSpecies() throws Exception {
-		try {
-			Model model = getModelForFile("testFiles/export_with_artifitial_comp.xml", false);
-			List<ExportColumn> columns = new ArrayList<ExportColumn>();
-			for (ExportColumn column : ExportColumn.values()) {
-				if (column.getClazz().isAssignableFrom(Species.class)) {
-					columns.add(column);
-				}
-			}
-
-			ExporterParameters params = new IExporterService.ExporterParameters().model(model).column(columns).fileType(ExportFileType.TAB_SEPARATED);
-
-			// full export (all elements)
-			String string = exporter.getExportSpeciesString(params);
-			assertNotNull(string);
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testAllExportColumnsReaction() throws Exception {
-		try {
-			Model model = getModelForFile("testFiles/export_with_artifitial_comp.xml", false);
-			List<ExportColumn> columns = new ArrayList<ExportColumn>();
-			for (ExportColumn column : ExportColumn.values()) {
-				if (column.getClazz().isAssignableFrom(Reaction.class)) {
-					columns.add(column);
-				}
-			}
-
-			ExporterParameters params = new IExporterService.ExporterParameters().model(model).column(columns).fileType(ExportFileType.TAB_SEPARATED);
-
-			// full export (all elements)
-			String string = exporter.getExportInteractionString(params);
-			assertNotNull(string);
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testGetTabSeparatedReaction() throws Exception {
-		try {
-			Model model = getModelForFile("testFiles/export/reaction.xml", false);
-			Set<Compartment> aliases = new HashSet<>();
-			for (Compartment alias : model.getCompartments()) {
-				if (alias.getName().equalsIgnoreCase("Dopamine loaded synaptic vesicle"))
-					aliases.add(alias);
-			}
-
-			ExporterParameters params = new IExporterService.ExporterParameters().model(model).//
-					fileType(ExportFileType.TAB_SEPARATED).//
-					column(ExportColumn.REACTION_ID).//
-					column(ExportColumn.REACTION_TYPE).//
-					type(Species.class);
-
-			String string = exporter.getExportInteractionString(params);
-			assertTrue(string.indexOf("STATE_TRANSITION	REACTANT") >= 0);
-			assertTrue(string.indexOf("sa7") >= 0);
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-
-	}
-
-	@Test
-	public void test() throws Exception {
-		try {
-			Model model = getModelForFile("testFiles/export/new_line_file.xml", false);
-			List<ExportColumn> columns = new ArrayList<ExportColumn>();
-			for (ExportColumn column : ExportColumn.values()) {
-				if (column.getClazz().isAssignableFrom(Species.class)) {
-					columns.add(column);
-				}
-			}
-
-			ExporterParameters params = new IExporterService.ExporterParameters().model(model).column(columns).fileType(ExportFileType.TAB_SEPARATED);
-
-			// full export (all elements)
-			String string = exporter.getExportSpeciesString(params);
-			String tmp[] = string.split("\n");
-			for (String string2 : tmp) {
-				assertTrue(string2, columns.size() <= string2.split("\t", -1).length);
-			}
-			assertNotNull(string);
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testPubmedSummary() throws Exception {
-		try {
-			Model model = getModelForFile("testFiles/export/reaction.xml", false);
-			List<PubmedAnnotatedElementsView> result = exporter.getPublicationModelSummary(model);
-			assertNotNull(result);
-			for (PubmedAnnotatedElementsView pubmedAnnotatedElementsView : result) {
-				assertNotNull(pubmedAnnotatedElementsView.getArticle());
-				assertNotNull(pubmedAnnotatedElementsView.getArticle().getTitle());
-				assertTrue(pubmedAnnotatedElementsView.getElements().size() > 0);
-			}
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
+  Logger logger = Logger.getLogger(ExporterServiceTest.class);
+  @Autowired
+  IExporterService exporter2;
+
+  ExporterService exporter;
+
+  @Before
+  public void setUp() throws Exception {
+    exporter = (ExporterService) exporter2;
+  }
+
+  @After
+  public void tearDown() throws Exception {
+  }
+
+  @Test
+  public void testGetExportSpeciesStringForTabSeparatedFile() throws Exception {
+    try {
+      Model model = getModelForFile("testFiles/export_with_artifitial_comp.xml", false);
+      ExportColumn columns[] = { ExportColumn.NAME, ExportColumn.ID, ExportColumn.COMPONENT_NAME,
+          ExportColumn.COMPARTMENT_NAME, ExportColumn.TYPE };
+
+      ExporterParameters params = new IExporterService.ExporterParameters().model(model).column(columns)
+          .fileType(ExportFileType.TAB_SEPARATED);
+
+      // full export (all elements)
+      String string = exporter.getExportSpeciesString(params);
+      String lines[] = string.split("\n");
+      assertTrue("Not enough elements in the result file", lines.length > 1);
+
+      String response = lines[0];
+      String textColumns[] = response.split("\t");
+      assertEquals(5, textColumns.length);
+
+      // only proteins for self-made modules
+      new CreateHierarchyCommand(model, 8, 80).execute();
+      string = exporter.getExportSpeciesString(params.type(GenericProtein.class));
+      lines = string.split("\n");
+      assertTrue(lines.length > 1);
+
+      boolean differenceBetweenComponentCompartmnet = false;
+      int lineCount = 0;
+      for (String string2 : lines) {
+        if (lineCount == 0) {
+          textColumns = string2.split("\t");
+          assertEquals(ExportColumn.TYPE.getTitle(), textColumns[4]);
+        } else {
+          textColumns = string2.split("\t");
+          assertEquals(GenericProtein.class.getSimpleName(), textColumns[4]);
+          if (!textColumns[2].equalsIgnoreCase(textColumns[3])) {
+            differenceBetweenComponentCompartmnet = true;
+          }
+        }
+        lineCount++;
+      }
+      assertTrue(differenceBetweenComponentCompartmnet);
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testDuplicatesInGetExportSpeciesString() throws Exception {
+    try {
+      Model model = getModelForFile("testFiles/export_duplicate_elements.xml", false);
+      ExportColumn columns[] = { ExportColumn.NAME, ExportColumn.COMPONENT_NAME, ExportColumn.TYPE };
+
+      ExporterParameters params = new IExporterService.ExporterParameters().model(model).column(columns)
+          .fileType(ExportFileType.TAB_SEPARATED);
+
+      // full export (all elements)
+      String string = exporter.getExportSpeciesString(params);
+
+      String lines[] = string.split("\n");
+      Set<String> uniqueNames = new HashSet<String>();
+      for (String string2 : lines) {
+        uniqueNames.add(string2);
+      }
+      assertEquals(uniqueNames.size(), lines.length);
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testGetExportStringForOneSpecies_Complex() {
+    try {
+      Model model = getModelForFile("testFiles/export/hsp70.xml", true);
+
+      Species alias = (Species) model.getElementByElementId("csa1");
+      ExportColumn columns[] = { ExportColumn.NAME };
+
+      ExporterParameters params = new IExporterService.ExporterParameters().model(model).//
+          column(columns).//
+          complexElementsName(false).//
+          fileType(ExportFileType.TAB_SEPARATED);
+
+      List<String> elements = exporter.getExportStringForOneSpecies(alias, params);
+      assertTrue(elements.contains("HSP70:chaperon"));
+
+      // now the results are concatenated children
+      params.complexElementsName(true);
+
+      elements = exporter.getExportStringForOneSpecies(alias, params);
+      assertTrue(elements.size() > 0);
+      String string = elements.get(0);
+      assertFalse(string.equals("HSP70:chaperon"));
+      assertTrue(string.contains("HSP70"));
+      assertTrue(string.contains("STUB1"));
+      assertTrue(string.contains("DNAJB2"));
+      assertTrue(string.contains("BAG1"));
+
+      // and now check complexes with mix of proteins and molecules
+      alias = (Species) model.getElementByElementId("csa3");
+
+      elements = exporter.getExportStringForOneSpecies(alias, params);
+      assertTrue(elements.size() > 0);
+      string = elements.get(0);
+      assertTrue(string.contains("UBA1"));
+      assertTrue(string.contains("UBA6"));
+      assertTrue(string.contains("AMP"));
+
+      elements = exporter.getExportStringForOneSpecies(alias, params.type(Protein.class));
+      assertTrue(elements.size() > 0);
+      string = elements.get(0);
+      assertTrue(string.contains("UBA1"));
+      assertTrue(string.contains("UBA6"));
+      assertFalse(string.contains("AMP"));
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      fail("Exception occured");
+    }
+  }
+
+  @Test
+  public void testGetExportStringForOneReaction() throws Exception {
+    try {
+      Model model = getModelForFile("testFiles/export/reaction.xml", false);
+      Set<Compartment> aliases = new HashSet<>();
+      for (Compartment alias : model.getCompartments()) {
+        if (alias.getName().equalsIgnoreCase("Dopamine loaded synaptic vesicle"))
+          aliases.add(alias);
+      }
+
+      Reaction reaction = model.getReactionByReactionId("re2");
+
+      ExporterParameters params = new IExporterService.ExporterParameters().model(model).//
+          fileType(ExportFileType.SIF).//
+          type(Protein.class).//
+          type(Complex.class).//
+          fileType(ExportFileType.SIF).//
+          complexElementsName(false).//
+          excluded(aliases);
+
+      String string = exporter.getExportSingleInteractionString(reaction, params).get(0);
+      assertNotNull(string);
+      assertTrue(string.contains("Calcium channel:RIMBP:RIM:MUNC13:RAB"));
+      assertTrue(string.contains("CSP:Hsc70:SGT"));
+      assertTrue(string.contains("SNCA"));
+      assertTrue(string.contains("trans-SNARE complex"));
+      assertFalse(string.contains("VAMP2"));
+
+      params = new IExporterService.ExporterParameters().model(model).fileType(ExportFileType.SIF).type(Complex.class)
+          .type(Protein.class);
+      string = exporter.getExportSingleInteractionString(reaction, params).get(0);
+      assertTrue(string.contains("VAMP2"));
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+
+  }
+
+  @Test
+  public void testGetExportStringForOneReactionInGeneral() {
+    try {
+      Model model = getModelForFile("testFiles/export/reaction.xml", true);
+      Reaction reaction = model.getReactionByReactionId("re2");
+      ExporterParameters params = new IExporterService.ExporterParameters().model(model).//
+          fileType(ExportFileType.SIF).//
+          complexElementsName(false).//
+          type(Complex.class).type(Protein.class);
+      String string = exporter.getExportSingleInteractionString(reaction, params).get(0);
+      assertNotNull(string);
+      assertTrue(string.contains("Calcium channel:RIMBP:RIM:MUNC13:RAB"));
+      assertTrue(string.contains("CSP:Hsc70:SGT"));
+      assertTrue(string.contains("SNCA"));
+      assertTrue(string.contains("trans-SNARE complex"));
+      assertTrue(string.contains("SNAP25"));
+      assertFalse(string.contains("RAB3A"));
+
+      params.complexElementsName(true);
+      string = exporter.getExportSingleInteractionString(reaction, params).get(0);
+      assertFalse(string.contains("trans-SNARE complex"));
+      assertTrue(string.contains("RAB3A"));
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      fail("Exception occured");
+    }
+
+  }
+
+  @Test
+  public void testGetExportStringForOneReactionInGeneralWithOnlyOneElement() throws Exception {
+    try {
+      Model model = getModelForFile("testFiles/export/reaction.xml", false);
+      Reaction reaction = model.getReactionByReactionId("re11");
+      model.removeReactions(model.getReactions());
+      model.addReaction(reaction);
+      Set<Compartment> aliases = new HashSet<>();
+      aliases.add((Compartment) model.getElementByElementId("ca1"));
+      ExporterParameters params = new IExporterService.ExporterParameters().model(model).fileType(ExportFileType.SIF)
+          .included("dopamine loaded synaptic vesicle");
+      assertEquals(0, exporter.getExportSingleInteractionString(reaction, params).size());
+
+      params = new IExporterService.ExporterParameters().model(model).fileType(ExportFileType.SIF);
+      assertEquals(1, exporter.getExportSingleInteractionString(reaction, params).size());
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testGetExportSingleInteractionString_text() {
+    try {
+      Model model = getModelForFile("testFiles/export_with_artifitial_comp.xml", false);
+      for (Reaction reaction : model.getReactions()) {
+        String str = exporter
+            .getExportSingleInteractionString(reaction,
+                new IExporterService.ExporterParameters().fileType(ExportFileType.TAB_SEPARATED).type(Species.class))
+            .get(0);
+
+        List<String> strings = new ArrayList<String>();
+        strings.add(ReactionLineData.getByReactionType(reaction.getClass()).getCellDesignerString());
+        strings.add(reaction.getIdReaction());
+        for (ReactionNode node : reaction.getReactionNodes()) {
+          strings.add(node.getElement().getName());
+
+        }
+        for (String string : strings) {
+          assertTrue(
+              "Description \"" + str + "\" doesn't contain " + string + ". reactionId=" + reaction.getIdReaction(),
+              str.contains(string));
+        }
+      }
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      fail("Exception occured");
+    }
+  }
+
+  @Test
+  public void testGetExportComponentAndCompartments() throws Exception {
+    try {
+      Model model = getModelForFile("testFiles/export/export_model.xml", false);
+      new CreateHierarchyCommand(model, 7, 80).execute();
+      ExporterParameters params = new IExporterService.ExporterParameters().model(model)
+          .fileType(ExportFileType.TAB_SEPARATED).column(ExportColumn.NAME).column(ExportColumn.COMPONENT_NAME)
+          .column(ExportColumn.COMPARTMENT_NAME);
+
+      List<String> list = exporter.getExportStringForOneSpecies((Species) model.getElementByElementId("sa1"), params);
+      String desc = list.get(0);
+      String compartment = desc.split("\t")[2];
+      assertEquals("c1", compartment);
+      String component = desc.split("\t")[1];
+      assertEquals("Test3", component);
+
+      list = exporter.getExportStringForOneSpecies((Species) model.getElementByElementId("sa2"), params);
+      desc = null;
+      for (String string : list) {
+        if (string.contains("Test 1")) {
+          desc = string;
+        }
+      }
+      compartment = desc.split("\t")[2];
+      assertEquals("c2", compartment);
+      component = desc.split("\t")[1];
+      assertEquals("Test 1", component);
+
+      for (String string : list) {
+        if (string.contains("Test2")) {
+          desc = string;
+        }
+      }
+      compartment = desc.split("\t")[2];
+      assertEquals("c2", compartment);
+      component = desc.split("\t")[1];
+      assertEquals("Test2", component);
+
+      for (String string : list) {
+        if (string.contains("Test3")) {
+          desc = string;
+        }
+      }
+      compartment = desc.split("\t")[2];
+      assertEquals("c2", compartment);
+      component = desc.split("\t")[1];
+      assertEquals("Test3", component);
+
+      list = exporter.getExportStringForOneSpecies((Species) model.getElementByElementId("sa3"), params);
+      boolean ok = false;
+      for (String string : list) {
+        if (string.split("\t")[2].equals("null") && string.split("\t")[1].equals("Test2")) {
+          ok = true;
+        }
+      }
+      assertTrue(ok);
+
+      list = exporter.getExportStringForOneSpecies((Species) model.getElementByElementId("sa4"), params);
+      desc = list.get(0);
+      compartment = desc.split("\t")[2];
+      assertEquals("null", compartment);
+      component = desc.split("\t")[1];
+      assertEquals("Test3", component);
+
+      list = exporter.getExportStringForOneSpecies((Species) model.getElementByElementId("sa5"), params);
+      desc = list.get(0);
+      compartment = desc.split("\t")[2];
+      assertEquals("c3", compartment);
+      component = desc.split("\t")[1];
+      assertEquals("null", component);
+
+      list = exporter.getExportStringForOneSpecies((Species) model.getElementByElementId("sa6"), params);
+      desc = list.get(0);
+      compartment = desc.split("\t")[2];
+      assertEquals("null", compartment);
+      component = desc.split("\t")[1];
+      assertEquals("null", component);
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testGetExportSpeciesStringForTabSeparatedFile2() throws Exception {
+    try {
+      Model model = getModelForFile("testFiles/export_with_artifitial_comp.xml", false);
+      ExportColumn columns[] = { ExportColumn.NAME, ExportColumn.ID, ExportColumn.COMPONENT_NAME,
+          ExportColumn.COMPARTMENT_NAME, ExportColumn.TYPE };
+
+      ExporterParameters params = new IExporterService.ExporterParameters().model(model).column(columns)
+          .fileType(ExportFileType.TAB_SEPARATED).type(Object.class);
+
+      // full export (all elements)
+      String string = exporter.getExportSpeciesString(params);
+      String lines[] = string.split("\n");
+      assertTrue("Not enough elements in the result file", lines.length > 1);
+
+      String response = lines[0];
+      String textColumns[] = response.split("\t");
+      assertEquals(columns.length, textColumns.length);
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testGetExportCompartmentsString() throws Exception {
+    try {
+      Model model = getModelForFile("testFiles/export/export_compartments.xml", false);
+
+      ExporterParameters params = new IExporterService.ExporterParameters().model(model)
+          .fileType(ExportFileType.TAB_SEPARATED).type(Object.class);
+
+      // full export (all compartments)
+      String string = exporter.getExportCompartmentsString(params);
+      String lines[] = string.split("\n");
+      assertTrue("Not enough elements in the result file", lines.length >= 2);
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testAllExportColumnsSpecies() throws Exception {
+    try {
+      Model model = getModelForFile("testFiles/export_with_artifitial_comp.xml", false);
+      List<ExportColumn> columns = new ArrayList<ExportColumn>();
+      for (ExportColumn column : ExportColumn.values()) {
+        if (column.getClazz().isAssignableFrom(Species.class)) {
+          columns.add(column);
+        }
+      }
+
+      ExporterParameters params = new IExporterService.ExporterParameters().model(model).column(columns)
+          .fileType(ExportFileType.TAB_SEPARATED);
+
+      // full export (all elements)
+      String string = exporter.getExportSpeciesString(params);
+      assertNotNull(string);
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testAllExportColumnsReaction() throws Exception {
+    try {
+      Model model = getModelForFile("testFiles/export_with_artifitial_comp.xml", false);
+      List<ExportColumn> columns = new ArrayList<ExportColumn>();
+      for (ExportColumn column : ExportColumn.values()) {
+        if (column.getClazz().isAssignableFrom(Reaction.class)) {
+          columns.add(column);
+        }
+      }
+
+      ExporterParameters params = new IExporterService.ExporterParameters().model(model).column(columns)
+          .fileType(ExportFileType.TAB_SEPARATED);
+
+      // full export (all elements)
+      String string = exporter.getExportInteractionString(params);
+      assertNotNull(string);
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testGetTabSeparatedReaction() throws Exception {
+    try {
+      Model model = getModelForFile("testFiles/export/reaction.xml", false);
+      Set<Compartment> aliases = new HashSet<>();
+      for (Compartment alias : model.getCompartments()) {
+        if (alias.getName().equalsIgnoreCase("Dopamine loaded synaptic vesicle"))
+          aliases.add(alias);
+      }
+
+      ExporterParameters params = new IExporterService.ExporterParameters().model(model).//
+          fileType(ExportFileType.TAB_SEPARATED).//
+          column(ExportColumn.REACTION_ID).//
+          column(ExportColumn.REACTION_TYPE).//
+          type(Species.class);
+
+      String string = exporter.getExportInteractionString(params);
+      assertTrue(string.indexOf("STATE_TRANSITION	REACTANT") >= 0);
+      assertTrue(string.indexOf("sa7") >= 0);
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+
+  }
+
+  @Test
+  public void test() throws Exception {
+    try {
+      Model model = getModelForFile("testFiles/export/new_line_file.xml", false);
+      List<ExportColumn> columns = new ArrayList<ExportColumn>();
+      for (ExportColumn column : ExportColumn.values()) {
+        if (column.getClazz().isAssignableFrom(Species.class)) {
+          columns.add(column);
+        }
+      }
+
+      ExporterParameters params = new IExporterService.ExporterParameters().model(model).column(columns)
+          .fileType(ExportFileType.TAB_SEPARATED);
+
+      // full export (all elements)
+      String string = exporter.getExportSpeciesString(params);
+      String tmp[] = string.split("\n");
+      for (String string2 : tmp) {
+        assertTrue(string2, columns.size() <= string2.split("\t", -1).length);
+      }
+      assertNotNull(string);
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testPubmedSummary() throws Exception {
+    try {
+      Model model = getModelForFile("testFiles/export/reaction.xml", false);
+      List<PubmedAnnotatedElementsView> result = exporter.getPublicationModelSummary(model);
+      assertNotNull(result);
+      for (PubmedAnnotatedElementsView pubmedAnnotatedElementsView : result) {
+        assertNotNull(pubmedAnnotatedElementsView.getArticle());
+        assertNotNull(pubmedAnnotatedElementsView.getArticle().getTitle());
+        assertTrue(pubmedAnnotatedElementsView.getElements().size() > 0);
+      }
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
 }
diff --git a/service/src/test/java/lcsb/mapviewer/services/search/data/FullAliasViewFactoryTest.java b/service/src/test/java/lcsb/mapviewer/services/search/data/FullAliasViewFactoryTest.java
index 538ec5894c2b3dc05c62f2d74065b3aa4b6dd833..0e1577f840cb18a675253a920e1db457d0662a8c 100644
--- a/service/src/test/java/lcsb/mapviewer/services/search/data/FullAliasViewFactoryTest.java
+++ b/service/src/test/java/lcsb/mapviewer/services/search/data/FullAliasViewFactoryTest.java
@@ -40,195 +40,197 @@ import lcsb.mapviewer.services.ServiceTestFunctions;
 import lcsb.mapviewer.services.overlay.ChebiTreeRow;
 
 public class FullAliasViewFactoryTest extends ServiceTestFunctions {
-	Logger									 logger	= Logger.getLogger(FullAliasViewFactoryTest.class);
-
-	@Autowired
-	FullAliasViewFactory		 fullAliasViewFactory;
-
-	@Autowired
-	private ChebiAnnotator	 backend;
-	private Species		 alias;
-	private Species		 alias2;
-	private Point2D					 midPoint;
-	private Reaction				 reaction;
-	private Species		 alias3;
-
-	private Model						 model;
-
-	private Compartment compartmentAlias;
-
-	@Before
-	public void setUp() throws Exception {
-
-		model = new ModelFullIndexed(null);
-		model.setWidth(20010);
-		model.setHeight(20010);
-		model.setTileSize(256);
-		model.setZoomLevels(7);
-		model.addLayout(new Layout());
-		model.getModelData().setId(-12);
-
-		alias = new GenericProtein("AL1");
-		alias.setName("blablabla");
-		alias.setNotes("nottttttes");
-		alias.setX(10.0);
-		alias.setY(12.0);
-		alias.getMiriamData().add(new MiriamData(MiriamRelationType.BQ_BIOL_IS_DESCRIBED_BY, MiriamType.WIKIPEDIA, "144352"));
-		alias.getMiriamData().add(new MiriamData(MiriamRelationType.BQ_BIOL_IS_DESCRIBED_BY, MiriamType.PUBMED, "43345"));
-
-		model.addElement(alias);
-
-		alias2 = new GenericProtein("AL2");
-		alias2.setName("blablabla2");
-		alias2.setX(100.0);
-		alias2.setY(120.0);
-
-		model.addElement(alias2);
-
-		midPoint = new Point2D.Double(30, 100);
-
-		reaction = new Reaction();
-
-		Reactant reactant = new Reactant(alias);
-		reactant.setLine(new PolylineData(alias.getCenter(), midPoint));
-		reaction.addReactant(reactant);
-
-		Product product = new Product(alias2);
-		product.setLine(new PolylineData(alias2.getCenter(), midPoint));
-		reaction.addProduct(product);
-
-		model.addReaction(reaction);
-
-		alias3 = new GenericProtein("AL3");
-		alias3.setName("blablabla3");
-		alias3.setX(200.0);
-		alias3.setY(120.0);
-
-		model.addElement(alias3);
-
-		reaction = new NegativeInfluenceReaction(reaction);
-		reaction.getMiriamData().add(new MiriamData(MiriamRelationType.BQ_BIOL_IS_DESCRIBED_BY, MiriamType.CAS, "cc"));
-
-		model.addReaction(reaction);
-
-		compartmentAlias = new Compartment("AL4");
-		compartmentAlias.setX(10);
-		compartmentAlias.setY(10);
-		compartmentAlias.setWidth(10);
-		compartmentAlias.setHeight(10);
-		model.addElement(compartmentAlias);
-	}
-
-	@After
-	public void tearDown() throws Exception {
-	}
-
-	@Test
-	public void testCreateGson() {
-		try {
-			Element alias = new GenericProtein("id");
-			alias.setName("12");
-			alias.setModel(new ModelFullIndexed(null));
-			FullAliasView object = fullAliasViewFactory.create(alias);
-			String gson = fullAliasViewFactory.createGson(object);
-			assertNotNull(gson);
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testAliasOverlay() throws Exception {
-		try {
-			FullAliasView result = fullAliasViewFactory.create(alias);
-			assertNotNull(result);
-			assertEquals(model.getId(), result.getModelId());
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testAliasOverlay2() throws Exception {
-		try {
-			FullAliasView result = fullAliasViewFactory.create(alias2);
-			assertNotNull(result);
-			assertEquals(model.getId(), result.getModelId());
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testGetNotes() throws Exception {
-		try {
-			Model model = getModelForFile("testFiles/protein_with_modification.xml", true);
-			model.setTileSize(256);
-			Species alias = (Species) model.getElementByElementId("sa1");
-			FullAliasView marker = fullAliasViewFactory.create(alias);
-			List<?> list = (List<?>) marker.getOther("posttranslationalModifications");
-			assertNotNull(list);
-			assertEquals(2, list.size());
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testCreateChebiTree() throws Exception {
-		try {
-			Chebi chebi = backend.getChebiElementForChebiId(new MiriamData(MiriamType.CHEBI, "CHEBI:15377"));
-
-			TreeNode root = fullAliasViewFactory.createTreeForChebi(chebi);
-
-			Set<String> el = new HashSet<String>();
-			assertNotNull(root);
-
-			Queue<TreeNode> elements = new LinkedList<TreeNode>();
-
-			elements.add(root);
-
-			while (!elements.isEmpty()) {
-				TreeNode node = elements.peek();
-				elements.remove();
-				el.add(((ChebiTreeRow) node.getData()).getName());
-				for (TreeNode child : node.getChildren()) {
-					elements.add(child);
-				}
-			}
-
-			assertTrue(el.size() > 3);
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testAnnotationsInConversionForChebiTree() throws Exception {
-		try {
-			Model model = getModelForFile("testFiles/graph_path_example3.xml", false);
-			model.setTileSize(256);
-			Species alias = (Species) model.getElementByElementId("sa4");
-			assertNotNull(alias);
-			FullAliasView result = fullAliasViewFactory.create(alias);
-			assertNotNull(result.getOther("chebiTree"));
-
-			alias = (Species) model.getElementByElementId("sa3");
-			result = fullAliasViewFactory.create(alias);
-			assertNull(result.getOther("chebiTree"));
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
+  Logger logger = Logger.getLogger(FullAliasViewFactoryTest.class);
+
+  @Autowired
+  FullAliasViewFactory fullAliasViewFactory;
+
+  @Autowired
+  private ChebiAnnotator backend;
+  private Species alias;
+  private Species alias2;
+  private Point2D midPoint;
+  private Reaction reaction;
+  private Species alias3;
+
+  private Model model;
+
+  private Compartment compartmentAlias;
+
+  @Before
+  public void setUp() throws Exception {
+
+    model = new ModelFullIndexed(null);
+    model.setWidth(20010);
+    model.setHeight(20010);
+    model.setTileSize(256);
+    model.setZoomLevels(7);
+    model.addLayout(new Layout());
+    model.getModelData().setId(-12);
+
+    alias = new GenericProtein("AL1");
+    alias.setName("blablabla");
+    alias.setNotes("nottttttes");
+    alias.setX(10.0);
+    alias.setY(12.0);
+    alias.getMiriamData()
+        .add(new MiriamData(MiriamRelationType.BQ_BIOL_IS_DESCRIBED_BY, MiriamType.WIKIPEDIA, "144352"));
+    alias.getMiriamData().add(new MiriamData(MiriamRelationType.BQ_BIOL_IS_DESCRIBED_BY, MiriamType.PUBMED, "43345"));
+
+    model.addElement(alias);
+
+    alias2 = new GenericProtein("AL2");
+    alias2.setName("blablabla2");
+    alias2.setX(100.0);
+    alias2.setY(120.0);
+
+    model.addElement(alias2);
+
+    midPoint = new Point2D.Double(30, 100);
+
+    reaction = new Reaction("re1");
+
+    Reactant reactant = new Reactant(alias);
+    reactant.setLine(new PolylineData(alias.getCenter(), midPoint));
+    reaction.addReactant(reactant);
+
+    Product product = new Product(alias2);
+    product.setLine(new PolylineData(alias2.getCenter(), midPoint));
+    reaction.addProduct(product);
+
+    model.addReaction(reaction);
+
+    alias3 = new GenericProtein("AL3");
+    alias3.setName("blablabla3");
+    alias3.setX(200.0);
+    alias3.setY(120.0);
+
+    model.addElement(alias3);
+
+    reaction = new NegativeInfluenceReaction(reaction);
+    reaction.setIdReaction("re2");
+    reaction.getMiriamData().add(new MiriamData(MiriamRelationType.BQ_BIOL_IS_DESCRIBED_BY, MiriamType.CAS, "cc"));
+
+    model.addReaction(reaction);
+
+    compartmentAlias = new Compartment("AL4");
+    compartmentAlias.setX(10);
+    compartmentAlias.setY(10);
+    compartmentAlias.setWidth(10);
+    compartmentAlias.setHeight(10);
+    model.addElement(compartmentAlias);
+  }
+
+  @After
+  public void tearDown() throws Exception {
+  }
+
+  @Test
+  public void testCreateGson() {
+    try {
+      Element alias = new GenericProtein("id");
+      alias.setName("12");
+      alias.setModel(new ModelFullIndexed(null));
+      FullAliasView object = fullAliasViewFactory.create(alias);
+      String gson = fullAliasViewFactory.createGson(object);
+      assertNotNull(gson);
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testAliasOverlay() throws Exception {
+    try {
+      FullAliasView result = fullAliasViewFactory.create(alias);
+      assertNotNull(result);
+      assertEquals(model.getId(), result.getModelId());
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testAliasOverlay2() throws Exception {
+    try {
+      FullAliasView result = fullAliasViewFactory.create(alias2);
+      assertNotNull(result);
+      assertEquals(model.getId(), result.getModelId());
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testGetNotes() throws Exception {
+    try {
+      Model model = getModelForFile("testFiles/protein_with_modification.xml", true);
+      model.setTileSize(256);
+      Species alias = (Species) model.getElementByElementId("sa1");
+      FullAliasView marker = fullAliasViewFactory.create(alias);
+      List<?> list = (List<?>) marker.getOther("posttranslationalModifications");
+      assertNotNull(list);
+      assertEquals(2, list.size());
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testCreateChebiTree() throws Exception {
+    try {
+      Chebi chebi = backend.getChebiElementForChebiId(new MiriamData(MiriamType.CHEBI, "CHEBI:15377"));
+
+      TreeNode root = fullAliasViewFactory.createTreeForChebi(chebi);
+
+      Set<String> el = new HashSet<String>();
+      assertNotNull(root);
+
+      Queue<TreeNode> elements = new LinkedList<TreeNode>();
+
+      elements.add(root);
+
+      while (!elements.isEmpty()) {
+        TreeNode node = elements.peek();
+        elements.remove();
+        el.add(((ChebiTreeRow) node.getData()).getName());
+        for (TreeNode child : node.getChildren()) {
+          elements.add(child);
+        }
+      }
+
+      assertTrue(el.size() > 3);
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testAnnotationsInConversionForChebiTree() throws Exception {
+    try {
+      Model model = getModelForFile("testFiles/graph_path_example3.xml", false);
+      model.setTileSize(256);
+      Species alias = (Species) model.getElementByElementId("sa4");
+      assertNotNull(alias);
+      FullAliasView result = fullAliasViewFactory.create(alias);
+      assertNotNull(result.getOther("chebiTree"));
+
+      alias = (Species) model.getElementByElementId("sa3");
+      result = fullAliasViewFactory.create(alias);
+      assertNull(result.getOther("chebiTree"));
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
 
 }