diff --git a/CHANGELOG b/CHANGELOG
index 68e8a13aaa71072819a31384b88aaa35076a293c..8c14990d688290edf73c98af49f4085c20650892 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,9 @@
+minerva (14.0.3) stable; urgency=medium
+  * Bug fix: parsing of CellDesigner files that contained substanceUnits could
+    crash the upload (#985)
+
+ -- Piotr Gawron <piotr.gawron@uni.lu>  Wed, 16 Oct 2019 9:00:00 +0200
+
 minerva (14.0.2) stable; urgency=medium
   * Bug fix: Genetic data overlay uploaded prior to 14.0.0 crashed maps (#988)
 
diff --git a/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/CellDesignerXmlParser.java b/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/CellDesignerXmlParser.java
index 37084d1bd0d9dd30292a8ded5c05ae0cb2a6c14b..c6386575d66324c51057c8837de764cddd3d11d8 100644
--- a/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/CellDesignerXmlParser.java
+++ b/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/CellDesignerXmlParser.java
@@ -98,7 +98,7 @@ public class CellDesignerXmlParser extends Converter {
     if (params.getFilename() != null) {
       model.setName(FilenameUtils.getBaseName(params.getFilename()));
     }
-    speciesSbmlParser = new SpeciesCollectionXmlParser(elements);
+    speciesSbmlParser = new SpeciesCollectionXmlParser(elements, model.getUnits());
     aliasCollectionParser = new AliasCollectionXmlParser(elements, model);
     compartmentCollectionXmlParser = new CompartmentCollectionXmlParser(elements);
 
@@ -133,21 +133,6 @@ public class CellDesignerXmlParser extends Converter {
         model.setIdModel(modelId);
       }
 
-      Node compartmentNode = XmlParser.getNode("listOfCompartments", modelNode.getChildNodes());
-      if (compartmentNode != null) {
-        List<CellDesignerCompartment> compartments = compartmentCollectionXmlParser
-            .parseXmlCompartmentCollection(compartmentNode);
-        elements.addElements(compartments);
-      }
-
-      InternalModelSpeciesData modelData = new InternalModelSpeciesData();
-
-      Node speciesNode = XmlParser.getNode("listOfSpecies", modelNode.getChildNodes());
-      if (speciesNode != null) {
-        List<Pair<String, ? extends CellDesignerSpecies<?>>> species = speciesSbmlParser
-            .parseSbmlSpeciesCollection(speciesNode);
-        modelData.updateSpecies(species);
-      }
       Node reactionsNode = null;
       Node functionsNode = null;
       Node unitsNode = null;
@@ -192,6 +177,22 @@ public class CellDesignerXmlParser extends Converter {
         model.addParameters(parameterParser.parseXmlParameterCollection(parametersNode));
       }
 
+      Node compartmentNode = XmlParser.getNode("listOfCompartments", modelNode.getChildNodes());
+      if (compartmentNode != null) {
+        List<CellDesignerCompartment> compartments = compartmentCollectionXmlParser
+            .parseXmlCompartmentCollection(compartmentNode);
+        elements.addElements(compartments);
+      }
+
+      InternalModelSpeciesData modelData = new InternalModelSpeciesData();
+
+      Node speciesNode = XmlParser.getNode("listOfSpecies", modelNode.getChildNodes());
+      if (speciesNode != null) {
+        List<Pair<String, ? extends CellDesignerSpecies<?>>> species = speciesSbmlParser
+            .parseSbmlSpeciesCollection(speciesNode);
+        modelData.updateSpecies(species);
+      }
+
       Node annotationNode = XmlParser.getNode("annotation", modelNode.getChildNodes());
       if (annotationNode == null) {
         throw new InvalidInputDataExecption("No annotation node in SBML/model");
@@ -388,7 +389,7 @@ public class CellDesignerXmlParser extends Converter {
 
   private void parseAnnotationExtension(Model model, InternalModelSpeciesData modelData,
       CellDesignerElementCollection elements, Node extensionNode) throws InvalidXmlSchemaException {
-    SpeciesCollectionXmlParser parser = new SpeciesCollectionXmlParser(elements);
+    SpeciesCollectionXmlParser parser = new SpeciesCollectionXmlParser(elements, model.getUnits());
 
     NodeList nodes = extensionNode.getChildNodes();
     Node includedSpecies = null;
@@ -598,7 +599,7 @@ public class CellDesignerXmlParser extends Converter {
     try {
       CellDesignerElementCollection elements = new CellDesignerElementCollection();
 
-      SpeciesCollectionXmlParser speciesCollectionXmlParser = new SpeciesCollectionXmlParser(elements);
+      SpeciesCollectionXmlParser speciesCollectionXmlParser = new SpeciesCollectionXmlParser(elements, model.getUnits());
       ReactionCollectionXmlParser reactionCollectionXmlParser = new ReactionCollectionXmlParser(model, elements, false);
       UnitCollectionXmlParser unitCollectionXmlParser = new UnitCollectionXmlParser();
       FunctionCollectionXmlParser functionCollectionXmlParser = new FunctionCollectionXmlParser();
@@ -667,7 +668,7 @@ public class CellDesignerXmlParser extends Converter {
    * @return annotation xml string for the model
    */
   private String annotationToXml(Model model, CellDesignerElementCollection elements) {
-    SpeciesCollectionXmlParser speciesCollectionXmlParser = new SpeciesCollectionXmlParser(elements);
+    SpeciesCollectionXmlParser speciesCollectionXmlParser = new SpeciesCollectionXmlParser(elements, model.getUnits());
 
     StringBuilder result = new StringBuilder();
     result.append("<annotation>\n");
diff --git a/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/species/SpeciesCollectionXmlParser.java b/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/species/SpeciesCollectionXmlParser.java
index c7647412b1a5c27f870c47feb3256546ab1951ab..d174992a69afced89e30ae83ef3814f0974395c3 100644
--- a/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/species/SpeciesCollectionXmlParser.java
+++ b/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/species/SpeciesCollectionXmlParser.java
@@ -16,6 +16,7 @@ import lcsb.mapviewer.converter.model.celldesigner.CellDesignerElementCollection
 import lcsb.mapviewer.converter.model.celldesigner.annotation.RestAnnotationParser;
 import lcsb.mapviewer.converter.model.celldesigner.structure.*;
 import lcsb.mapviewer.model.map.InconsistentModelException;
+import lcsb.mapviewer.model.map.kinetics.SbmlUnit;
 import lcsb.mapviewer.model.map.species.*;
 
 /**
@@ -95,6 +96,8 @@ public class SpeciesCollectionXmlParser {
    */
   private CellDesignerElementCollection elements;
 
+  private Collection<SbmlUnit> units;
+
   /**
    * Default constructor. Model is required because some CellDesigner nodes
    * require access to other parts of the model.
@@ -103,9 +106,10 @@ public class SpeciesCollectionXmlParser {
    *          collection of {@link CellDesignerElement cell designer elements}
    *          parsed from xml
    */
-  public SpeciesCollectionXmlParser(CellDesignerElementCollection elements) {
-    sbmlSpeciesParser = new SpeciesSbmlParser(elements);
+  public SpeciesCollectionXmlParser(CellDesignerElementCollection elements, Collection<SbmlUnit> units) {
+    sbmlSpeciesParser = new SpeciesSbmlParser(elements, units);
     this.elements = elements;
+    this.units = units;
     rnaParser = new RnaXmlParser(elements);
     geneParser = new GeneXmlParser(elements);
     proteinParser = new ProteinXmlParser(elements);
@@ -390,7 +394,7 @@ public class SpeciesCollectionXmlParser {
     // Probably this should be improved, this part of a CD model is really
     // messy.
     NodeList nodes = spieciesNode.getChildNodes();
-    SpeciesSbmlParser parser = new SpeciesSbmlParser(elements);
+    SpeciesSbmlParser parser = new SpeciesSbmlParser(elements, units);
     for (int x = 0; x < nodes.getLength(); x++) {
       Node node = nodes.item(x);
       if (node.getNodeType() == Node.ELEMENT_NODE) {
diff --git a/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/species/SpeciesSbmlParser.java b/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/species/SpeciesSbmlParser.java
index de2bdea00a1d52d932cbb9681d8343286c23eb49..d6065ed852c48bd0504d41ec903e6ea63f5f722e 100644
--- a/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/species/SpeciesSbmlParser.java
+++ b/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/species/SpeciesSbmlParser.java
@@ -1,5 +1,7 @@
 package lcsb.mapviewer.converter.model.celldesigner.species;
 
+import java.util.Collection;
+
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.w3c.dom.Node;
@@ -16,6 +18,7 @@ import lcsb.mapviewer.converter.model.celldesigner.structure.fields.CellDesigner
 import lcsb.mapviewer.converter.model.celldesigner.structure.fields.SpeciesState;
 import lcsb.mapviewer.model.map.compartment.Compartment;
 import lcsb.mapviewer.model.map.compartment.PathwayCompartment;
+import lcsb.mapviewer.model.map.kinetics.SbmlUnit;
 import lcsb.mapviewer.model.map.kinetics.SbmlUnitType;
 import lcsb.mapviewer.model.map.model.ModelData;
 import lcsb.mapviewer.model.map.species.*;
@@ -43,6 +46,8 @@ public class SpeciesSbmlParser extends AbstractElementXmlParser<CellDesignerSpec
    */
   private CellDesignerElementCollection elements;
 
+  private Collection<SbmlUnit> units;
+
   /**
    * Default constructor. Model is required because some nodes require access to
    * other parts of the model.
@@ -51,8 +56,9 @@ public class SpeciesSbmlParser extends AbstractElementXmlParser<CellDesignerSpec
    *          collection of {@link CellDesignerElement cell designer elements}
    *          parsed from xml
    */
-  public SpeciesSbmlParser(CellDesignerElementCollection elements) {
+  public SpeciesSbmlParser(CellDesignerElementCollection elements, Collection<SbmlUnit> units) {
     this.elements = elements;
+    this.units = units;
   }
 
   @Override
@@ -146,7 +152,17 @@ public class SpeciesSbmlParser extends AbstractElementXmlParser<CellDesignerSpec
     species.setInitialAmount(XmlParser.getNodeAttr("initialAmount", spieciesNode));
     String substanceUnits = XmlParser.getNodeAttr("substanceUnits", spieciesNode);
     if (substanceUnits != null && !substanceUnits.isEmpty()) {
-      species.setSubstanceUnits(SbmlUnitType.valueOf(substanceUnits.toUpperCase()));
+      SbmlUnit sbmlUnit = null;
+      for (SbmlUnit unit : units) {
+        if (unit.getUnitId().equals(substanceUnits)) {
+          sbmlUnit = unit;
+        }
+      }
+      if (sbmlUnit != null) {
+        species.setSubstanceUnits(sbmlUnit);
+      } else {
+        species.setSubstanceUnits(SbmlUnitType.valueOf(substanceUnits.toUpperCase()));
+      }
     }
     species.setInitialAmount(XmlParser.getNodeAttr("initialAmount", spieciesNode));
     species.setInitialConcentration(XmlParser.getNodeAttr("initialConcentration", spieciesNode));
@@ -196,7 +212,11 @@ public class SpeciesSbmlParser extends AbstractElementXmlParser<CellDesignerSpec
       attributesBuilder.append(" hasOnlySubstanceUnits=\"" + species.hasOnlySubstanceUnits() + "\"");
     }
     if (species.getSubstanceUnits() != null) {
-      attributesBuilder.append(" substanceUnits=\"" + species.getSubstanceUnits().toString().toLowerCase() + "\"");
+      if (species.getSubstanceUnits() instanceof SbmlUnit) {
+        attributesBuilder.append(" substanceUnits=\"" + ((SbmlUnit)species.getSubstanceUnits()).getUnitId().toLowerCase() + "\"");
+      } else {
+        attributesBuilder.append(" substanceUnits=\"" + species.getSubstanceUnits().toString().toLowerCase() + "\"");
+      }
     }
     if (species.getConstant() != null) {
       attributesBuilder.append(" constant=\"" + species.getConstant().toString().toLowerCase() + "\"");
diff --git a/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/structure/CellDesignerSpecies.java b/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/structure/CellDesignerSpecies.java
index 2f162057b66c7d686bbcdad91d81842da1d07c15..35f6b92423cf3873fcc70fad6025929cd29a17e5 100644
--- a/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/structure/CellDesignerSpecies.java
+++ b/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/structure/CellDesignerSpecies.java
@@ -6,6 +6,7 @@ import org.apache.logging.log4j.Logger;
 import lcsb.mapviewer.common.exception.InvalidArgumentException;
 import lcsb.mapviewer.common.exception.NotImplementedException;
 import lcsb.mapviewer.model.map.MiriamData;
+import lcsb.mapviewer.model.map.kinetics.SbmlUnit;
 import lcsb.mapviewer.model.map.kinetics.SbmlUnitType;
 import lcsb.mapviewer.model.map.species.Species;
 import lcsb.mapviewer.model.map.species.field.PositionToCompartment;
@@ -70,7 +71,20 @@ public class CellDesignerSpecies<T extends Species> extends CellDesignerElement<
    */
   private Boolean hypothetical = null;
 
-  private SbmlUnitType substanceUnits;
+  /**
+   * SBML allows to store substanceUnit as either basic SI unit type or complex
+   * unit definition. To map it properly to database we need to separate the type
+   * into two properties. This property is responsible for basic SI unit type.
+   */
+  private SbmlUnitType substanceUnitRawType;
+
+  /**
+   * SBML allows to store substanceUnit as either basic SI unit type or complex
+   * unit definition. To map it properly to database we need to separate the type
+   * into two properties. This property is responsible for complex unit
+   * definition.
+   */
+  private SbmlUnit substanceUnitComlexType;
 
   private Boolean boundaryCondition;
 
@@ -93,7 +107,8 @@ public class CellDesignerSpecies<T extends Species> extends CellDesignerElement<
     this.onlySubstanceUnits = species.onlySubstanceUnits;
     this.homodimer = species.homodimer;
     this.constant = species.constant;
-    this.substanceUnits = species.substanceUnits;
+    this.substanceUnitComlexType = species.substanceUnitComlexType;
+    this.substanceUnitRawType = species.substanceUnitRawType;
     this.boundaryCondition = species.boundaryCondition;
   }
 
@@ -287,7 +302,11 @@ public class CellDesignerSpecies<T extends Species> extends CellDesignerElement<
     if (boundaryCondition != null) {
       result.setBoundaryCondition(boundaryCondition);
     }
-    result.setSubstanceUnits(substanceUnits);
+    if (substanceUnitComlexType != null) {
+      result.setSubstanceUnits(substanceUnitComlexType);
+    } else {
+      result.setSubstanceUnits(substanceUnitRawType);
+    }
     result.setHomodimer(homodimer);
     result.setPositionToCompartment(positionToCompartment);
     result.setHypothetical(hypothetical);
@@ -503,11 +522,21 @@ public class CellDesignerSpecies<T extends Species> extends CellDesignerElement<
   }
 
   public void setSubstanceUnits(SbmlUnitType substanceUnits) {
-    this.substanceUnits = substanceUnits;
+    this.substanceUnitRawType = substanceUnits;
+  }
+
+  public void setSubstanceUnits(SbmlUnit substanceUnits) {
+    this.substanceUnitComlexType = substanceUnits;
   }
 
-  public SbmlUnitType getSubstanceUnit() {
-    return this.substanceUnits;
+  public Object getSubstanceUnit() {
+    if (substanceUnitComlexType != null) {
+      return substanceUnitComlexType;
+    } else if (substanceUnitRawType != null) {
+      return substanceUnitRawType;
+    } else {
+      return null;
+    }
   }
 
   public Boolean isBoundaryCondition() {
diff --git a/converter-CellDesigner/src/test/java/lcsb/mapviewer/converter/model/celldesigner/CellDesignerXmlParserTest.java b/converter-CellDesigner/src/test/java/lcsb/mapviewer/converter/model/celldesigner/CellDesignerXmlParserTest.java
index be028cc32e0977ae977f16aad1ebfd2acd24f4cc..021b121691d9aeefdfc3a58f64b02164a6d1e4b6 100644
--- a/converter-CellDesigner/src/test/java/lcsb/mapviewer/converter/model/celldesigner/CellDesignerXmlParserTest.java
+++ b/converter-CellDesigner/src/test/java/lcsb/mapviewer/converter/model/celldesigner/CellDesignerXmlParserTest.java
@@ -67,6 +67,16 @@ public class CellDesignerXmlParserTest extends CellDesignerTestFunctions {
     assertEquals("sample", model.getName());
   }
 
+  @Test
+  public void testSubstanceUnitAsType() throws Exception {
+    CellDesignerXmlParser parser = new CellDesignerXmlParser();
+    Model model = parser
+        .createModel(new ConverterParams().filename("testFiles/problematic/substance_defined_as_type.xml").sizeAutoAdjust(false));
+    assertNotNull(model);
+    assertNotNull(model.getSpeciesList().get(0).getSubstanceUnits());
+    super.testXmlSerialization(model);
+  }
+
   @Test
   public void testParseTransparency() throws Exception {
     CellDesignerXmlParser parser = new CellDesignerXmlParser();
diff --git a/converter-CellDesigner/src/test/java/lcsb/mapviewer/converter/model/celldesigner/species/SpeciesCollectionXmlParserTest.java b/converter-CellDesigner/src/test/java/lcsb/mapviewer/converter/model/celldesigner/species/SpeciesCollectionXmlParserTest.java
index 8dcfc0e81042f939ad4c66ce8f98fb0c6944d07b..1c1cdcb38b1ba051a7e56e17271441433c4db7f6 100644
--- a/converter-CellDesigner/src/test/java/lcsb/mapviewer/converter/model/celldesigner/species/SpeciesCollectionXmlParserTest.java
+++ b/converter-CellDesigner/src/test/java/lcsb/mapviewer/converter/model/celldesigner/species/SpeciesCollectionXmlParserTest.java
@@ -3,8 +3,7 @@ package lcsb.mapviewer.converter.model.celldesigner.species;
 import static org.junit.Assert.*;
 
 import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.*;
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
@@ -41,7 +40,7 @@ public class SpeciesCollectionXmlParserTest extends CellDesignerTestFunctions {
   @Before
   public void setUp() throws Exception {
     elements = new CellDesignerElementCollection();
-    parser = new SpeciesCollectionXmlParser(elements);
+    parser = new SpeciesCollectionXmlParser(elements, new HashSet<>());
   }
 
   @After
@@ -292,7 +291,7 @@ public class SpeciesCollectionXmlParserTest extends CellDesignerTestFunctions {
 
     // this is only for test coverage purpose
 
-    SpeciesCollectionXmlParser parser = new SpeciesCollectionXmlParser(elements);
+    SpeciesCollectionXmlParser parser = new SpeciesCollectionXmlParser(elements, new HashSet<>());
     Field field = SpeciesCollectionXmlParser.class.getDeclaredField("helpParser");
     field.setAccessible(true);
     try {
diff --git a/converter-CellDesigner/src/test/java/lcsb/mapviewer/converter/model/celldesigner/species/SpeciesSbmlParserTest.java b/converter-CellDesigner/src/test/java/lcsb/mapviewer/converter/model/celldesigner/species/SpeciesSbmlParserTest.java
index 191980708730fe87dc2e5a735fcf8b9393b465d3..69f57b7473f3e5cca1ead7bc33ae806cd92e57e1 100644
--- a/converter-CellDesigner/src/test/java/lcsb/mapviewer/converter/model/celldesigner/species/SpeciesSbmlParserTest.java
+++ b/converter-CellDesigner/src/test/java/lcsb/mapviewer/converter/model/celldesigner/species/SpeciesSbmlParserTest.java
@@ -3,6 +3,7 @@ package lcsb.mapviewer.converter.model.celldesigner.species;
 import static org.junit.Assert.*;
 
 import java.io.StringReader;
+import java.util.HashSet;
 
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
@@ -45,7 +46,7 @@ public class SpeciesSbmlParserTest extends CellDesignerTestFunctions {
   @Before
   public void setUp() throws Exception {
     elements = new CellDesignerElementCollection();
-    parser = new SpeciesSbmlParser(elements);
+    parser = new SpeciesSbmlParser(elements, new HashSet<>());
   }
 
   @After
@@ -269,7 +270,7 @@ public class SpeciesSbmlParserTest extends CellDesignerTestFunctions {
     InternalModelSpeciesData modelData = new InternalModelSpeciesData();
     modelData.updateSpecies(gene, "");
 
-    SpeciesSbmlParser complexParser = new SpeciesSbmlParser(elements);
+    SpeciesSbmlParser complexParser = new SpeciesSbmlParser(elements, new HashSet<>());
     CellDesignerGene oldGene = new CellDesignerGene();
     oldGene.setElementId("s5916");
     oldGene.setName("Ptgr1");
diff --git a/converter-CellDesigner/testFiles/problematic/substance_defined_as_type.xml b/converter-CellDesigner/testFiles/problematic/substance_defined_as_type.xml
new file mode 100644
index 0000000000000000000000000000000000000000..cba3c6f7d241ff8f28340fe4040d68a9223f117e
--- /dev/null
+++ b/converter-CellDesigner/testFiles/problematic/substance_defined_as_type.xml
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<sbml xmlns="http://www.sbml.org/sbml/level2/version4" xmlns:celldesigner="http://www.sbml.org/2001/ns/celldesigner" level="2" version="4">
+<model metaid="CellDesigner_Ver_42_Components" id="CellDesigner_Ver_42_Components" sboTerm="SBO:0000231">
+<notes>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title/>
+</head>
+<body>This is a sample file for CellDesigner 4.2, describing the graphical notation.
+http://celldesigner.org
+</body>
+</html>
+</notes>
+<annotation>
+<celldesigner:extension>
+<celldesigner:modelVersion>4.0</celldesigner:modelVersion>
+<celldesigner:modelDisplay sizeX="1700" sizeY="1200"/>
+<celldesigner:listOfCompartmentAliases/>
+<celldesigner:listOfComplexSpeciesAliases/>
+<celldesigner:listOfSpeciesAliases>
+<celldesigner:speciesAlias id="a1" species="s198">
+<celldesigner:activity>inactive</celldesigner:activity>
+<celldesigner:bounds x="123.25" y="47.20381061236179" w="80.0" h="40.0"/>
+<celldesigner:font size="12"/>
+<celldesigner:view state="usual"/>
+<celldesigner:usualView>
+<celldesigner:boxSize width="80.0" height="40.0"/>
+<celldesigner:singleLine width="1.0"/>
+<celldesigner:paint color="ffccffcc" scheme="Color"/>
+</celldesigner:usualView>
+<celldesigner:briefView>
+<celldesigner:innerPosition x="0.0" y="0.0"/>
+<celldesigner:boxSize width="80.0" height="60.0"/>
+<celldesigner:singleLine width="1.0"/>
+<celldesigner:paint color="3fff0000" scheme="Color"/>
+</celldesigner:briefView>
+<celldesigner:info state="empty" angle="-1.5707963267948966"/>
+</celldesigner:speciesAlias>
+</celldesigner:listOfSpeciesAliases>
+<celldesigner:listOfGroups/>
+<celldesigner:listOfProteins>
+<celldesigner:protein id="p1" name="Protein" type="GENERIC"/>
+</celldesigner:listOfProteins>
+<celldesigner:listOfGenes/>
+<celldesigner:listOfRNAs/>
+<celldesigner:listOfAntisenseRNAs/>
+<celldesigner:listOfLayers>
+<celldesigner:layer id="1" name="comment" locked="false" visible="true"/>
+</celldesigner:listOfLayers>
+<celldesigner:listOfBlockDiagrams/>
+</celldesigner:extension>
+<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:vCard="http://www.w3.org/2001/vcard-rdf/3.0#" xmlns:bqbiol="http://biomodels.net/biology-qualifiers/" xmlns:bqmodel="http://biomodels.net/model-qualifiers/">
+<rdf:Description rdf:about="#CellDesigner_Ver_42_Components">
+<dc:creator>
+<rdf:Bag>
+<rdf:li rdf:parseType="Resource">
+<vCard:EMAIL>info@celldesigner.org</vCard:EMAIL>
+<vCard:ORG rdf:parseType="Resource">
+<vCard:Orgname>The Systems Biology Institute</vCard:Orgname>
+</vCard:ORG>
+</rdf:li>
+</rdf:Bag>
+</dc:creator>
+<dcterms:created rdf:parseType="Resource">
+<dcterms:W3CDTF>2009-07-13T20:39:30Z</dcterms:W3CDTF>
+</dcterms:created>
+<dcterms:modified rdf:parseType="Resource">
+<dcterms:W3CDTF>2011-03-09T19:11:39Z</dcterms:W3CDTF>
+</dcterms:modified>
+</rdf:Description>
+</rdf:RDF>
+</annotation>
+<listOfUnitDefinitions>
+<unitDefinition metaid="substance" id="substance" name="substance">
+<listOfUnits>
+<unit metaid="CDMT00121" kind="mole"/>
+</listOfUnits>
+</unitDefinition>
+<unitDefinition metaid="volume" id="volume" name="volume">
+<listOfUnits>
+<unit metaid="CDMT00122" kind="litre"/>
+</listOfUnits>
+</unitDefinition>
+<unitDefinition metaid="area" id="area" name="area">
+<listOfUnits>
+<unit metaid="CDMT00123" kind="metre" exponent="2"/>
+</listOfUnits>
+</unitDefinition>
+<unitDefinition metaid="length" id="length" name="length">
+<listOfUnits>
+<unit metaid="CDMT00124" kind="metre"/>
+</listOfUnits>
+</unitDefinition>
+<unitDefinition metaid="time" id="time" name="time">
+<listOfUnits>
+<unit metaid="CDMT00125" kind="second"/>
+</listOfUnits>
+</unitDefinition>
+</listOfUnitDefinitions>
+<listOfCompartments>
+<compartment metaid="default" id="default" size="1" units="volume" sboTerm="SBO:0000240"/>
+</listOfCompartments>
+<listOfSpecies>
+<species metaid="s198" id="s198" name="Protein" compartment="default" initialAmount="0" substanceUnits="substance" sboTerm="SBO:0000252">
+<notes>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title/>
+</head>
+<body>You can input the Protein Notes here.
+</body>
+</html>
+</notes>
+<annotation>
+<celldesigner:extension>
+<celldesigner:positionToCompartment>inside</celldesigner:positionToCompartment>
+<celldesigner:speciesIdentity>
+<celldesigner:class>PROTEIN</celldesigner:class>
+<celldesigner:proteinReference>p1</celldesigner:proteinReference>
+</celldesigner:speciesIdentity>
+</celldesigner:extension>
+</annotation>
+</species>
+</listOfSpecies>
+</model>
+</sbml>
diff --git a/converter/src/main/java/lcsb/mapviewer/converter/annotation/XmlAnnotationParser.java b/converter/src/main/java/lcsb/mapviewer/converter/annotation/XmlAnnotationParser.java
index 4c811618c5ef54550290dcaa292a9faf0018a8a7..c5fda22de6cfac76ea539d8167f3755d6cda098f 100644
--- a/converter/src/main/java/lcsb/mapviewer/converter/annotation/XmlAnnotationParser.java
+++ b/converter/src/main/java/lcsb/mapviewer/converter/annotation/XmlAnnotationParser.java
@@ -320,8 +320,12 @@ public class XmlAnnotationParser {
     result.append("<rdf:Bag>\n");
     result.append("<rdf:li rdf:parseType=\"Resource\">\n");
     result.append("<vCard:N rdf:parseType=\"Resource\">\n");
-    result.append("<vCard:Family>" + XmlParser.escapeXml(author.getLastName()) + "</vCard:Family>\n");
-    result.append("<vCard:Given>" + XmlParser.escapeXml(author.getFirstName()) + "</vCard:Given>\n");
+    if (author.getLastName() != null) {
+      result.append("<vCard:Family>" + XmlParser.escapeXml(author.getLastName()) + "</vCard:Family>\n");
+    }
+    if (author.getFirstName() != null) {
+      result.append("<vCard:Given>" + XmlParser.escapeXml(author.getFirstName()) + "</vCard:Given>\n");
+    }
     result.append("</vCard:N>\n");
 
     if (author.getEmail() != null && !author.getEmail().trim().isEmpty()) {
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/species/Species.java b/model/src/main/java/lcsb/mapviewer/model/map/species/Species.java
index 22b065e41aa5f740ef1177fbb44d2e46e115744b..19eb0d2e4b88567723e5fea893e6483cea81f641 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/species/Species.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/species/Species.java
@@ -10,6 +10,7 @@ import org.apache.logging.log4j.Logger;
 import org.hibernate.annotations.Cascade;
 import org.hibernate.annotations.CascadeType;
 
+import lcsb.mapviewer.model.map.kinetics.SbmlUnit;
 import lcsb.mapviewer.model.map.kinetics.SbmlUnitType;
 import lcsb.mapviewer.model.map.species.field.PositionToCompartment;
 import lcsb.mapviewer.model.map.species.field.UniprotRecord;
@@ -120,8 +121,23 @@ public abstract class Species extends Element {
 
   private Boolean constant = false;
 
+  /**
+   * SBML allows to store substanceUnit as either basic SI unit type or complex
+   * unit definition. To map it properly to database we need to separate the type
+   * into two properties. This property is responsible for basic SI unit type.
+   */
   @Enumerated(EnumType.STRING)
-  private SbmlUnitType substanceUnits;
+  private SbmlUnitType substanceUnitRawType;
+
+  /**
+   * SBML allows to store substanceUnit as either basic SI unit type or complex
+   * unit definition. To map it properly to database we need to separate the type
+   * into two properties. This property is responsible for complex unit
+   * definition.
+   */
+  @ManyToOne
+  @Cascade({ CascadeType.ALL })
+  private SbmlUnit substanceUnitComlexType;
 
   /**
    * Constructor that set element identifier.
@@ -171,7 +187,8 @@ public abstract class Species extends Element {
     hypothetical = original.getHypothetical();
     boundaryCondition = original.getBoundaryCondition();
     constant = original.getConstant();
-    substanceUnits = original.getSubstanceUnits();
+    substanceUnitComlexType = original.substanceUnitComlexType;
+    substanceUnitRawType = original.substanceUnitRawType;
 
     uniprots = original.getUniprots();
 
@@ -476,12 +493,22 @@ public abstract class Species extends Element {
     this.constant = constant;
   }
 
-  public SbmlUnitType getSubstanceUnits() {
-    return substanceUnits;
+  public Object getSubstanceUnits() {
+    if (this.substanceUnitRawType != null) {
+      return this.substanceUnitRawType;
+    } else {
+      return this.substanceUnitComlexType;
+    }
   }
 
   public void setSubstanceUnits(SbmlUnitType substanceUnits) {
-    this.substanceUnits = substanceUnits;
+    this.substanceUnitRawType = substanceUnits;
+    this.substanceUnitComlexType = null;
+  }
+
+  public void setSubstanceUnits(SbmlUnit substanceUnits) {
+    this.substanceUnitComlexType = substanceUnits;
+    this.substanceUnitRawType = null;
   }
 
 }
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/species/SpeciesComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/species/SpeciesComparator.java
index 5aed73eaf242cd8f0bc0068906b23517c73a0254..aad1de4fb320d9fa9cfa9337a0aa28495d3c0574 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/species/SpeciesComparator.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/species/SpeciesComparator.java
@@ -6,7 +6,7 @@ import org.apache.logging.log4j.Logger;
 import lcsb.mapviewer.common.Comparator;
 import lcsb.mapviewer.common.Configuration;
 import lcsb.mapviewer.common.comparator.*;
-import lcsb.mapviewer.model.map.kinetics.SbmlUnitType;
+import lcsb.mapviewer.model.map.kinetics.*;
 
 /**
  * Comparator class used for comparing {@link Species} objects.
@@ -145,11 +145,32 @@ public class SpeciesComparator extends Comparator<Species> {
       return booleanComparator.compare(arg0.isBoundaryCondition(), arg1.isBoundaryCondition());
     }
 
-    EnumComparator<SbmlUnitType> enumComparator = new EnumComparator<>();
-    if (enumComparator.compare(arg0.getSubstanceUnits(), arg1.getSubstanceUnits()) != 0) {
+    EnumComparator<SbmlUnitType> unitTypeComparator = new EnumComparator<>();
+    SbmlUnitComparator unitComparator = new SbmlUnitComparator();
+    SbmlUnitType sbmlUnitType1 = null;
+    SbmlUnitType sbmlUnitType2 = null;
+
+    SbmlUnit sbmlUnit1 = null;
+    SbmlUnit sbmlUnit2 = null;
+    if (arg0.getSubstanceUnits() instanceof SbmlUnit) {
+      sbmlUnit1 = (SbmlUnit) arg0.getSubstanceUnits();
+    } else {
+      sbmlUnitType1 = (SbmlUnitType) arg0.getSubstanceUnits();
+    }
+    if (arg1.getSubstanceUnits() instanceof SbmlUnit) {
+      sbmlUnit2 = (SbmlUnit) arg1.getSubstanceUnits();
+    } else {
+      sbmlUnitType2 = (SbmlUnitType) arg1.getSubstanceUnits();
+    }
+    if (unitTypeComparator.compare(sbmlUnitType1, sbmlUnitType2) != 0) {
+      logger.debug(
+          "SubstanceUnits different: \"" + arg0.getSubstanceUnits() + "\", \"" + arg1.getSubstanceUnits() + "\"");
+      return unitTypeComparator.compare(sbmlUnitType1, sbmlUnitType2);
+    }
+    if (unitComparator.compare(sbmlUnit1, sbmlUnit2) != 0) {
       logger.debug(
           "SubstanceUnits different: \"" + arg0.getSubstanceUnits() + "\", \"" + arg1.getSubstanceUnits() + "\"");
-      return enumComparator.compare(arg0.getSubstanceUnits(), arg1.getSubstanceUnits());
+      return unitComparator.compare(sbmlUnit1, sbmlUnit2);
     }
 
     return 0;
diff --git a/persist/src/main/resources/db/migration/14.0.3/V14.0.1.20191016__substance_unit_complex_type.sql b/persist/src/main/resources/db/migration/14.0.3/V14.0.1.20191016__substance_unit_complex_type.sql
new file mode 100644
index 0000000000000000000000000000000000000000..48134aea4e6c1fa9387c84954191ce3fc96dc35a
--- /dev/null
+++ b/persist/src/main/resources/db/migration/14.0.3/V14.0.1.20191016__substance_unit_complex_type.sql
@@ -0,0 +1,3 @@
+alter table element_table add column substance_unit_comlex_type_id integer;
+alter table element_table add foreign key (substance_unit_comlex_type_id) references sbml_unit_table(id);
+alter table element_table rename column substance_units to substance_unit_raw_type;