From db9da5829f0c823b3e6788c774210f429ed375e0 Mon Sep 17 00:00:00 2001
From: Piotr Gawron <piotr.gawron@uni.lu>
Date: Mon, 5 Feb 2018 10:06:45 +0100
Subject: [PATCH] simple export of reaction kinetics

---
 .../java/lcsb/mapviewer/common/XmlParser.java |  2 +-
 .../reaction/KineticsXmlParser.java           |  6 +-
 .../reaction/ReactionFromXml.java             | 40 ++++++++---
 .../model/sbml/SbmlBioEntityExporter.java     |  3 +-
 .../model/sbml/SbmlElementParser.java         |  1 +
 .../converter/model/sbml/SbmlExporter.java    |  5 +-
 .../converter/model/sbml/SbmlParser.java      |  1 +
 .../model/sbml/SbmlReactionExporter.java      | 68 ++++++++++++++++++-
 .../model/sbml/SbmlReactionParser.java        |  1 +
 .../model/sbml/SbmlSpeciesParser.java         |  5 +-
 .../model/sbml/SbmlUnitExporter.java          | 30 ++++++++
 .../model/sbml/GenericSbmlParserTest.java     |  8 +--
 .../sbml/GenericSbmlToXmlParserTest.java      |  2 +-
 .../model/map/InconsistentModelException.java | 30 ++++----
 .../model/map/compartment/Compartment.java    |  6 ++
 .../map/reaction/ReactionComparator.java      |  2 +
 16 files changed, 172 insertions(+), 38 deletions(-)
 create mode 100644 converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlUnitExporter.java

diff --git a/commons/src/main/java/lcsb/mapviewer/common/XmlParser.java b/commons/src/main/java/lcsb/mapviewer/common/XmlParser.java
index d7ac52a290..66be945a96 100644
--- a/commons/src/main/java/lcsb/mapviewer/common/XmlParser.java
+++ b/commons/src/main/java/lcsb/mapviewer/common/XmlParser.java
@@ -8,6 +8,7 @@ import java.io.InputStream;
 import java.io.StringReader;
 import java.io.StringWriter;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.List;
 
 import javax.xml.parsers.DocumentBuilder;
@@ -374,5 +375,4 @@ public class XmlParser {
     }
     return result;
   }
-
 }
diff --git a/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/reaction/KineticsXmlParser.java b/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/reaction/KineticsXmlParser.java
index b1ae5738ed..e77e87b9d8 100644
--- a/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/reaction/KineticsXmlParser.java
+++ b/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/reaction/KineticsXmlParser.java
@@ -63,7 +63,11 @@ public class KineticsXmlParser extends XmlParser {
       elementsUsedInKinetics.add(element);
     }
     result.addArguments(elementsUsedInKinetics);
-    result.setDefinition(super.nodeToString(mathNode, true));
+    
+    String definition = super.nodeToString(mathNode, true);
+    definition = definition.replace(" xmlns=\"http://www.sbml.org/sbml/level2/version4\"", "");
+    definition = definition.replace("<math>", "<math xmlns=\"http://www.w3.org/1998/Math/MathML\">");
+    result.setDefinition(definition);
 
     return result;
   }
diff --git a/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/reaction/ReactionFromXml.java b/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/reaction/ReactionFromXml.java
index c0a3ef113e..cbf7f44399 100644
--- a/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/reaction/ReactionFromXml.java
+++ b/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/reaction/ReactionFromXml.java
@@ -225,20 +225,40 @@ public class ReactionFromXml extends XmlParser {
     for (Node node : elementNodes) {
       String speciesId = super.getNodeAttr("species", node);
       String aliasId = super.getNodeAttr("alias", node);
-      Element element = model.getElementByElementId(aliasId);
-      result.put(speciesId, element);
-
-      Compartment compartment = element.getCompartment();
-      if (compartment != null) {
-        // in kinetics we can have reference to compartment (so we need to find SBML
-        // compartment id)
-        String compartmentId = elements.getElementByElementId(compartment.getElementId()).getElementId();
-        result.put(compartmentId, compartment);
-      }
+      addElementMapping(model, result, speciesId, aliasId);
+    }
+
+    for (Node node : super.getAllNotNecessirellyDirectChild("celldesigner:reactantLink", annotationNode)) {
+      String speciesId = super.getNodeAttr("reactant", node);
+      String aliasId = super.getNodeAttr("alias", node);
+      addElementMapping(model, result, speciesId, aliasId);
+    }
+    
+    for (Node node : super.getAllNotNecessirellyDirectChild("celldesigner:productLink", annotationNode)) {
+      String speciesId = super.getNodeAttr("product", node);
+      String aliasId = super.getNodeAttr("alias", node);
+      addElementMapping(model, result, speciesId, aliasId);
     }
+    
     return result;
   }
 
+  private void addElementMapping(Model model, Map<String, Element> result, String speciesId, String aliasId) {
+    Element element = model.getElementByElementId(aliasId);
+    result.put(speciesId, element);
+    addCompartmentMapping(result, element);
+  }
+
+  private void addCompartmentMapping(Map<String, Element> result, Element element) {
+    Compartment compartment = element.getCompartment();
+    if (compartment != null) {
+      // in kinetics we can have reference to compartment (so we need to find SBML
+      // compartment id)
+      String compartmentId = elements.getElementByElementId(compartment.getElementId()).getElementId();
+      result.put(compartmentId, compartment);
+    }
+  }
+
   /**
    * Parses reaction annotation node and update reaction.
    * 
diff --git a/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlBioEntityExporter.java b/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlBioEntityExporter.java
index 97f1c528a8..b864632fea 100644
--- a/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlBioEntityExporter.java
+++ b/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlBioEntityExporter.java
@@ -11,11 +11,12 @@ import org.sbml.jsbml.Model;
 import org.sbml.jsbml.ext.layout.AbstractReferenceGlyph;
 import org.sbml.jsbml.ext.layout.Layout;
 
+import lcsb.mapviewer.common.XmlParser;
 import lcsb.mapviewer.common.exception.InvalidStateException;
 import lcsb.mapviewer.model.map.BioEntity;
 import lcsb.mapviewer.model.map.InconsistentModelException;
 
-public abstract class SbmlBioEntityExporter<T extends BioEntity, S extends org.sbml.jsbml.AbstractNamedSBase> {
+public abstract class SbmlBioEntityExporter<T extends BioEntity, S extends org.sbml.jsbml.AbstractNamedSBase> extends XmlParser {
   Logger logger = Logger.getLogger(SbmlBioEntityExporter.class);
 
   Layout layout;
diff --git a/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlElementParser.java b/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlElementParser.java
index 5987e77f0c..7cd9676e7a 100644
--- a/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlElementParser.java
+++ b/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlElementParser.java
@@ -15,6 +15,7 @@ import org.sbml.jsbml.ext.layout.Layout;
 
 import lcsb.mapviewer.common.Pair;
 import lcsb.mapviewer.converter.InvalidInputDataExecption;
+import lcsb.mapviewer.model.map.compartment.Compartment;
 import lcsb.mapviewer.model.map.species.Element;
 
 public abstract class SbmlElementParser<T extends org.sbml.jsbml.Symbol> extends SbmlBioEntityParser {
diff --git a/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlExporter.java b/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlExporter.java
index cc105d8a04..1b159bd344 100644
--- a/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlExporter.java
+++ b/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlExporter.java
@@ -25,10 +25,13 @@ public class SbmlExporter {
     SbmlCompartmentExporter compartmentExporter = new SbmlCompartmentExporter(layout, model);
     SbmlBioEntityExporter<Species, org.sbml.jsbml.Species> speciesExporter = new SbmlSpeciesExporter(layout, model,
         compartmentExporter);
-    SbmlReactionExporter reactionExporter = new SbmlReactionExporter(layout, model, speciesExporter);
+    SbmlReactionExporter reactionExporter = new SbmlReactionExporter(layout, model, speciesExporter, compartmentExporter);
+    SbmlUnitExporter unitExporter = new SbmlUnitExporter(model);
     compartmentExporter.exportElements(result);
     speciesExporter.exportElements(result);
     reactionExporter.exportElements(result);
+    unitExporter.exportUnits(result);
+
 
     ByteArrayOutputStream stream = new ByteArrayOutputStream();
     SBMLWriter.write(doc, stream, "minerva", "1.0");
diff --git a/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlParser.java b/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlParser.java
index 5d17c13bd7..07429d9d30 100644
--- a/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlParser.java
+++ b/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlParser.java
@@ -226,6 +226,7 @@ public class SbmlParser implements IConverter {
       throws ConverterException, InconsistentModelException, IOException {
     File file = new File(filePath);
     String exportedString = toXml(model);
+    logger.debug(exportedString);
     FileWriter fileWriter = new FileWriter(file);
     fileWriter.write(exportedString);
     fileWriter.flush();
diff --git a/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlReactionExporter.java b/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlReactionExporter.java
index a563670114..02ec6cbdf8 100644
--- a/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlReactionExporter.java
+++ b/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlReactionExporter.java
@@ -7,6 +7,9 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.log4j.Logger;
+import org.sbml.jsbml.ASTNode;
+import org.sbml.jsbml.KineticLaw;
+import org.sbml.jsbml.LocalParameter;
 import org.sbml.jsbml.SimpleSpeciesReference;
 import org.sbml.jsbml.Species;
 import org.sbml.jsbml.SpeciesReference;
@@ -18,26 +21,35 @@ import org.sbml.jsbml.ext.layout.Point;
 import org.sbml.jsbml.ext.layout.ReactionGlyph;
 import org.sbml.jsbml.ext.layout.SpeciesReferenceGlyph;
 import org.sbml.jsbml.ext.layout.SpeciesReferenceRole;
+import org.sbml.jsbml.text.parser.ParseException;
+import org.w3c.dom.Node;
 
 import lcsb.mapviewer.common.Configuration;
+import lcsb.mapviewer.common.exception.InvalidXmlSchemaException;
 import lcsb.mapviewer.model.map.InconsistentModelException;
+import lcsb.mapviewer.model.map.compartment.Compartment;
+import lcsb.mapviewer.model.map.kinetics.SbmlKinetics;
+import lcsb.mapviewer.model.map.kinetics.SbmlParameter;
 import lcsb.mapviewer.model.map.modifier.Inhibition;
-import lcsb.mapviewer.model.map.modifier.Modulation;
 import lcsb.mapviewer.model.map.modifier.Trigger;
 import lcsb.mapviewer.model.map.reaction.Modifier;
 import lcsb.mapviewer.model.map.reaction.Product;
 import lcsb.mapviewer.model.map.reaction.Reactant;
 import lcsb.mapviewer.model.map.reaction.Reaction;
 import lcsb.mapviewer.model.map.reaction.ReactionNode;
+import lcsb.mapviewer.model.map.species.Element;
 
 public class SbmlReactionExporter extends SbmlBioEntityExporter<Reaction, org.sbml.jsbml.Reaction> {
   Logger logger = Logger.getLogger(SbmlReactionExporter.class);
   private SbmlBioEntityExporter<lcsb.mapviewer.model.map.species.Species, Species> speciesExporter;
+  private SbmlBioEntityExporter<Compartment, org.sbml.jsbml.Compartment> compartmentExporter;
 
   public SbmlReactionExporter(Layout layout, lcsb.mapviewer.model.map.model.Model minervaModel,
-      SbmlBioEntityExporter<lcsb.mapviewer.model.map.species.Species, Species> speciesExporter) {
+      SbmlBioEntityExporter<lcsb.mapviewer.model.map.species.Species, Species> speciesExporter,
+      SbmlBioEntityExporter<lcsb.mapviewer.model.map.compartment.Compartment, org.sbml.jsbml.Compartment> compartmentExporter) {
     super(layout, minervaModel);
     this.speciesExporter = speciesExporter;
+    this.compartmentExporter = compartmentExporter;
   }
 
   Map<ReactionNode, SimpleSpeciesReference> speciesReferenceByReactionNode = new HashMap<>();
@@ -66,9 +78,61 @@ public class SbmlReactionExporter extends SbmlBioEntityExporter<Reaction, org.sb
       SimpleSpeciesReference speciesReference = result.createModifier(sbmlSymbol);
       speciesReferenceByReactionNode.put(modifier, speciesReference);
     }
+    if (reaction.getKinetics() != null) {
+      result.setKineticLaw(createKineticLaw(reaction));
+    }
     return result;
   }
 
+  private KineticLaw createKineticLaw(Reaction reaction) throws InconsistentModelException {
+    SbmlKinetics kinetics = reaction.getKinetics();
+    KineticLaw result = new KineticLaw();
+    for (SbmlParameter minervaParameter : kinetics.getParameters()) {
+      if (minervaModel.getParameterById(minervaParameter.getElementId()) == null) {
+        LocalParameter parameter = new LocalParameter();
+        parameter.setId(minervaParameter.getElementId());
+        parameter.setName(minervaParameter.getName());
+        parameter.setValue(minervaParameter.getValue());
+        parameter.setUnits(minervaParameter.getUnits().getUnitId());
+        result.addLocalParameter(parameter);
+      }
+    }
+
+    try {
+      Node node = super.getXmlDocumentFromString(kinetics.getDefinition());
+      for (Node ciNode : super.getAllNotNecessirellyDirectChild("ci", node)) {
+        String id = super.getNodeValue(ciNode).trim();
+        Element element = minervaModel.getElementByElementId(id);
+        if (element != null) {
+          String sbmlId = null;
+          Species species= speciesExporter.sbmlElementByElementId.get(id);
+          if (species !=null) {
+            sbmlId = species.getId();
+          } else {
+            sbmlId = compartmentExporter.sbmlElementByElementId.get(id).getId();
+          }
+          
+          logger.debug(id);
+          logger.debug(element.getElementId());
+          logger.debug(speciesExporter);
+          logger.debug(speciesExporter.sbmlElementByElementId);
+          logger.debug(speciesExporter.sbmlElementByElementId.get(element.getElementId()));
+          ciNode.setTextContent(sbmlId);
+        }
+      }
+      String definition = super.nodeToString(node);
+      definition = definition.replace(" xmlns=\"http://www.sbml.org/sbml/level2/version4\"", "");
+      definition = definition.replace("<math>", "<math xmlns=\"http://www.w3.org/1998/Math/MathML\">");
+      logger.debug(definition);
+      result.setMath(ASTNode.parseMathML(definition));
+      logger.debug(result.getMathMLString());
+      return result;
+    } catch (InvalidXmlSchemaException e) {
+      throw new InconsistentModelException(e);
+    }
+
+  }
+
   private String getReactionId(Reaction reaction) {
     int separatorIndex = reaction.getElementId().indexOf("__");
     if (separatorIndex > 0) {
diff --git a/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlReactionParser.java b/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlReactionParser.java
index 0f91b7a80c..cceec32e95 100644
--- a/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlReactionParser.java
+++ b/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlReactionParser.java
@@ -305,6 +305,7 @@ public class SbmlReactionParser extends SbmlBioEntityParser {
         elementsUsedInKinetics.add(element);
       }
       result.addArguments(elementsUsedInKinetics);
+      result.setDefinition(super.nodeToString(node));
     } catch (InvalidXmlSchemaException e) {
       throw new InvalidInputDataExecption(e);
     }
diff --git a/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlSpeciesParser.java b/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlSpeciesParser.java
index 15b76f37b1..1a9826c4e3 100644
--- a/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlSpeciesParser.java
+++ b/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlSpeciesParser.java
@@ -40,6 +40,9 @@ public class SbmlSpeciesParser extends SbmlElementParser<org.sbml.jsbml.Species>
     try {
       Species result = clazz.getConstructor(String.class).newInstance(species.getId());
       assignBioEntityData(species, result);
+      if (layout == null) {
+        assignCompartment(result, species.getCompartment());
+      }
       return result;
     } catch (SecurityException | NoSuchMethodException | InstantiationException | IllegalAccessException
         | IllegalArgumentException | InvocationTargetException e) {
@@ -67,7 +70,7 @@ public class SbmlSpeciesParser extends SbmlElementParser<org.sbml.jsbml.Species>
 
   private void assignCompartment(Element element, String compartmentId) {
     Compartment compartment = minervaModel.getElementByElementId(compartmentId);
-    if (compartment == null) {
+    if (compartment == null && layout != null) {
       List<Compartment> compartments = new ArrayList<>();
       for (CompartmentGlyph glyph : layout.getListOfCompartmentGlyphs()) {
         if (glyph.getCompartment().equals(compartmentId)) {
diff --git a/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlUnitExporter.java b/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlUnitExporter.java
new file mode 100644
index 0000000000..27e2fa310d
--- /dev/null
+++ b/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlUnitExporter.java
@@ -0,0 +1,30 @@
+package lcsb.mapviewer.converter.model.sbml;
+
+import org.apache.log4j.Logger;
+import org.sbml.jsbml.UnitDefinition;
+
+import lcsb.mapviewer.model.map.kinetics.SbmlUnit;
+import lcsb.mapviewer.model.map.model.Model;
+
+public class SbmlUnitExporter {
+  Logger logger = Logger.getLogger(SbmlUnitExporter.class);
+  private Model minervaModel;
+
+  public SbmlUnitExporter(lcsb.mapviewer.model.map.model.Model minervaModel) {
+    this.minervaModel = minervaModel;
+  }
+
+  public void exportUnits(org.sbml.jsbml.Model result) {
+    for (SbmlUnit unit : minervaModel.getUnits()) {
+      result.addUnitDefinition(createUnitDefinition(unit));
+    }
+  }
+
+  private UnitDefinition createUnitDefinition(SbmlUnit unit) {
+    UnitDefinition result = new UnitDefinition();
+    result.setId(unit.getUnitId());
+    result.setName(unit.getName());
+    return result;
+  }
+
+}
diff --git a/converter-sbml/src/test/java/lcsb/mapviewer/converter/model/sbml/GenericSbmlParserTest.java b/converter-sbml/src/test/java/lcsb/mapviewer/converter/model/sbml/GenericSbmlParserTest.java
index 9266510347..026f607a24 100644
--- a/converter-sbml/src/test/java/lcsb/mapviewer/converter/model/sbml/GenericSbmlParserTest.java
+++ b/converter-sbml/src/test/java/lcsb/mapviewer/converter/model/sbml/GenericSbmlParserTest.java
@@ -7,7 +7,6 @@ import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.PrintWriter;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
@@ -60,7 +59,7 @@ public class GenericSbmlParserTest {
   @Test
   public void createModelTest() throws Exception {
     try {
-      String dir = Files.createTempDirectory("sbgn-temp-images-dir").toFile().getAbsolutePath();
+      String dir = Files.createTempDirectory("sbml-temp-images-dir").toFile().getAbsolutePath();
 
       IConverter converter = new SbmlParser();
 
@@ -80,11 +79,6 @@ public class GenericSbmlParserTest {
       CellDesignerXmlParser cellDesignerXmlParser = new CellDesignerXmlParser();
       String xmlString = cellDesignerXmlParser.toXml(model);
 
-      String cellDesignerFilePath = pathWithouExtension.concat("_CD.xml");
-      PrintWriter out = new PrintWriter(cellDesignerFilePath);
-      out.print(xmlString);
-      out.close();
-
       InputStream is = new ByteArrayInputStream(xmlString.getBytes("UTF-8"));
 
       Model model2 = cellDesignerXmlParser.createModel(new ConverterParams().inputStream(is).sizeAutoAdjust(false));
diff --git a/converter-sbml/src/test/java/lcsb/mapviewer/converter/model/sbml/GenericSbmlToXmlParserTest.java b/converter-sbml/src/test/java/lcsb/mapviewer/converter/model/sbml/GenericSbmlToXmlParserTest.java
index 65211af194..7fbdd583ff 100644
--- a/converter-sbml/src/test/java/lcsb/mapviewer/converter/model/sbml/GenericSbmlToXmlParserTest.java
+++ b/converter-sbml/src/test/java/lcsb/mapviewer/converter/model/sbml/GenericSbmlToXmlParserTest.java
@@ -59,7 +59,7 @@ public class GenericSbmlToXmlParserTest {
           + filePath.getFileName().toString().substring(0, filePath.getFileName().toString().indexOf(".xml"));
       String xmlFilePath = pathWithouExtension.concat(".xml");
       converter.exportModelToFile(model, xmlFilePath);
-
+      
       Model model2 = converter.createModel(new ConverterParams().filename(xmlFilePath));
       model2.setName(null);
 
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/InconsistentModelException.java b/model/src/main/java/lcsb/mapviewer/model/map/InconsistentModelException.java
index 2b339c01e9..a823e1bf11 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/InconsistentModelException.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/InconsistentModelException.java
@@ -7,18 +7,22 @@ package lcsb.mapviewer.model.map;
  * 
  */
 public class InconsistentModelException extends Exception {
-	/**
-	 * 
-	 */
-	private static final long	serialVersionUID	= 1L;
+  /**
+   * 
+   */
+  private static final long serialVersionUID = 1L;
 
-	/**
-	 * Default constructor with a message passed in the argument.
-	 * 
-	 * @param message
-	 *          text message of this exception
-	 */
-	public InconsistentModelException(String message) {
-		super(message);
-	}
+  /**
+   * Default constructor with a message passed in the argument.
+   * 
+   * @param message
+   *          text message of this exception
+   */
+  public InconsistentModelException(String message) {
+    super(message);
+  }
+
+  public InconsistentModelException(Exception e) {
+    super(e);
+  }
 }
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/compartment/Compartment.java b/model/src/main/java/lcsb/mapviewer/model/map/compartment/Compartment.java
index b06a1b5dd4..bfba815afd 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/compartment/Compartment.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/compartment/Compartment.java
@@ -395,4 +395,10 @@ public class Compartment extends Element {
     return "Compartment";
   }
 
+  public void removeElements(Set<Element> elements) {
+    for (Element element : elements) {
+      removeElement(element);
+    }
+  }
+
 }
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/reaction/ReactionComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/reaction/ReactionComparator.java
index eb812a44ed..856ed07348 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/reaction/ReactionComparator.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/reaction/ReactionComparator.java
@@ -177,6 +177,8 @@ public class ReactionComparator extends Comparator<Reaction> {
     SbmlKineticsComparator kineticsComparator = new SbmlKineticsComparator();
     if (kineticsComparator.compare(arg0.getKinetics(), arg1.getKinetics()) != 0) {
       logger.debug("Kinetics different");
+      logger.debug(arg0.getKinetics());
+      logger.debug(arg1.getKinetics());
       return kineticsComparator.compare(arg0.getKinetics(), arg1.getKinetics());
     }
     return 0;
-- 
GitLab