diff --git a/commons/src/main/java/lcsb/mapviewer/common/Comparator.java b/commons/src/main/java/lcsb/mapviewer/common/Comparator.java
new file mode 100644
index 0000000000000000000000000000000000000000..6030a1a6f1d798306cccaf5a19e4336926972383
--- /dev/null
+++ b/commons/src/main/java/lcsb/mapviewer/common/Comparator.java
@@ -0,0 +1,94 @@
+package lcsb.mapviewer.common;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+
+import lcsb.mapviewer.common.exception.NotImplementedException;
+
+public abstract class Comparator<T extends Object> implements java.util.Comparator<T> {
+  Logger logger = Logger.getLogger(Comparator.class);
+  private Class<T> comparatorClazz;
+  private boolean exactClassMatch;
+  private List<Comparator<? extends T>> subClassComparatorList = new ArrayList<>();
+
+  protected Comparator(Class<T> clazz) {
+    this(clazz, false);
+  }
+
+  protected Comparator(Class<T> clazz, boolean exactClassMatch) {
+    this.comparatorClazz = clazz;
+    this.exactClassMatch = exactClassMatch;
+  }
+
+  @Override
+  public final int compare(T arg0, T arg1) {
+    if (arg0 == null) {
+      if (arg1 == null) {
+        return 0;
+      } else {
+        return 1;
+      }
+    } else if (arg1 == null) {
+      return -1;
+    }
+
+    if (arg0.getClass().equals(arg1.getClass())) {
+      if (!arg0.getClass().equals(comparatorClazz)) {
+        Comparator subClassComparator = getSubClassComparatorForClass(arg0.getClass());
+        if (subClassComparator != null) {
+          return subClassComparator.compare(arg0, arg1);
+        } else if (exactClassMatch) {
+          throw new NotImplementedException("Don't know how to compare classes: " + arg0.getClass());
+        }
+      }
+      int result = compareParents(arg0, arg1);
+      if (result != 0) {
+        return result;
+      }
+      return internalCompare(arg0, arg1);
+    } else {
+      return -1;
+    }
+  }
+
+  private Comparator getSubClassComparatorForClass(Class<? extends Object> clazz) {
+    for (Comparator comparator : subClassComparatorList) {
+      if (comparator.getComparatorClazz().isAssignableFrom(clazz)) {
+        return comparator;
+      }
+    }
+    return null;
+  }
+
+  private int compareParents(T arg0, T arg1) {
+    Comparator parentComparator = getParentComparator();
+    while (parentComparator != null) {
+      int result = parentComparator.internalCompare(arg0, arg1);
+      if (result != 0) {
+        return result;
+      }
+      parentComparator = parentComparator.getParentComparator();
+    }
+    return 0;
+
+  }
+
+  protected Comparator getParentComparator() {
+    return null;
+  }
+
+  protected abstract int internalCompare(T arg0, T arg1);
+
+  protected void addSubClassComparator(Comparator<? extends T> subClassComparator) {
+    subClassComparatorList.add(subClassComparator);
+  }
+
+  public Class<T> getComparatorClazz() {
+    return comparatorClazz;
+  }
+
+}
diff --git a/converter-sbml/.classpath b/converter-sbml/.classpath
index 121fc2c8190e91386cecbac241fc4a0b7e6bb5ad..ebdb3af0aa2a29bebab2b0565e1f7c49e9d1aec3 100644
--- a/converter-sbml/.classpath
+++ b/converter-sbml/.classpath
@@ -30,6 +30,7 @@
 	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
 		<attributes>
 			<attribute name="maven.pomderived" value="true"/>
+			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
 		</attributes>
 	</classpathentry>
 	<classpathentry kind="output" path="target/classes"/>
diff --git a/converter-sbml/.project b/converter-sbml/.project
index 0a5695c6c29ccbc08e4825dbbe3b8aa759daa0f0..6ae989581c3ea83c552dd30b96d1c07ebbe4ee9d 100644
--- a/converter-sbml/.project
+++ b/converter-sbml/.project
@@ -5,6 +5,11 @@
 	<projects>
 	</projects>
 	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.wst.common.project.facet.core.builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
 		<buildCommand>
 			<name>org.eclipse.jdt.core.javabuilder</name>
 			<arguments>
@@ -15,9 +20,17 @@
 			<arguments>
 			</arguments>
 		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.wst.validation.validationbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
 	</buildSpec>
 	<natures>
+		<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
+		<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
 		<nature>org.eclipse.jdt.core.javanature</nature>
 		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
 	</natures>
 </projectDescription>
diff --git a/converter-sbml/.settings/org.eclipse.jdt.core.prefs b/converter-sbml/.settings/org.eclipse.jdt.core.prefs
index 714351aec195a9a572640e6844dcafd51565a2a5..6e80039d3b822e65e46fbf18906ef652814e9505 100644
--- a/converter-sbml/.settings/org.eclipse.jdt.core.prefs
+++ b/converter-sbml/.settings/org.eclipse.jdt.core.prefs
@@ -1,5 +1,8 @@
 eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
 org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
 org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
 org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
 org.eclipse.jdt.core.compiler.source=1.8
diff --git a/model/src/main/java/lcsb/mapviewer/model/graphics/ArrowTypeDataComparator.java b/model/src/main/java/lcsb/mapviewer/model/graphics/ArrowTypeDataComparator.java
index 3d67b7b4f649f6ee77df0c7c651ba33d0fafd899..787d1a4e8313d49c976e531b4070d108f08bbbff 100644
--- a/model/src/main/java/lcsb/mapviewer/model/graphics/ArrowTypeDataComparator.java
+++ b/model/src/main/java/lcsb/mapviewer/model/graphics/ArrowTypeDataComparator.java
@@ -1,9 +1,8 @@
 package lcsb.mapviewer.model.graphics;
 
-import java.util.Comparator;
-
 import org.apache.log4j.Logger;
 
+import lcsb.mapviewer.common.Comparator;
 import lcsb.mapviewer.common.Configuration;
 import lcsb.mapviewer.common.comparator.DoubleComparator;
 
@@ -14,87 +13,59 @@ import lcsb.mapviewer.common.comparator.DoubleComparator;
  * @author Piotr Gawron
  * 
  */
-public class ArrowTypeDataComparator implements Comparator<ArrowTypeData> {
-	/**
-	 * Default class logger.
-	 */
-	private Logger	logger	= Logger.getLogger(PolylineDataComparator.class);
-
-	/**
-	 * Epsilon value used for comparison of doubles.
-	 */
-	private double	epsilon;
-
-	/**
-	 * Constructor that requires {@link #epsilon} parameter.
-	 * 
-	 * @param epsilon
-	 *          {@link #epsilon}
-	 */
-	public ArrowTypeDataComparator(double epsilon) {
-		this.epsilon = epsilon;
-	}
+public class ArrowTypeDataComparator extends Comparator<ArrowTypeData> {
+  /**
+   * Default class logger.
+   */
+  private Logger logger = Logger.getLogger(PolylineDataComparator.class);
 
-	/**
-	 * Default constructor.
-	 */
-	public ArrowTypeDataComparator() {
-		this(Configuration.EPSILON);
-	}
+  /**
+   * Epsilon value used for comparison of doubles.
+   */
+  private double epsilon;
 
-	@Override
-	public int compare(ArrowTypeData arg0, ArrowTypeData arg1) {
-		if (arg0 == null) {
-			if (arg1 == null) {
-				return 0;
-			} else {
-				return 1;
-			}
-		} else if (arg1 == null) {
-			return -1;
-		}
+  /**
+   * Constructor that requires {@link #epsilon} parameter.
+   * 
+   * @param epsilon
+   *          {@link #epsilon}
+   */
+  public ArrowTypeDataComparator(double epsilon) {
+    super(ArrowTypeData.class);
+    this.epsilon = epsilon;
+  }
 
-		if (arg0.getClass().equals(arg1.getClass())) {
-			return internalCompare(arg0, arg1);
-		} else {
-			return -1;
-		}
-	}
+  /**
+   * Default constructor.
+   */
+  public ArrowTypeDataComparator() {
+    this(Configuration.EPSILON);
+  }
 
-	/**
-	 * This method compares only the fields that are defined in ArrowTypeData
-	 * class in inheritance tree.
-	 * 
-	 * @param arg0
-	 *          first object to compare
-	 * @param arg1
-	 *          second object to compare
-	 * @return if all fields are equal then returns 0. If they are different then
-	 *         -1/1 is returned.
-	 */
-	private int internalCompare(ArrowTypeData arg0, ArrowTypeData arg1) {
-		DoubleComparator doubleComparator = new DoubleComparator(epsilon);
+  @Override
+  protected int internalCompare(ArrowTypeData arg0, ArrowTypeData arg1) {
+    DoubleComparator doubleComparator = new DoubleComparator(epsilon);
 
-		if (arg0.getArrowType().compareTo(arg1.getArrowType()) != 0) {
-			logger.debug("Different arrow type: " + arg0.getArrowType() + ", " + arg1.getArrowType());
-			return arg0.getArrowType().compareTo(arg1.getArrowType());
-		}
+    if (arg0.getArrowType().compareTo(arg1.getArrowType()) != 0) {
+      logger.debug("Different arrow type: " + arg0.getArrowType() + ", " + arg1.getArrowType());
+      return arg0.getArrowType().compareTo(arg1.getArrowType());
+    }
 
-		if (arg0.getArrowLineType().compareTo(arg1.getArrowLineType()) != 0) {
-			logger.debug("Different arrow line type: " + arg0.getArrowLineType() + ", " + arg1.getArrowLineType());
-			return arg0.getArrowLineType().compareTo(arg1.getArrowLineType());
-		}
+    if (arg0.getArrowLineType().compareTo(arg1.getArrowLineType()) != 0) {
+      logger.debug("Different arrow line type: " + arg0.getArrowLineType() + ", " + arg1.getArrowLineType());
+      return arg0.getArrowLineType().compareTo(arg1.getArrowLineType());
+    }
 
-		if (doubleComparator.compare(arg0.getLen(), arg1.getLen()) != 0) {
-			logger.debug("Different length: " + arg0.getLen() + ", " + arg1.getLen());
-			return doubleComparator.compare(arg0.getLen(), arg1.getLen());
-		}
+    if (doubleComparator.compare(arg0.getLen(), arg1.getLen()) != 0) {
+      logger.debug("Different length: " + arg0.getLen() + ", " + arg1.getLen());
+      return doubleComparator.compare(arg0.getLen(), arg1.getLen());
+    }
 
-		if (doubleComparator.compare(arg0.getAngle(), arg1.getAngle()) != 0) {
-			logger.debug("Different angle: " + arg0.getAngle() + ", " + arg1.getAngle());
-			return doubleComparator.compare(arg0.getAngle(), arg1.getAngle());
-		}
-		return 0;
-	}
+    if (doubleComparator.compare(arg0.getAngle(), arg1.getAngle()) != 0) {
+      logger.debug("Different angle: " + arg0.getAngle() + ", " + arg1.getAngle());
+      return doubleComparator.compare(arg0.getAngle(), arg1.getAngle());
+    }
+    return 0;
+  }
 
 }
diff --git a/model/src/main/java/lcsb/mapviewer/model/graphics/PolylineDataComparator.java b/model/src/main/java/lcsb/mapviewer/model/graphics/PolylineDataComparator.java
index d06b841c16046228ec85564ad9a72f35ffe2b27c..12e7bde45dfb098f163d1b7b2772d0be5d4b0455 100644
--- a/model/src/main/java/lcsb/mapviewer/model/graphics/PolylineDataComparator.java
+++ b/model/src/main/java/lcsb/mapviewer/model/graphics/PolylineDataComparator.java
@@ -1,13 +1,11 @@
 package lcsb.mapviewer.model.graphics;
 
-import java.util.Comparator;
-
 import org.apache.log4j.Logger;
 
+import lcsb.mapviewer.common.Comparator;
 import lcsb.mapviewer.common.Configuration;
 import lcsb.mapviewer.common.comparator.DoubleComparator;
 import lcsb.mapviewer.common.comparator.IntegerComparator;
-import lcsb.mapviewer.common.exception.NotImplementedException;
 
 /**
  * This class implements comparator interface for {@link PolylineData}. It
@@ -16,7 +14,7 @@ import lcsb.mapviewer.common.exception.NotImplementedException;
  * @author Piotr Gawron
  * 
  */
-public class PolylineDataComparator implements Comparator<PolylineData> {
+public class PolylineDataComparator extends Comparator<PolylineData> {
   /**
    * Default class logger.
    */
@@ -34,6 +32,7 @@ public class PolylineDataComparator implements Comparator<PolylineData> {
    *          {@link #epsilon}
    */
   public PolylineDataComparator(double epsilon) {
+    super(PolylineData.class, true);
     this.epsilon = epsilon;
   }
 
@@ -45,53 +44,20 @@ public class PolylineDataComparator implements Comparator<PolylineData> {
   }
 
   @Override
-  public int compare(PolylineData arg0, PolylineData arg1) {
-    if (arg0 == null) {
-      if (arg1 == null) {
-        return 0;
-      } else {
-        return 1;
-      }
-    } else if (arg1 == null) {
-      return -1;
-    }
-
-    if (arg0.getClass().equals(arg1.getClass())) {
-      if (arg0.getClass().equals(PolylineData.class)) {
-        return internalCompare(arg0, arg1);
-      } else {
-        throw new NotImplementedException("Don't know how to compare classes: " + arg0.getClass());
-      }
-    } else {
-      return -1;
-    }
-  }
-
-  /**
-   * This method compares only the fields that are defined in {@link PolylineData}
-   * class in inheritance tree.
-   * 
-   * @param arg0
-   *          first object to compare
-   * @param arg1
-   *          second object to compare
-   * @return if all fields are equal then returns 0. If they are different then
-   *         -1/1 is returned.
-   */
-  private int internalCompare(PolylineData arg0, PolylineData arg1) {
+  protected int internalCompare(PolylineData arg0, PolylineData arg1) {
     IntegerComparator integerComparator = new IntegerComparator();
     DoubleComparator doubleComparator = new DoubleComparator(epsilon);
     ArrowTypeDataComparator atdComparator = new ArrowTypeDataComparator(epsilon);
 
-    int different1=0;
-    int different2=0;
-    for (int i=1;i<arg0.getPoints().size();i++) {
-      if (arg0.getPoints().get(i).distance(arg0.getPoints().get(i-1))>Configuration.EPSILON) {
+    int different1 = 0;
+    int different2 = 0;
+    for (int i = 1; i < arg0.getPoints().size(); i++) {
+      if (arg0.getPoints().get(i).distance(arg0.getPoints().get(i - 1)) > Configuration.EPSILON) {
         different1++;
       }
     }
-    for (int i=1;i<arg1.getPoints().size();i++) {
-      if (arg1.getPoints().get(i).distance(arg1.getPoints().get(i-1))>Configuration.EPSILON) {
+    for (int i = 1; i < arg1.getPoints().size(); i++) {
+      if (arg1.getPoints().get(i).distance(arg1.getPoints().get(i - 1)) > Configuration.EPSILON) {
         different2++;
       }
     }
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/MiriamTypeNameComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/MiriamTypeNameComparator.java
index 87bfc05c4a9bedcdfb735a1705db60f807a6b2ae..c7d981188407b65cadb177b397061e03a38a6580 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/MiriamTypeNameComparator.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/MiriamTypeNameComparator.java
@@ -1,6 +1,6 @@
 package lcsb.mapviewer.model.map;
 
-import java.util.Comparator;
+import lcsb.mapviewer.common.Comparator;
 
 /**
  * {@link Comparator} implementation for {@link MiriamType} that uses
@@ -9,21 +9,15 @@ import java.util.Comparator;
  * @author Piotr Gawron
  *
  */
-public class MiriamTypeNameComparator implements Comparator<MiriamType> {
+public class MiriamTypeNameComparator extends Comparator<MiriamType> {
 
-	@Override
-	public int compare(MiriamType arg0, MiriamType arg1) {
-		// comparator is null-safe
-		if (arg0 == null) {
-			if (arg1 == null) {
-				return 0;
-			} else {
-				return 1;
-			}
-		} else if (arg1 == null) {
-			return -1;
-		}
-		return arg0.getCommonName().compareTo(arg1.getCommonName());
-	}
+  public MiriamTypeNameComparator() {
+    super(MiriamType.class);
+  }
+
+  @Override
+  protected int internalCompare(MiriamType arg0, MiriamType arg1) {
+    return arg0.getCommonName().compareTo(arg1.getCommonName());
+  }
 
 }
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/OverviewImageComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/OverviewImageComparator.java
index 6796e011abf1e305e893255d135e453a00d9e89c..de8391c624b8a30ccc3d4670c0ba1e2a3344f95e 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/OverviewImageComparator.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/OverviewImageComparator.java
@@ -1,127 +1,98 @@
 package lcsb.mapviewer.model.map;
 
-import java.util.Comparator;
 import java.util.List;
 
+import org.apache.log4j.Logger;
+
+import lcsb.mapviewer.common.Comparator;
 import lcsb.mapviewer.common.Configuration;
 import lcsb.mapviewer.common.comparator.IntegerComparator;
 import lcsb.mapviewer.common.comparator.StringComparator;
 
-import org.apache.log4j.Logger;
-
 /**
  * This class implements comparator interface for {@link OverviewImage}.
  * 
  * @author Piotr Gawron
  * 
  */
-public class OverviewImageComparator implements Comparator<OverviewImage> {
-	/**
-	 * Default class logger.
-	 */
-	private static Logger	logger	= Logger.getLogger(OverviewImageComparator.class);
-
-	/**
-	 * Epsilon value used for comparison of doubles.
-	 */
-	private double				epsilon;
-
-	/**
-	 * Constructor that requires {@link #epsilon} parameter.
-	 * 
-	 * @param epsilon
-	 *          {@link #epsilon}
-	 */
-	public OverviewImageComparator(double epsilon) {
-		this.epsilon = epsilon;
-	}
-
-	/**
-	 * Default constructor.
-	 */
-	public OverviewImageComparator() {
-		this(Configuration.EPSILON);
-	}
-
-	@Override
-	public int compare(OverviewImage arg0, OverviewImage arg1) {
-		if (arg0 == null) {
-			if (arg1 == null) {
-				return 0;
-			} else {
-				return 1;
-			}
-		} else if (arg1 == null) {
-			return -1;
-		}
-
-		if (arg0.getClass().equals(arg1.getClass())) {
-			return internalCompare(arg0, arg1);
-		} else {
-			logger.debug("class different: " + arg0.getClass() + ", " + arg1.getClass());
-			return -1;
-		}
-	}
-
-	/**
-	 * This method compares only the fields that are defined in
-	 * {@link OverviewImage} class in inheritence tree.
-	 * 
-	 * @param arg0
-	 *          first object to compare
-	 * @param arg1
-	 *          second object to compare
-	 * @return if all fields are qual then returns 0. If they are different then
-	 *         -1/1 is returned.
-	 */
-	public int internalCompare(OverviewImage arg0, OverviewImage arg1) {
-		StringComparator stringComparator = new StringComparator();
-
-		if (stringComparator.compare(arg0.getFilename(), arg1.getFilename()) != 0) {
-			logger.debug("filename different: " + arg0.getFilename() + ", " + arg1.getFilename());
-			return stringComparator.compare(arg0.getFilename(), arg1.getFilename());
-		}
-
-		IntegerComparator integerComparator = new IntegerComparator();
-
-		if (integerComparator.compare(arg0.getWidth(), arg1.getWidth()) != 0) {
-			logger.debug("width different: " + arg0.getWidth() + ", " + arg1.getWidth());
-			return integerComparator.compare(arg0.getWidth(), arg1.getWidth());
-		}
-
-		if (integerComparator.compare(arg0.getHeight(), arg1.getHeight()) != 0) {
-			logger.debug("height different: " + arg0.getHeight() + ", " + arg1.getHeight());
-			return integerComparator.compare(arg0.getHeight(), arg1.getHeight());
-		}
-
-		if (compareLinks(arg0.getLinks(), arg1.getLinks()) != 0) {
-			return compareLinks(arg0.getLinks(), arg1.getLinks());
-		}
-
-		return 0;
-	}
-
-	/**
-	 * Compare two list of {@link OverviewLink links}.
-	 * 
-	 * @param links
-	 *          first list to compare
-	 * @param links2
-	 *          second list to compare
-	 * @return 0 if the list are identical, -1/1 otherwise
-	 */
-	private int compareLinks(List<OverviewLink> links, List<OverviewLink> links2) {
-		IntegerComparator integerComparator = new IntegerComparator();
-		OverviewLinkComparator ovc = new OverviewLinkComparator(epsilon);
-		if (integerComparator.compare(links.size(), links2.size()) != 0) {
-			return integerComparator.compare(links.size(), links2.size());
-		}
-		for (int i = 0; i < links.size(); i++) {
-			if (ovc.compare(links.get(i), links2.get(i)) != 0) {
-				return ovc.compare(links.get(i), links2.get(i));
-			}
-		}
-		return 0;
-	}
+public class OverviewImageComparator extends Comparator<OverviewImage> {
+  /**
+   * Default class logger.
+   */
+  private static Logger logger = Logger.getLogger(OverviewImageComparator.class);
+
+  /**
+   * Epsilon value used for comparison of doubles.
+   */
+  private double epsilon;
+
+  /**
+   * Constructor that requires {@link #epsilon} parameter.
+   * 
+   * @param epsilon
+   *          {@link #epsilon}
+   */
+  public OverviewImageComparator(double epsilon) {
+    super(OverviewImage.class);
+    this.epsilon = epsilon;
+  }
+
+  /**
+   * Default constructor.
+   */
+  public OverviewImageComparator() {
+    this(Configuration.EPSILON);
+  }
+
+  @Override
+  protected int internalCompare(OverviewImage arg0, OverviewImage arg1) {
+    StringComparator stringComparator = new StringComparator();
+
+    if (stringComparator.compare(arg0.getFilename(), arg1.getFilename()) != 0) {
+      logger.debug("filename different: " + arg0.getFilename() + ", " + arg1.getFilename());
+      return stringComparator.compare(arg0.getFilename(), arg1.getFilename());
+    }
+
+    IntegerComparator integerComparator = new IntegerComparator();
+
+    if (integerComparator.compare(arg0.getWidth(), arg1.getWidth()) != 0) {
+      logger.debug("width different: " + arg0.getWidth() + ", " + arg1.getWidth());
+      return integerComparator.compare(arg0.getWidth(), arg1.getWidth());
+    }
+
+    if (integerComparator.compare(arg0.getHeight(), arg1.getHeight()) != 0) {
+      logger.debug("height different: " + arg0.getHeight() + ", " + arg1.getHeight());
+      return integerComparator.compare(arg0.getHeight(), arg1.getHeight());
+    }
+
+    if (compareLinks(arg0.getLinks(), arg1.getLinks()) != 0) {
+      return compareLinks(arg0.getLinks(), arg1.getLinks());
+    }
+
+    return 0;
+  }
+
+  /**
+   * Compare two list of {@link OverviewLink links}.
+   * 
+   * @param links
+   *          first list to compare
+   * @param links2
+   *          second list to compare
+   * @return 0 if the list are identical, -1/1 otherwise
+   */
+  private int compareLinks(List<OverviewLink> links, List<OverviewLink> links2) {
+    IntegerComparator integerComparator = new IntegerComparator();
+    OverviewLinkComparator ovc = new OverviewLinkComparator(epsilon);
+    if (integerComparator.compare(links.size(), links2.size()) != 0) {
+      return integerComparator.compare(links.size(), links2.size());
+    }
+    for (int i = 0; i < links.size(); i++) {
+      if (ovc.compare(links.get(i), links2.get(i)) != 0) {
+        return ovc.compare(links.get(i), links2.get(i));
+      }
+    }
+    return 0;
+  }
 
 }
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/OverviewImageLinkComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/OverviewImageLinkComparator.java
index 3ba0b157c6fce7ba885ad3821ff725996147608d..eeb7f3ba0b7034a88c3e7d53267000ce567c70c9 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/OverviewImageLinkComparator.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/OverviewImageLinkComparator.java
@@ -1,104 +1,74 @@
 package lcsb.mapviewer.model.map;
 
-import java.util.Comparator;
+import org.apache.log4j.Logger;
 
+import lcsb.mapviewer.common.Comparator;
 import lcsb.mapviewer.common.Configuration;
 import lcsb.mapviewer.common.comparator.IntegerComparator;
 
-import org.apache.log4j.Logger;
-
 /**
  * This class implements comparator interface for {@link OverviewImageLink}.
  * 
  * @author Piotr Gawron
  * 
  */
-public class OverviewImageLinkComparator implements Comparator<OverviewImageLink> {
-	/**
-	 * Default class logger.
-	 */
-	private static Logger	logger	= Logger.getLogger(OverviewImageLinkComparator.class);
-
-	/**
-	 * Epsilon value used for comparison of doubles.
-	 */
-	private double				epsilon;
-
-	/**
-	 * Constructor that requires {@link #epsilon} parameter.
-	 * 
-	 * @param epsilon
-	 *          {@link #epsilon}
-	 */
-	public OverviewImageLinkComparator(double epsilon) {
-		this.epsilon = epsilon;
-	}
-
-	/**
-	 * Default constructor.
-	 */
-	public OverviewImageLinkComparator() {
-		this(Configuration.EPSILON);
-	}
-
-	@Override
-	public int compare(OverviewImageLink arg0, OverviewImageLink arg1) {
-		if (arg0 == null) {
-			if (arg1 == null) {
-				return 0;
-			} else {
-				return 1;
-			}
-		} else if (arg1 == null) {
-			return -1;
-		}
-
-		if (arg0.getClass().equals(arg1.getClass())) {
-			return internalCompare(arg0, arg1);
-		} else {
-			logger.debug("class different: " + arg0.getClass() + ", " + arg1.getClass());
-			return -1;
-		}
-	}
-
-	/**
-	 * This method compares only the fields that are defined in
-	 * {@link OverviewImageLink} class in inheritence tree.
-	 * 
-	 * @param arg0
-	 *          first object to compare
-	 * @param arg1
-	 *          second object to compare
-	 * @return if all fields are qual then returns 0. If they are different then
-	 *         -1/1 is returned.
-	 */
-	public int internalCompare(OverviewImageLink arg0, OverviewImageLink arg1) {
-		OverviewLinkComparator overviewLinkComparator = new OverviewLinkComparator(epsilon);
-		int result = overviewLinkComparator.internalCompare(arg0, arg1);
-		if (result != 0) {
-			return result;
-		}
-
-		IntegerComparator integerComparator = new IntegerComparator();
-
-		if (arg0.getLinkedOverviewImage() == null) {
-			if (arg1.getLinkedOverviewImage() == null) {
-				result = 0;
-			} else {
-				result = 1;
-			}
-		} else if (arg1.getLinkedOverviewImage() == null) {
-			result = -1;
-		} else {
-			result = integerComparator.compare(arg0.getLinkedOverviewImage().getId(), arg1.getLinkedOverviewImage().getId());
-		}
-
-		if (result != 0) {
-			return result;
-		}
-
-		return 0;
-
-	}
+public class OverviewImageLinkComparator extends Comparator<OverviewImageLink> {
+  /**
+   * Default class logger.
+   */
+  private static Logger logger = Logger.getLogger(OverviewImageLinkComparator.class);
+
+  /**
+   * Epsilon value used for comparison of doubles.
+   */
+  private double epsilon;
+
+  /**
+   * Constructor that requires {@link #epsilon} parameter.
+   * 
+   * @param epsilon
+   *          {@link #epsilon}
+   */
+  public OverviewImageLinkComparator(double epsilon) {
+    super(OverviewImageLink.class);
+    this.epsilon = epsilon;
+  }
+  
+  @Override
+  protected Comparator<?> getParentComparator() {
+    return new OverviewLinkComparator(epsilon);
+  }
+
+  /**
+   * Default constructor.
+   */
+  public OverviewImageLinkComparator() {
+    this(Configuration.EPSILON);
+  }
+
+  @Override
+  protected int internalCompare(OverviewImageLink arg0, OverviewImageLink arg1) {
+    int result = 0;
+    IntegerComparator integerComparator = new IntegerComparator();
+
+    if (arg0.getLinkedOverviewImage() == null) {
+      if (arg1.getLinkedOverviewImage() == null) {
+        result = 0;
+      } else {
+        result = 1;
+      }
+    } else if (arg1.getLinkedOverviewImage() == null) {
+      result = -1;
+    } else {
+      result = integerComparator.compare(arg0.getLinkedOverviewImage().getId(), arg1.getLinkedOverviewImage().getId());
+    }
+
+    if (result != 0) {
+      return result;
+    }
+
+    return 0;
+
+  }
 
 }
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/OverviewLinkComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/OverviewLinkComparator.java
index a81a46c0e6dd3dadbdbb3702479e69055233af9e..6ea1cc68e505f8b9d6af4360813761e2d05b16d1 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/OverviewLinkComparator.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/OverviewLinkComparator.java
@@ -1,12 +1,10 @@
 package lcsb.mapviewer.model.map;
 
-import java.util.Comparator;
-
 import org.apache.log4j.Logger;
 
+import lcsb.mapviewer.common.Comparator;
 import lcsb.mapviewer.common.Configuration;
 import lcsb.mapviewer.common.comparator.StringComparator;
-import lcsb.mapviewer.common.exception.NotImplementedException;
 
 /**
  * This class implements comparator interface for {@link OverviewLink}.
@@ -14,96 +12,51 @@ import lcsb.mapviewer.common.exception.NotImplementedException;
  * @author Piotr Gawron
  * 
  */
-public class OverviewLinkComparator implements Comparator<OverviewLink> {
-
-	/**
-	 * Default class logger.
-	 */
-	private static Logger								logger = Logger.getLogger(OverviewLinkComparator.class);
-
-	/**
-	 * Comparator used to compare {@link OverviewModelLink} objects.
-	 */
-	private OverviewModelLinkComparator	overviewModelLinkComparator;
-
-	/**
-	 * Comparator used to compare {@link OverviewImageLink} objects.
-	 */
-	private OverviewImageLinkComparator	overviewImageLinkComparator;
-
-	/**
-	 * Epsilon value used for comparison of doubles.
-	 */
-	@SuppressWarnings("unused")
-	private double											epsilon;
-
-	/**
-	 * Constructor that requires {@link #epsilon} parameter.
-	 * 
-	 * @param epsilon
-	 *          {@link #epsilon}
-	 */
-	public OverviewLinkComparator(double epsilon) {
-		this.epsilon = epsilon;
-		overviewImageLinkComparator = new OverviewImageLinkComparator(epsilon);
-		overviewModelLinkComparator = new OverviewModelLinkComparator(epsilon);
-	}
-
-	/**
-	 * Default constructor.
-	 */
-	public OverviewLinkComparator() {
-		this(Configuration.EPSILON);
-	}
-
-	@Override
-	public int compare(OverviewLink arg0, OverviewLink arg1) {
-		if (arg0 == null) {
-			if (arg1 == null) {
-				return 0;
-			} else {
-				return 1;
-			}
-		} else if (arg1 == null) {
-			return -1;
-		}
-
-		if (arg0.getClass().equals(arg1.getClass())) {
-			if (arg0 instanceof OverviewImageLink) {
-				return overviewImageLinkComparator.compare((OverviewImageLink) arg0, (OverviewImageLink) arg1);
-			} else if (arg0 instanceof OverviewModelLink) {
-				return overviewModelLinkComparator.compare((OverviewModelLink) arg0, (OverviewModelLink) arg1);
-			} else {
-				throw new NotImplementedException("Don't know how to compare classes: " + arg0.getClass());
-			}
-		} else {
-			logger.debug("class different: " + arg0.getClass() + ", " + arg1.getClass());
-			return -1;
-		}
-	}
-
-	/**
-	 * This method compares only the fields that are defined in
-	 * {@link OverviewImage} class in inheritence tree.
-	 * 
-	 * @param arg0
-	 *          first object to compare
-	 * @param arg1
-	 *          second object to compare
-	 * @return if all fields are qual then returns 0. If they are different then
-	 *         -1/1 is returned.
-	 */
-	public int internalCompare(OverviewLink arg0, OverviewLink arg1) {
-
-		StringComparator stringComparator = new StringComparator();
-
-		if (stringComparator.compare(arg0.getPolygon(), arg1.getPolygon()) != 0) {
-			logger.debug("polygon different: " + arg0.getPolygon() + ", " + arg1.getPolygon());
-			return stringComparator.compare(arg0.getPolygon(), arg1.getPolygon());
-		}
-
-		return 0;
-
-	}
+public class OverviewLinkComparator extends Comparator<OverviewLink> {
+
+  /**
+   * Default class logger.
+   */
+  private static Logger logger = Logger.getLogger(OverviewLinkComparator.class);
+
+  /**
+   * Epsilon value used for comparison of doubles.
+   */
+  @SuppressWarnings("unused")
+  private double epsilon;
+
+  /**
+   * Constructor that requires {@link #epsilon} parameter.
+   * 
+   * @param epsilon
+   *          {@link #epsilon}
+   */
+  public OverviewLinkComparator(double epsilon) {
+    super(OverviewLink.class, true);
+    this.epsilon = epsilon;
+    addSubClassComparator(new OverviewImageLinkComparator(epsilon));
+    addSubClassComparator(new OverviewModelLinkComparator(epsilon));
+  }
+
+  /**
+   * Default constructor.
+   */
+  public OverviewLinkComparator() {
+    this(Configuration.EPSILON);
+  }
+
+  @Override
+  protected int internalCompare(OverviewLink arg0, OverviewLink arg1) {
+
+    StringComparator stringComparator = new StringComparator();
+
+    if (stringComparator.compare(arg0.getPolygon(), arg1.getPolygon()) != 0) {
+      logger.debug("polygon different: " + arg0.getPolygon() + ", " + arg1.getPolygon());
+      return stringComparator.compare(arg0.getPolygon(), arg1.getPolygon());
+    }
+
+    return 0;
+
+  }
 
 }
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/OverviewModelLinkComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/OverviewModelLinkComparator.java
index dfa7a9c72c92fed205ffd5012a04a5df96b96085..7adb2b8647c14a4770da68d57bbae0cc0e8cfce3 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/OverviewModelLinkComparator.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/OverviewModelLinkComparator.java
@@ -1,120 +1,88 @@
 package lcsb.mapviewer.model.map;
 
-import java.util.Comparator;
+import org.apache.log4j.Logger;
 
+import lcsb.mapviewer.common.Comparator;
 import lcsb.mapviewer.common.Configuration;
 import lcsb.mapviewer.common.comparator.IntegerComparator;
 
-import org.apache.log4j.Logger;
-
 /**
  * This class implements comparator interface for {@link OverviewModelLink}.
  * 
  * @author Piotr Gawron
  * 
  */
-public class OverviewModelLinkComparator implements Comparator<OverviewModelLink> {
-	/**
-	 * Default class logger.
-	 */
-	private static Logger	logger	= Logger.getLogger(OverviewModelLinkComparator.class);
-
-	/**
-	 * Epsilon value used for comparison of doubles.
-	 */
-	private double				epsilon;
-
-	/**
-	 * Constructor that requires {@link #epsilon} parameter.
-	 * 
-	 * @param epsilon
-	 *          {@link #epsilon}
-	 */
-	public OverviewModelLinkComparator(double epsilon) {
-		this.epsilon = epsilon;
-	}
-
-	/**
-	 * Default constructor.
-	 */
-	public OverviewModelLinkComparator() {
-		this(Configuration.EPSILON);
-	}
-
-	@Override
-	public int compare(OverviewModelLink arg0, OverviewModelLink arg1) {
-		if (arg0 == null) {
-			if (arg1 == null) {
-				return 0;
-			} else {
-				return 1;
-			}
-		} else if (arg1 == null) {
-			return -1;
-		}
-
-		if (arg0.getClass().equals(arg1.getClass())) {
-			return internalCompare(arg0, arg1);
-		} else {
-			logger.debug("class different: " + arg0.getClass() + ", " + arg1.getClass());
-			return -1;
-		}
-	}
-
-	/**
-	 * This method compares only the fields that are defined in
-	 * {@link OverviewModelLink} class in inheritence tree. It also calls the
-	 * {@link OverviewLinkComparator} for the super class ({@link OverviewLink}).
-	 * 
-	 * @param arg0
-	 *          first object to compare
-	 * @param arg1
-	 *          second object to compare
-	 * @return if all fields are qual then returns 0. If they are different then
-	 *         -1/1 is returned.
-	 */
-	public int internalCompare(OverviewModelLink arg0, OverviewModelLink arg1) {
-		OverviewLinkComparator overviewLinkComparator = new OverviewLinkComparator(epsilon);
-		int result = overviewLinkComparator.internalCompare(arg0, arg1);
-		if (result != 0) {
-			return result;
-		}
-		IntegerComparator integerComparator = new IntegerComparator();
-		if (integerComparator.compare(arg0.getxCoord(), arg1.getxCoord()) != 0) {
-			logger.debug("xCoord different: " + arg0.getxCoord() + ", " + arg1.getxCoord());
-			return integerComparator.compare(arg0.getxCoord(), arg1.getxCoord());
-		}
-
-		if (integerComparator.compare(arg0.getyCoord(), arg1.getyCoord()) != 0) {
-			logger.debug("yCoord different: " + arg0.getyCoord() + ", " + arg1.getyCoord());
-			return integerComparator.compare(arg0.getyCoord(), arg1.getyCoord());
-		}
-
-		if (integerComparator.compare(arg0.getZoomLevel(), arg1.getZoomLevel()) != 0) {
-			logger.debug("zoomLevel different: " + arg0.getZoomLevel() + ", " + arg1.getZoomLevel());
-			return integerComparator.compare(arg0.getZoomLevel(), arg1.getZoomLevel());
-		}
-
-
-		if (arg0.getLinkedModel() == null) {
-			if (arg1.getLinkedModel() == null) {
-				result = 0;
-			} else {
-				result = 1;
-			}
-		} else if (arg1.getLinkedModel() == null) {
-			result = -1;
-		} else {
-			result = integerComparator.compare(arg0.getLinkedModel().getId(), arg1.getLinkedModel().getId());
-		}
-
-		if (result != 0) {
-			return result;
-		}
-
-		
-		return 0;
-
-	}
+public class OverviewModelLinkComparator extends Comparator<OverviewModelLink> {
+  /**
+   * Default class logger.
+   */
+  private static Logger logger = Logger.getLogger(OverviewModelLinkComparator.class);
+
+  /**
+   * Epsilon value used for comparison of doubles.
+   */
+  private double epsilon;
+
+  /**
+   * Constructor that requires {@link #epsilon} parameter.
+   * 
+   * @param epsilon
+   *          {@link #epsilon}
+   */
+  public OverviewModelLinkComparator(double epsilon) {
+    super(OverviewModelLink.class);
+    this.epsilon = epsilon;
+  }
+
+  /**
+   * Default constructor.
+   */
+  public OverviewModelLinkComparator() {
+    this(Configuration.EPSILON);
+  }
+
+  @Override
+  public Comparator<?> getParentComparator() {
+    return new OverviewLinkComparator(epsilon);
+  }
+
+  @Override
+  protected int internalCompare(OverviewModelLink arg0, OverviewModelLink arg1) {
+    int result = 0;
+    IntegerComparator integerComparator = new IntegerComparator();
+    if (integerComparator.compare(arg0.getxCoord(), arg1.getxCoord()) != 0) {
+      logger.debug("xCoord different: " + arg0.getxCoord() + ", " + arg1.getxCoord());
+      return integerComparator.compare(arg0.getxCoord(), arg1.getxCoord());
+    }
+
+    if (integerComparator.compare(arg0.getyCoord(), arg1.getyCoord()) != 0) {
+      logger.debug("yCoord different: " + arg0.getyCoord() + ", " + arg1.getyCoord());
+      return integerComparator.compare(arg0.getyCoord(), arg1.getyCoord());
+    }
+
+    if (integerComparator.compare(arg0.getZoomLevel(), arg1.getZoomLevel()) != 0) {
+      logger.debug("zoomLevel different: " + arg0.getZoomLevel() + ", " + arg1.getZoomLevel());
+      return integerComparator.compare(arg0.getZoomLevel(), arg1.getZoomLevel());
+    }
+
+    if (arg0.getLinkedModel() == null) {
+      if (arg1.getLinkedModel() == null) {
+        result = 0;
+      } else {
+        result = 1;
+      }
+    } else if (arg1.getLinkedModel() == null) {
+      result = -1;
+    } else {
+      result = integerComparator.compare(arg0.getLinkedModel().getId(), arg1.getLinkedModel().getId());
+    }
+
+    if (result != 0) {
+      return result;
+    }
+
+    return 0;
+
+  }
 
 }
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/compartment/CompartmentComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/compartment/CompartmentComparator.java
index e56a9c0532e64df5fa2f8d48cec9daf9e32081d5..80b2870b9c6a0b29da4ff7ae0d151efb291a8048 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/compartment/CompartmentComparator.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/compartment/CompartmentComparator.java
@@ -1,16 +1,17 @@
 package lcsb.mapviewer.model.map.compartment;
 
-import java.util.Comparator;
 import java.util.HashMap;
 import java.util.Map;
 
 import org.apache.log4j.Logger;
 
+import lcsb.mapviewer.common.Comparator;
 import lcsb.mapviewer.common.Configuration;
 import lcsb.mapviewer.common.comparator.DoubleComparator;
 import lcsb.mapviewer.common.comparator.IntegerComparator;
 import lcsb.mapviewer.common.comparator.PointComparator;
 import lcsb.mapviewer.common.exception.InvalidArgumentException;
+import lcsb.mapviewer.model.map.reaction.AbstractNodeComparator;
 import lcsb.mapviewer.model.map.species.Element;
 import lcsb.mapviewer.model.map.species.ElementComparator;
 
@@ -22,127 +23,99 @@ import lcsb.mapviewer.model.map.species.ElementComparator;
  * @see Compartment
  * 
  */
-public class CompartmentComparator implements Comparator<Compartment> {
-
-	/**
-	 * Default class logger.
-	 */
-	private Logger logger	= Logger.getLogger(CompartmentComparator.class);
-
-	/**
-	 * Epsilon value used for comparison of doubles.
-	 */
-	private double epsilon;
-
-	/**
-	 * Constructor that requires {@link #epsilon} parameter.
-	 * 
-	 * @param epsilon
-	 *          {@link #epsilon}
-	 */
-	public CompartmentComparator(double epsilon) {
-		this.epsilon = epsilon;
-	}
-
-	/**
-	 * Default constructor.
-	 */
-	public CompartmentComparator() {
-		this(Configuration.EPSILON);
-	}
-
-	@Override
-	public int compare(Compartment arg0, Compartment arg1) {
-		if (arg0 == null) {
-			if (arg1 == null) {
-				return 0;
-			} else {
-				return 1;
-			}
-		} else if (arg1 == null) {
-			return -1;
-		}
-
-		if (arg0.getClass().equals(arg1.getClass())) {
-			return internalCompare(arg0, arg1);
-		} else {
-			return -1;
-		}
-	}
-
-	/**
-	 * This method compares only the fields that are defined in
-	 * {@link Compartment} class in inheritence tree.
-	 * 
-	 * @param arg0
-	 *          first object to compare
-	 * @param arg1
-	 *          second object to compare
-	 * @return if all fields are qual then returns 0. If they are different then
-	 *         -1/1 is returned.
-	 */
-	private int internalCompare(Compartment arg0, Compartment arg1) {
-		ElementComparator elementComparator = new ElementComparator(epsilon);
-		int result = elementComparator.internalCompare(arg0, arg1);
-		if (result != 0) {
-			return result;
-		}
-
-		DoubleComparator doubleComparator = new DoubleComparator(epsilon);
-		IntegerComparator integerComparator = new IntegerComparator();
-		PointComparator pointComparator = new PointComparator(epsilon);
-
-		if (doubleComparator.compare(arg0.getThickness(), arg1.getThickness()) != 0) {
-			logger.debug("Thickness different: " + arg0.getThickness() + ", " + arg1.getThickness());
-			return doubleComparator.compare(arg0.getThickness(), arg1.getThickness());
-		}
-
-		if (doubleComparator.compare(arg0.getOuterWidth(), arg1.getOuterWidth()) != 0) {
-			logger.debug("Outer width different: " + arg0.getOuterWidth() + ", " + arg1.getOuterWidth());
-			return doubleComparator.compare(arg0.getOuterWidth(), arg1.getOuterWidth());
-		}
-
-		if (doubleComparator.compare(arg0.getInnerWidth(), arg1.getInnerWidth()) != 0) {
-			logger.debug("Inner width different: " + arg0.getInnerWidth() + ", " + arg1.getInnerWidth());
-			return doubleComparator.compare(arg0.getInnerWidth(), arg1.getInnerWidth());
-		}
-
-		if (pointComparator.compare(arg0.getNamePoint(), arg1.getNamePoint()) != 0) {
-			logger.debug("NamePoint different: " + arg0.getNamePoint() + ", " + arg1.getNamePoint());
-			return pointComparator.compare(arg0.getNamePoint(), arg1.getNamePoint());
-		}
-
-		if (integerComparator.compare(arg0.getElements().size(), arg1.getElements().size()) != 0) {
-			logger.debug("Elements number different: " + arg0.getElements().size() + ", " + arg1.getElements().size());
-			return integerComparator.compare(arg0.getElements().size(), arg1.getElements().size());
-		}
-
-		Map<String, Element> map1 = new HashMap<>();
-		Map<String, Element> map2 = new HashMap<>();
-
-		for (Element element : arg0.getElements()) {
-			if (map1.get(element.getElementId()) != null) {
-				throw new InvalidArgumentException("Few elements with the same id: " + element.getElementId());
-			}
-			map1.put(element.getElementId(), element);
-		}
-
-		for (Element element : arg1.getElements()) {
-			if (map2.get(element.getElementId()) != null) {
-				throw new InvalidArgumentException("Few elements with the same id: " + element.getElementId());
-			}
-			map2.put(element.getElementId(), element);
-		}
-
-		for (Element element : arg0.getElements()) {
-			Element element2 = map2.get(element.getElementId());
-			int status = elementComparator.compare(element, element2);
-			if (status != 0) {
-				logger.debug("Couldn't match element: " + element.getElementId() + ", " + element2);
-				return status;
-			}
-		}
-
-		return 0;
-	}
+public class CompartmentComparator extends Comparator<Compartment> {
+
+  /**
+   * Default class logger.
+   */
+  private Logger logger = Logger.getLogger(CompartmentComparator.class);
+
+  /**
+   * Epsilon value used for comparison of doubles.
+   */
+  private double epsilon;
+
+  /**
+   * Constructor that requires {@link #epsilon} parameter.
+   * 
+   * @param epsilon
+   *          {@link #epsilon}
+   */
+  public CompartmentComparator(double epsilon) {
+    super(Compartment.class);
+    this.epsilon = epsilon;
+  }
+  
+  protected Comparator<?> getParentComparator() {
+    return new ElementComparator(epsilon);
+  }
+  
+
+  /**
+   * Default constructor.
+   */
+  public CompartmentComparator() {
+    this(Configuration.EPSILON);
+  }
+
+  @Override
+  protected int internalCompare(Compartment arg0, Compartment arg1) {
+    ElementComparator elementComparator = new ElementComparator(epsilon);
+    DoubleComparator doubleComparator = new DoubleComparator(epsilon);
+    IntegerComparator integerComparator = new IntegerComparator();
+    PointComparator pointComparator = new PointComparator(epsilon);
+
+    if (doubleComparator.compare(arg0.getThickness(), arg1.getThickness()) != 0) {
+      logger.debug("Thickness different: " + arg0.getThickness() + ", " + arg1.getThickness());
+      return doubleComparator.compare(arg0.getThickness(), arg1.getThickness());
+    }
+
+    if (doubleComparator.compare(arg0.getOuterWidth(), arg1.getOuterWidth()) != 0) {
+      logger.debug("Outer width different: " + arg0.getOuterWidth() + ", " + arg1.getOuterWidth());
+      return doubleComparator.compare(arg0.getOuterWidth(), arg1.getOuterWidth());
+    }
+
+    if (doubleComparator.compare(arg0.getInnerWidth(), arg1.getInnerWidth()) != 0) {
+      logger.debug("Inner width different: " + arg0.getInnerWidth() + ", " + arg1.getInnerWidth());
+      return doubleComparator.compare(arg0.getInnerWidth(), arg1.getInnerWidth());
+    }
+
+    if (pointComparator.compare(arg0.getNamePoint(), arg1.getNamePoint()) != 0) {
+      logger.debug("NamePoint different: " + arg0.getNamePoint() + ", " + arg1.getNamePoint());
+      return pointComparator.compare(arg0.getNamePoint(), arg1.getNamePoint());
+    }
+
+    if (integerComparator.compare(arg0.getElements().size(), arg1.getElements().size()) != 0) {
+      logger.debug("Elements number different: " + arg0.getElements().size() + ", " + arg1.getElements().size());
+      return integerComparator.compare(arg0.getElements().size(), arg1.getElements().size());
+    }
+
+    Map<String, Element> map1 = new HashMap<>();
+    Map<String, Element> map2 = new HashMap<>();
+
+    for (Element element : arg0.getElements()) {
+      if (map1.get(element.getElementId()) != null) {
+        throw new InvalidArgumentException("Few elements with the same id: " + element.getElementId());
+      }
+      map1.put(element.getElementId(), element);
+    }
+
+    for (Element element : arg1.getElements()) {
+      if (map2.get(element.getElementId()) != null) {
+        throw new InvalidArgumentException("Few elements with the same id: " + element.getElementId());
+      }
+      map2.put(element.getElementId(), element);
+    }
+
+    for (Element element : arg0.getElements()) {
+      Element element2 = map2.get(element.getElementId());
+      int status = elementComparator.compare(element, element2);
+      if (status != 0) {
+        logger.debug("Couldn't match element: " + element.getElementId() + ", " + element2);
+        return status;
+      }
+    }
+
+    return 0;
+  }
 }
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/graph/DataMiningSetComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/graph/DataMiningSetComparator.java
index faed93797389cd29ed81305b87b78290565e8e32..7cb3f086934b312e6b42a403e5f228ccfb7b5e5e 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/graph/DataMiningSetComparator.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/graph/DataMiningSetComparator.java
@@ -1,12 +1,10 @@
 package lcsb.mapviewer.model.map.graph;
 
-import java.util.Comparator;
-
 import org.apache.log4j.Logger;
 
+import lcsb.mapviewer.common.Comparator;
 import lcsb.mapviewer.common.Configuration;
 import lcsb.mapviewer.common.comparator.StringComparator;
-import lcsb.mapviewer.common.exception.NotImplementedException;
 
 /**
  * Comparator for {@link DataMiningSet} class.
@@ -14,78 +12,46 @@ import lcsb.mapviewer.common.exception.NotImplementedException;
  * @author Piotr Gawron
  * 
  */
-public class DataMiningSetComparator implements Comparator<DataMiningSet> {
-	/**
-	 * Default class logger.
-	 */
-	private Logger logger	= Logger.getLogger(DataMiningSetComparator.class);
-
-	/**
-	 * Epsilon value used for comparison of doubles.
-	 */
-	@SuppressWarnings("unused")
-	private double epsilon;
-
-	/**
-	 * Constructor that requires {@link #epsilon} parameter.
-	 * 
-	 * @param epsilon
-	 *          {@link #epsilon}
-	 */
-	public DataMiningSetComparator(double epsilon) {
-		this.epsilon = epsilon;
-	}
-
-	/**
-	 * Default constructor.
-	 */
-	public DataMiningSetComparator() {
-		this(Configuration.EPSILON);
-	}
-
-	@Override
-	public int compare(DataMiningSet arg0, DataMiningSet arg1) {
-		if (arg0 == null) {
-			if (arg1 == null) {
-				return 0;
-			} else {
-				return 1;
-			}
-		} else if (arg1 == null) {
-			return -1;
-		}
-
-		if (arg0.getClass().equals(arg1.getClass())) {
-			if (arg0.getClass() == DataMiningSet.class) {
-				return internalCompare(arg0, arg1);
-			} else {
-				throw new NotImplementedException("Don't know how to compare classes: " + arg0.getClass());
-			}
-		} else {
-			return -1;
-		}
-	}
-
-	/**
-	 * This method compares only the fields that are defined in
-	 * {@link DataMiningSet} class.
-	 * 
-	 * @param arg0
-	 *          first object to compare
-	 * @param arg1
-	 *          second object to compare
-	 * @return if all fields are qual then returns 0. If they are different then
-	 *         -1/1 is returned.
-	 */
-	private int internalCompare(DataMiningSet arg0, DataMiningSet arg1) {
-		StringComparator stringComparator = new StringComparator();
-
-		if (stringComparator.compare(arg0.getName(), arg1.getName()) != 0) {
-			logger.debug("Name different: " + arg0.getName() + ", " + arg1.getName());
-			return stringComparator.compare(arg0.getName(), arg1.getName());
-		}
-
-		return 0;
-	}
+public class DataMiningSetComparator extends Comparator<DataMiningSet> {
+  /**
+   * Default class logger.
+   */
+  private Logger logger = Logger.getLogger(DataMiningSetComparator.class);
+
+  /**
+   * Epsilon value used for comparison of doubles.
+   */
+  @SuppressWarnings("unused")
+  private double epsilon;
+
+  /**
+   * Constructor that requires {@link #epsilon} parameter.
+   * 
+   * @param epsilon
+   *          {@link #epsilon}
+   */
+  public DataMiningSetComparator(double epsilon) {
+    super(DataMiningSet.class, true);
+    this.epsilon = epsilon;
+  }
+
+  /**
+   * Default constructor.
+   */
+  public DataMiningSetComparator() {
+    this(Configuration.EPSILON);
+  }
+
+  @Override
+  protected int internalCompare(DataMiningSet arg0, DataMiningSet arg1) {
+    StringComparator stringComparator = new StringComparator();
+
+    if (stringComparator.compare(arg0.getName(), arg1.getName()) != 0) {
+      logger.debug("Name different: " + arg0.getName() + ", " + arg1.getName());
+      return stringComparator.compare(arg0.getName(), arg1.getName());
+    }
+
+    return 0;
+  }
 
 }
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/kinetics/SbmlKineticsComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/kinetics/SbmlKineticsComparator.java
new file mode 100644
index 0000000000000000000000000000000000000000..bee84ba436b5eca70e93e39edd477c841377f504
--- /dev/null
+++ b/model/src/main/java/lcsb/mapviewer/model/map/kinetics/SbmlKineticsComparator.java
@@ -0,0 +1,16 @@
+package lcsb.mapviewer.model.map.kinetics;
+
+import lcsb.mapviewer.common.Comparator;
+
+public class SbmlKineticsComparator extends Comparator<SbmlKinetics> {
+
+  public SbmlKineticsComparator() {
+    super(SbmlKinetics.class);
+  }
+
+  @Override
+  protected int internalCompare(SbmlKinetics arg0, SbmlKinetics arg1) {
+    return 0;
+  }
+
+}
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/layout/LayoutComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/layout/LayoutComparator.java
index 147590ff1e6c6fd7c39aea4a714c5d10de5a62be..30055b47f72cdec4a0ca6328ea213a61bd9b4825 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/layout/LayoutComparator.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/layout/LayoutComparator.java
@@ -1,11 +1,9 @@
 package lcsb.mapviewer.model.map.layout;
 
-import java.util.Comparator;
-
+import lcsb.mapviewer.common.Comparator;
 import lcsb.mapviewer.common.Configuration;
 import lcsb.mapviewer.common.comparator.BooleanComparator;
 import lcsb.mapviewer.common.comparator.StringComparator;
-import lcsb.mapviewer.common.exception.NotImplementedException;
 
 /**
  * This class implements comparator interface for Layout.
@@ -13,80 +11,48 @@ import lcsb.mapviewer.common.exception.NotImplementedException;
  * @author Piotr Gawron
  * 
  */
-public class LayoutComparator implements Comparator<Layout> {
-
-	/**
-	 * Epsilon value used for comparison of doubles.
-	 */
-	@SuppressWarnings("unused")
-	private double epsilon;
-
-	/**
-	 * Constructor that requires {@link #epsilon} parameter.
-	 * 
-	 * @param epsilon
-	 *          {@link #epsilon}
-	 */
-	public LayoutComparator(double epsilon) {
-		this.epsilon = epsilon;
-	}
-
-	/**
-	 * Default constructor.
-	 */
-	public LayoutComparator() {
-		this(Configuration.EPSILON);
-	}
-
-	/**
-	 * This method compares only the fields that are defined in {@link Layout}
-	 * class in inheritence tree.
-	 * 
-	 * @param arg0
-	 *          first object to compare
-	 * @param arg1
-	 *          second object to compare
-	 * @return if all fields are qual then returns 0. If they are different then
-	 *         -1/1 is returned.
-	 */
-	private int internalCompare(Layout arg0, Layout arg1) {
-		StringComparator stringComparator = new StringComparator();
-		BooleanComparator booleanComparator = new BooleanComparator();
-		if (stringComparator.compare(arg0.getDirectory(), arg1.getDirectory()) != 0) {
-			return stringComparator.compare(arg0.getDirectory(), arg1.getDirectory());
-		}
-		if (stringComparator.compare(arg0.getTitle(), arg1.getTitle()) != 0) {
-			return stringComparator.compare(arg0.getTitle(), arg1.getTitle());
-		}
-
-		if (booleanComparator.compare(arg0.isHierarchicalView(), arg1.isHierarchicalView()) != 0) {
-			return booleanComparator.compare(arg0.isHierarchicalView(), arg1.isHierarchicalView());
-		}
-
-		return 0;
-	}
-
-	@Override
-	public int compare(Layout arg0, Layout arg1) {
-		if (arg0 == null) {
-			if (arg1 == null) {
-				return 0;
-			} else {
-				return 1;
-			}
-		} else if (arg1 == null) {
-			return -1;
-		}
-
-		if (arg0.getClass().equals(arg1.getClass())) {
-			if (arg0.getClass() == Layout.class) {
-				return internalCompare(arg0, arg1);
-			} else {
-				throw new NotImplementedException("Don't know how to compare classes: " + arg0.getClass());
-			}
-		} else {
-			return -1;
-		}
-	}
+public class LayoutComparator extends Comparator<Layout> {
+
+  /**
+   * Epsilon value used for comparison of doubles.
+   */
+  @SuppressWarnings("unused")
+  private double epsilon;
+
+  /**
+   * Constructor that requires {@link #epsilon} parameter.
+   * 
+   * @param epsilon
+   *          {@link #epsilon}
+   */
+  public LayoutComparator(double epsilon) {
+    super(Layout.class, true);
+    this.epsilon = epsilon;
+  }
+
+  /**
+   * Default constructor.
+   */
+  public LayoutComparator() {
+    this(Configuration.EPSILON);
+  }
+
+  @Override
+  protected int internalCompare(Layout arg0, Layout arg1) {
+    StringComparator stringComparator = new StringComparator();
+    BooleanComparator booleanComparator = new BooleanComparator();
+    if (stringComparator.compare(arg0.getDirectory(), arg1.getDirectory()) != 0) {
+      return stringComparator.compare(arg0.getDirectory(), arg1.getDirectory());
+    }
+    if (stringComparator.compare(arg0.getTitle(), arg1.getTitle()) != 0) {
+      return stringComparator.compare(arg0.getTitle(), arg1.getTitle());
+    }
+
+    if (booleanComparator.compare(arg0.isHierarchicalView(), arg1.isHierarchicalView()) != 0) {
+      return booleanComparator.compare(arg0.isHierarchicalView(), arg1.isHierarchicalView());
+    }
+
+    return 0;
+  }
 
 }
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/layout/graphics/LayerComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/layout/graphics/LayerComparator.java
index 536b027b647877562981ceb1474e9071e34f40c6..8f842708acea2ad329ecb5f37d235c8c8dfc32c2 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/layout/graphics/LayerComparator.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/layout/graphics/LayerComparator.java
@@ -1,9 +1,8 @@
 package lcsb.mapviewer.model.map.layout.graphics;
 
-import java.util.Comparator;
-
 import org.apache.log4j.Logger;
 
+import lcsb.mapviewer.common.Comparator;
 import lcsb.mapviewer.common.Configuration;
 import lcsb.mapviewer.common.comparator.BooleanComparator;
 import lcsb.mapviewer.common.comparator.IntegerComparator;
@@ -12,153 +11,122 @@ import lcsb.mapviewer.common.exception.NotImplementedException;
 import lcsb.mapviewer.model.graphics.PolylineDataComparator;
 
 /**
- * Compparator of {@link Layer} class.
+ * Comparator of {@link Layer} class.
  * 
  * @author Piotr Gawron
  * 
  * 
  */
-public class LayerComparator implements Comparator<Layer> {
-
-	/**
-	 * Default class logger.
-	 */
-	private final Logger logger	= Logger.getLogger(LayerComparator.class);
-
-	/**
-	 * Epsilon value used for comparison of doubles.
-	 */
-	private double			 epsilon;
-
-	/**
-	 * Constructor that requires {@link #epsilon} parameter.
-	 * 
-	 * @param epsilon
-	 *          {@link #epsilon}
-	 */
-	public LayerComparator(double epsilon) {
-		this.epsilon = epsilon;
-	}
-
-	/**
-	 * Default constructor.
-	 */
-	public LayerComparator() {
-		this(Configuration.EPSILON);
-	}
-
-	@Override
-	public int compare(Layer arg0, Layer arg1) {
-		if (arg0 == null) {
-			if (arg1 == null) {
-				return 0;
-			} else {
-				return 1;
-			}
-		} else if (arg1 == null) {
-			return -1;
-		}
-
-		if (arg0.getClass().equals(arg1.getClass())) {
-			if (arg0.getClass().equals(Layer.class)) {
-				return internalCompare(arg0, arg1);
-			} else {
-				throw new NotImplementedException("Don't know how to compare classes: " + arg0.getClass());
-			}
-		} else {
-			return -1;
-		}
-	}
-
-	/**
-	 * This method compares all fields that are defined in Layer class.
-	 * 
-	 * @param arg0
-	 *          first object to compare
-	 * @param arg1
-	 *          second object to compare
-	 * @return if all fields are qual then returns 0. If they are different then
-	 *         -1/1 is returned.
-	 */
-	private int internalCompare(Layer arg0, Layer arg1) {
-		StringComparator stringComparator = new StringComparator();
-		BooleanComparator booleanComparator = new BooleanComparator();
-		IntegerComparator integerComparator = new IntegerComparator();
-
-		if (stringComparator.compare(arg0.getLayerId(), arg1.getLayerId()) != 0) {
-			logger.debug("layer ids different: " + arg0.getLayerId() + ", " + arg1.getLayerId());
-			return stringComparator.compare(arg0.getLayerId(), arg1.getLayerId());
-		}
-
-		if (stringComparator.compare(arg0.getName(), arg1.getName()) != 0) {
-			logger.debug("layer name different: " + arg0.getName() + ", " + arg1.getName());
-			return stringComparator.compare(arg0.getName(), arg1.getName());
-		}
-
-		if (booleanComparator.compare(arg0.isVisible(), arg1.isVisible()) != 0) {
-			logger.debug("layer visibility different: " + arg0.isVisible() + ", " + arg1.isVisible());
-			return booleanComparator.compare(arg0.isVisible(), arg1.isVisible());
-		}
-
-		if (booleanComparator.compare(arg0.isLocked(), arg1.isLocked()) != 0) {
-			logger.debug("layer locked different: " + arg0.isLocked() + ", " + arg1.isLocked());
-			return booleanComparator.compare(arg0.isLocked(), arg1.isLocked());
-		}
-
-		if (integerComparator.compare(arg0.getTexts().size(), arg1.getTexts().size()) != 0) {
-			logger.debug("layer texts different: " + arg0.getTexts().size() + ", " + arg1.getTexts().size());
-			return integerComparator.compare(arg0.getTexts().size(), arg1.getTexts().size());
-		}
-		if (integerComparator.compare(arg0.getLines().size(), arg1.getLines().size()) != 0) {
-			logger.debug("layer lines different: " + arg0.getLines().size() + ", " + arg1.getLines().size());
-			return integerComparator.compare(arg0.getLines().size(), arg1.getLines().size());
-		}
-		if (integerComparator.compare(arg0.getRectangles().size(), arg1.getRectangles().size()) != 0) {
-			logger.debug("layer rectangles different: " + arg0.getRectangles().size() + ", " + arg1.getRectangles().size());
-			return integerComparator.compare(arg0.getRectangles().size(), arg1.getRectangles().size());
-		}
-		if (integerComparator.compare(arg0.getOvals().size(), arg1.getOvals().size()) != 0) {
-			logger.debug("layer ovals different: " + arg0.getOvals().size() + ", " + arg1.getOvals().size());
-			return integerComparator.compare(arg0.getOvals().size(), arg1.getOvals().size());
-		}
-
-		LayerTextComparator textComparator = new LayerTextComparator(epsilon);
-		for (int i = 0; i < arg0.getTexts().size(); i++) {
-			int status = textComparator.compare(arg0.getTexts().get(i), arg1.getTexts().get(i));
-			if (status != 0) {
-				logger.debug("layer texts different");
-				return status;
-			}
-		}
-
-		LayerOvalComparator ovalComparator = new LayerOvalComparator(epsilon);
-		for (int i = 0; i < arg0.getOvals().size(); i++) {
-			int status = ovalComparator.compare(arg0.getOvals().get(i), arg1.getOvals().get(i));
-			if (status != 0) {
-				logger.debug("layer ovals different");
-				return status;
-			}
-		}
-
-		LayerRectComparator rectComparator = new LayerRectComparator(epsilon);
-		for (int i = 0; i < arg0.getRectangles().size(); i++) {
-			int status = rectComparator.compare(arg0.getRectangles().get(i), arg1.getRectangles().get(i));
-			if (status != 0) {
-				logger.debug("layer rectangles different ");
-				return status;
-			}
-		}
-
-		PolylineDataComparator lineComparator = new PolylineDataComparator(epsilon);
-		for (int i = 0; i < arg0.getLines().size(); i++) {
-			int status = lineComparator.compare(arg0.getLines().get(i), arg1.getLines().get(i));
-			if (status != 0) {
-				logger.debug("layer lines different ");
-				return status;
-			}
-		}
-
-		return 0;
-	}
+public class LayerComparator extends Comparator<Layer> {
+
+  /**
+   * Default class logger.
+   */
+  private final Logger logger = Logger.getLogger(LayerComparator.class);
+
+  /**
+   * Epsilon value used for comparison of doubles.
+   */
+  private double epsilon;
+
+  /**
+   * Constructor that requires {@link #epsilon} parameter.
+   * 
+   * @param epsilon
+   *          {@link #epsilon}
+   */
+  public LayerComparator(double epsilon) {
+    super(Layer.class, true);
+    this.epsilon = epsilon;
+  }
+
+  /**
+   * Default constructor.
+   */
+  public LayerComparator() {
+    this(Configuration.EPSILON);
+  }
+
+  @Override
+  protected int internalCompare(Layer arg0, Layer arg1) {
+    StringComparator stringComparator = new StringComparator();
+    BooleanComparator booleanComparator = new BooleanComparator();
+    IntegerComparator integerComparator = new IntegerComparator();
+
+    if (stringComparator.compare(arg0.getLayerId(), arg1.getLayerId()) != 0) {
+      logger.debug("layer ids different: " + arg0.getLayerId() + ", " + arg1.getLayerId());
+      return stringComparator.compare(arg0.getLayerId(), arg1.getLayerId());
+    }
+
+    if (stringComparator.compare(arg0.getName(), arg1.getName()) != 0) {
+      logger.debug("layer name different: " + arg0.getName() + ", " + arg1.getName());
+      return stringComparator.compare(arg0.getName(), arg1.getName());
+    }
+
+    if (booleanComparator.compare(arg0.isVisible(), arg1.isVisible()) != 0) {
+      logger.debug("layer visibility different: " + arg0.isVisible() + ", " + arg1.isVisible());
+      return booleanComparator.compare(arg0.isVisible(), arg1.isVisible());
+    }
+
+    if (booleanComparator.compare(arg0.isLocked(), arg1.isLocked()) != 0) {
+      logger.debug("layer locked different: " + arg0.isLocked() + ", " + arg1.isLocked());
+      return booleanComparator.compare(arg0.isLocked(), arg1.isLocked());
+    }
+
+    if (integerComparator.compare(arg0.getTexts().size(), arg1.getTexts().size()) != 0) {
+      logger.debug("layer texts different: " + arg0.getTexts().size() + ", " + arg1.getTexts().size());
+      return integerComparator.compare(arg0.getTexts().size(), arg1.getTexts().size());
+    }
+    if (integerComparator.compare(arg0.getLines().size(), arg1.getLines().size()) != 0) {
+      logger.debug("layer lines different: " + arg0.getLines().size() + ", " + arg1.getLines().size());
+      return integerComparator.compare(arg0.getLines().size(), arg1.getLines().size());
+    }
+    if (integerComparator.compare(arg0.getRectangles().size(), arg1.getRectangles().size()) != 0) {
+      logger.debug("layer rectangles different: " + arg0.getRectangles().size() + ", " + arg1.getRectangles().size());
+      return integerComparator.compare(arg0.getRectangles().size(), arg1.getRectangles().size());
+    }
+    if (integerComparator.compare(arg0.getOvals().size(), arg1.getOvals().size()) != 0) {
+      logger.debug("layer ovals different: " + arg0.getOvals().size() + ", " + arg1.getOvals().size());
+      return integerComparator.compare(arg0.getOvals().size(), arg1.getOvals().size());
+    }
+
+    LayerTextComparator textComparator = new LayerTextComparator(epsilon);
+    for (int i = 0; i < arg0.getTexts().size(); i++) {
+      int status = textComparator.compare(arg0.getTexts().get(i), arg1.getTexts().get(i));
+      if (status != 0) {
+        logger.debug("layer texts different");
+        return status;
+      }
+    }
+
+    LayerOvalComparator ovalComparator = new LayerOvalComparator(epsilon);
+    for (int i = 0; i < arg0.getOvals().size(); i++) {
+      int status = ovalComparator.compare(arg0.getOvals().get(i), arg1.getOvals().get(i));
+      if (status != 0) {
+        logger.debug("layer ovals different");
+        return status;
+      }
+    }
+
+    LayerRectComparator rectComparator = new LayerRectComparator(epsilon);
+    for (int i = 0; i < arg0.getRectangles().size(); i++) {
+      int status = rectComparator.compare(arg0.getRectangles().get(i), arg1.getRectangles().get(i));
+      if (status != 0) {
+        logger.debug("layer rectangles different ");
+        return status;
+      }
+    }
+
+    PolylineDataComparator lineComparator = new PolylineDataComparator(epsilon);
+    for (int i = 0; i < arg0.getLines().size(); i++) {
+      int status = lineComparator.compare(arg0.getLines().get(i), arg1.getLines().get(i));
+      if (status != 0) {
+        logger.debug("layer lines different ");
+        return status;
+      }
+    }
+
+    return 0;
+  }
 
 }
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/layout/graphics/LayerOvalComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/layout/graphics/LayerOvalComparator.java
index 2e005f1f1b16c451ccd832d51d2999ad91ef9a02..2ef01f855d2c5c4682dd0232b0a6cc4f3f8bee38 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/layout/graphics/LayerOvalComparator.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/layout/graphics/LayerOvalComparator.java
@@ -1,101 +1,68 @@
 package lcsb.mapviewer.model.map.layout.graphics;
 
-import java.util.Comparator;
-
+import lcsb.mapviewer.common.Comparator;
 import lcsb.mapviewer.common.Configuration;
 import lcsb.mapviewer.common.comparator.ColorComparator;
 import lcsb.mapviewer.common.comparator.DoubleComparator;
-import lcsb.mapviewer.common.exception.NotImplementedException;
 
 /**
- * Compparator of {@link LayerOval} class.
+ * Comparator of {@link LayerOval} class.
  * 
  * @author Piotr Gawron
  * 
  * 
  */
-public class LayerOvalComparator implements Comparator<LayerOval> {
-
-	/**
-	 * Epsilon value used for comparison of doubles.
-	 */
-	private double epsilon;
-
-	/**
-	 * Constructor that requires {@link #epsilon} parameter.
-	 * 
-	 * @param epsilon
-	 *          {@link #epsilon}
-	 */
-	public LayerOvalComparator(double epsilon) {
-		this.epsilon = epsilon;
-	}
-
-	/**
-	 * Default constructor.
-	 */
-	public LayerOvalComparator() {
-		this(Configuration.EPSILON);
-	}
-
-	/**
-	 * This method compares all fields that are defined in LayerOval class.
-	 * 
-	 * @param arg0
-	 *          first object to compare
-	 * @param arg1
-	 *          second object to compare
-	 * @return if all fields are qual then returns 0. If they are different then
-	 *         -1/1 is returned.
-	 */
-	private int internalCompare(LayerOval arg0, LayerOval arg1) {
-		DoubleComparator doubleComparator = new DoubleComparator(epsilon);
-		ColorComparator colorComparator = new ColorComparator();
-
-		if (doubleComparator.compare(arg0.getWidth(), arg1.getWidth()) != 0) {
-			return doubleComparator.compare(arg0.getWidth(), arg1.getWidth());
-		}
-
-		if (doubleComparator.compare(arg0.getHeight(), arg1.getHeight()) != 0) {
-			return doubleComparator.compare(arg0.getHeight(), arg1.getHeight());
-		}
-
-		if (doubleComparator.compare(arg0.getX(), arg1.getX()) != 0) {
-			return doubleComparator.compare(arg0.getX(), arg1.getX());
-		}
-
-		if (doubleComparator.compare(arg0.getY(), arg1.getY()) != 0) {
-			return doubleComparator.compare(arg0.getY(), arg1.getY());
-		}
-
-		if (colorComparator.compare(arg0.getColor(), arg1.getColor()) != 0) {
-			return colorComparator.compare(arg0.getColor(), arg1.getColor());
-		}
-
-		return 0;
-	}
-
-	@Override
-	public int compare(LayerOval arg0, LayerOval arg1) {
-		if (arg0 == null) {
-			if (arg1 == null) {
-				return 0;
-			} else {
-				return 1;
-			}
-		} else if (arg1 == null) {
-			return -1;
-		}
-
-		if (arg0.getClass().equals(arg1.getClass())) {
-			if (arg0.getClass().equals(LayerOval.class)) {
-				return internalCompare(arg0, arg1);
-			} else {
-				throw new NotImplementedException("Don't know how to compare classes: " + arg0.getClass());
-			}
-		} else {
-			return -1;
-		}
-	}
+public class LayerOvalComparator extends Comparator<LayerOval> {
+
+  /**
+   * Epsilon value used for comparison of doubles.
+   */
+  private double epsilon;
+
+  /**
+   * Constructor that requires {@link #epsilon} parameter.
+   * 
+   * @param epsilon
+   *          {@link #epsilon}
+   */
+  public LayerOvalComparator(double epsilon) {
+    super(LayerOval.class, true);
+    this.epsilon = epsilon;
+  }
+
+  /**
+   * Default constructor.
+   */
+  public LayerOvalComparator() {
+    this(Configuration.EPSILON);
+  }
+
+  @Override
+  protected int internalCompare(LayerOval arg0, LayerOval arg1) {
+    DoubleComparator doubleComparator = new DoubleComparator(epsilon);
+    ColorComparator colorComparator = new ColorComparator();
+
+    if (doubleComparator.compare(arg0.getWidth(), arg1.getWidth()) != 0) {
+      return doubleComparator.compare(arg0.getWidth(), arg1.getWidth());
+    }
+
+    if (doubleComparator.compare(arg0.getHeight(), arg1.getHeight()) != 0) {
+      return doubleComparator.compare(arg0.getHeight(), arg1.getHeight());
+    }
+
+    if (doubleComparator.compare(arg0.getX(), arg1.getX()) != 0) {
+      return doubleComparator.compare(arg0.getX(), arg1.getX());
+    }
+
+    if (doubleComparator.compare(arg0.getY(), arg1.getY()) != 0) {
+      return doubleComparator.compare(arg0.getY(), arg1.getY());
+    }
+
+    if (colorComparator.compare(arg0.getColor(), arg1.getColor()) != 0) {
+      return colorComparator.compare(arg0.getColor(), arg1.getColor());
+    }
+
+    return 0;
+  }
 
 }
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/layout/graphics/LayerRectComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/layout/graphics/LayerRectComparator.java
index 7d8f14d44263176b4aab77cf6a402eab80a43bcf..b945ac9e012ba0989b0a9fd159516f1547da0069 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/layout/graphics/LayerRectComparator.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/layout/graphics/LayerRectComparator.java
@@ -1,11 +1,9 @@
 package lcsb.mapviewer.model.map.layout.graphics;
 
-import java.util.Comparator;
-
+import lcsb.mapviewer.common.Comparator;
 import lcsb.mapviewer.common.Configuration;
 import lcsb.mapviewer.common.comparator.ColorComparator;
 import lcsb.mapviewer.common.comparator.DoubleComparator;
-import lcsb.mapviewer.common.exception.NotImplementedException;
 
 /**
  * Compparator of {@link LayerRect} class.
@@ -14,88 +12,57 @@ import lcsb.mapviewer.common.exception.NotImplementedException;
  * 
  * 
  */
-public class LayerRectComparator implements Comparator<LayerRect> {
-
-	/**
-	 * Epsilon value used for comparison of doubles.
-	 */
-	private double epsilon;
-
-	/**
-	 * Constructor that requires {@link #epsilon} parameter.
-	 * 
-	 * @param epsilon
-	 *          {@link #epsilon}
-	 */
-	public LayerRectComparator(double epsilon) {
-		this.epsilon = epsilon;
-	}
-
-	/**
-	 * Default constructor.
-	 */
-	public LayerRectComparator() {
-		this(Configuration.EPSILON);
-	}
-
-	/**
-	 * This method compares all fields that are defined in LayerRect class.
-	 * 
-	 * @param arg0
-	 *          first object to compare
-	 * @param arg1
-	 *          second object to compare
-	 * @return if all fields are qual then returns 0. If they are different then
-	 *         -1/1 is returned.
-	 */
-	private int internalCompare(LayerRect arg0, LayerRect arg1) {
-		DoubleComparator doubleComparator = new DoubleComparator(epsilon);
-		ColorComparator colorComparator = new ColorComparator();
-
-		if (doubleComparator.compare(arg0.getWidth(), arg1.getWidth()) != 0) {
-			return doubleComparator.compare(arg0.getWidth(), arg1.getWidth());
-		}
-
-		if (doubleComparator.compare(arg0.getHeight(), arg1.getHeight()) != 0) {
-			return doubleComparator.compare(arg0.getHeight(), arg1.getHeight());
-		}
-
-		if (doubleComparator.compare(arg0.getX(), arg1.getX()) != 0) {
-			return doubleComparator.compare(arg0.getX(), arg1.getX());
-		}
-
-		if (doubleComparator.compare(arg0.getY(), arg1.getY()) != 0) {
-			return doubleComparator.compare(arg0.getY(), arg1.getY());
-		}
-
-		if (colorComparator.compare(arg0.getColor(), arg1.getColor()) != 0) {
-			return colorComparator.compare(arg0.getColor(), arg1.getColor());
-		}
-
-		return 0;
-	}
-
-	@Override
-	public int compare(LayerRect arg0, LayerRect arg1) {
-		if (arg0 == null) {
-			if (arg1 == null) {
-				return 0;
-			} else {
-				return 1;
-			}
-		} else if (arg1 == null) {
-			return -1;
-		}
-
-		if (arg0.getClass().equals(arg1.getClass())) {
-			if (arg0.getClass().equals(LayerRect.class)) {
-				return internalCompare(arg0, arg1);
-			} else {
-				throw new NotImplementedException("Don't know how to compare classes: " + arg0.getClass());
-			}
-		} else {
-			return -1;
-		}
-	}
+public class LayerRectComparator extends Comparator<LayerRect> {
+
+  /**
+   * Epsilon value used for comparison of doubles.
+   */
+  private double epsilon;
+
+  /**
+   * Constructor that requires {@link #epsilon} parameter.
+   * 
+   * @param epsilon
+   *          {@link #epsilon}
+   */
+  public LayerRectComparator(double epsilon) {
+    super(LayerRect.class, true);
+    this.epsilon = epsilon;
+  }
+
+  /**
+   * Default constructor.
+   */
+  public LayerRectComparator() {
+    this(Configuration.EPSILON);
+  }
+
+  @Override
+  protected int internalCompare(LayerRect arg0, LayerRect arg1) {
+    DoubleComparator doubleComparator = new DoubleComparator(epsilon);
+    ColorComparator colorComparator = new ColorComparator();
+
+    if (doubleComparator.compare(arg0.getWidth(), arg1.getWidth()) != 0) {
+      return doubleComparator.compare(arg0.getWidth(), arg1.getWidth());
+    }
+
+    if (doubleComparator.compare(arg0.getHeight(), arg1.getHeight()) != 0) {
+      return doubleComparator.compare(arg0.getHeight(), arg1.getHeight());
+    }
+
+    if (doubleComparator.compare(arg0.getX(), arg1.getX()) != 0) {
+      return doubleComparator.compare(arg0.getX(), arg1.getX());
+    }
+
+    if (doubleComparator.compare(arg0.getY(), arg1.getY()) != 0) {
+      return doubleComparator.compare(arg0.getY(), arg1.getY());
+    }
+
+    if (colorComparator.compare(arg0.getColor(), arg1.getColor()) != 0) {
+      return colorComparator.compare(arg0.getColor(), arg1.getColor());
+    }
+
+    return 0;
+  }
 
 }
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/layout/graphics/LayerTextComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/layout/graphics/LayerTextComparator.java
index 8f35b4040c6c5c874c69611aea62c957dab8186e..d0371804acbe2519215c5b42e6e9638abd4d7d6a 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/layout/graphics/LayerTextComparator.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/layout/graphics/LayerTextComparator.java
@@ -1,12 +1,10 @@
 package lcsb.mapviewer.model.map.layout.graphics;
 
-import java.util.Comparator;
-
+import lcsb.mapviewer.common.Comparator;
 import lcsb.mapviewer.common.Configuration;
 import lcsb.mapviewer.common.comparator.ColorComparator;
 import lcsb.mapviewer.common.comparator.DoubleComparator;
 import lcsb.mapviewer.common.comparator.StringComparator;
-import lcsb.mapviewer.common.exception.NotImplementedException;
 
 /**
  * Compparator of {@link LayerText} class.
@@ -15,97 +13,66 @@ import lcsb.mapviewer.common.exception.NotImplementedException;
  * 
  * 
  */
-public class LayerTextComparator implements Comparator<LayerText> {
-
-	/**
-	 * Epsilon value used for comparison of doubles.
-	 */
-	private double epsilon;
-
-	/**
-	 * Constructor that requires {@link #epsilon} parameter.
-	 * 
-	 * @param epsilon
-	 *          {@link #epsilon}
-	 */
-	public LayerTextComparator(double epsilon) {
-		this.epsilon = epsilon;
-	}
-
-	/**
-	 * Default constructor.
-	 */
-	public LayerTextComparator() {
-		this(Configuration.EPSILON);
-	}
-
-	/**
-	 * This method compares all fields that are defined in LayerText class.
-	 * 
-	 * @param arg0
-	 *          first object to compare
-	 * @param arg1
-	 *          second object to compare
-	 * @return if all fields are qual then returns 0. If they are different then
-	 *         -1/1 is returned.
-	 */
-	private int internalCompare(LayerText arg0, LayerText arg1) {
-		DoubleComparator doubleComparator = new DoubleComparator(epsilon);
-		StringComparator stringComparator = new StringComparator();
-		ColorComparator colorComparator = new ColorComparator();
-
-		if (doubleComparator.compare(arg0.getWidth(), arg1.getWidth()) != 0) {
-			return doubleComparator.compare(arg0.getWidth(), arg1.getWidth());
-		}
-
-		if (doubleComparator.compare(arg0.getHeight(), arg1.getHeight()) != 0) {
-			return doubleComparator.compare(arg0.getHeight(), arg1.getHeight());
-		}
-
-		if (doubleComparator.compare(arg0.getX(), arg1.getX()) != 0) {
-			return doubleComparator.compare(arg0.getX(), arg1.getX());
-		}
-
-		if (doubleComparator.compare(arg0.getY(), arg1.getY()) != 0) {
-			return doubleComparator.compare(arg0.getY(), arg1.getY());
-		}
-
-		if (colorComparator.compare(arg0.getColor(), arg1.getColor()) != 0) {
-			return colorComparator.compare(arg0.getColor(), arg1.getColor());
-		}
-
-		if (stringComparator.compare(arg0.getNotes(), arg1.getNotes()) != 0) {
-			return stringComparator.compare(arg0.getNotes(), arg1.getNotes());
-		}
-
-		if (doubleComparator.compare(arg0.getFontSize(), arg1.getFontSize()) != 0) {
-			return doubleComparator.compare(arg0.getFontSize(), arg1.getFontSize());
-		}
-
-		return 0;
-	}
-
-	@Override
-	public int compare(LayerText arg0, LayerText arg1) {
-		if (arg0 == null) {
-			if (arg1 == null) {
-				return 0;
-			} else {
-				return 1;
-			}
-		} else if (arg1 == null) {
-			return -1;
-		}
-
-		if (arg0.getClass().equals(arg1.getClass())) {
-			if (arg0.getClass().equals(LayerText.class)) {
-				return internalCompare(arg0, arg1);
-			} else {
-				throw new NotImplementedException("Don't know how to compare classes: " + arg0.getClass());
-			}
-		} else {
-			return -1;
-		}
-	}
+public class LayerTextComparator extends Comparator<LayerText> {
+
+  /**
+   * Epsilon value used for comparison of doubles.
+   */
+  private double epsilon;
+
+  /**
+   * Constructor that requires {@link #epsilon} parameter.
+   * 
+   * @param epsilon
+   *          {@link #epsilon}
+   */
+  public LayerTextComparator(double epsilon) {
+    super(LayerText.class, true);
+    this.epsilon = epsilon;
+  }
+
+  /**
+   * Default constructor.
+   */
+  public LayerTextComparator() {
+    this(Configuration.EPSILON);
+  }
+
+  @Override
+  protected int internalCompare(LayerText arg0, LayerText arg1) {
+    DoubleComparator doubleComparator = new DoubleComparator(epsilon);
+    StringComparator stringComparator = new StringComparator();
+    ColorComparator colorComparator = new ColorComparator();
+
+    if (doubleComparator.compare(arg0.getWidth(), arg1.getWidth()) != 0) {
+      return doubleComparator.compare(arg0.getWidth(), arg1.getWidth());
+    }
+
+    if (doubleComparator.compare(arg0.getHeight(), arg1.getHeight()) != 0) {
+      return doubleComparator.compare(arg0.getHeight(), arg1.getHeight());
+    }
+
+    if (doubleComparator.compare(arg0.getX(), arg1.getX()) != 0) {
+      return doubleComparator.compare(arg0.getX(), arg1.getX());
+    }
+
+    if (doubleComparator.compare(arg0.getY(), arg1.getY()) != 0) {
+      return doubleComparator.compare(arg0.getY(), arg1.getY());
+    }
+
+    if (colorComparator.compare(arg0.getColor(), arg1.getColor()) != 0) {
+      return colorComparator.compare(arg0.getColor(), arg1.getColor());
+    }
+
+    if (stringComparator.compare(arg0.getNotes(), arg1.getNotes()) != 0) {
+      return stringComparator.compare(arg0.getNotes(), arg1.getNotes());
+    }
+
+    if (doubleComparator.compare(arg0.getFontSize(), arg1.getFontSize()) != 0) {
+      return doubleComparator.compare(arg0.getFontSize(), arg1.getFontSize());
+    }
+
+    return 0;
+  }
 
 }
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/model/ElementSubmodelConnectionComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/model/ElementSubmodelConnectionComparator.java
index c1709b3a29d3298dc9e184fa522981e01710745b..15f64f78e1473d8dfd8ffcd64db8cfe042ae4b49 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/model/ElementSubmodelConnectionComparator.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/model/ElementSubmodelConnectionComparator.java
@@ -1,113 +1,81 @@
 package lcsb.mapviewer.model.map.model;
 
-import java.util.Comparator;
+import org.apache.log4j.Logger;
 
+import lcsb.mapviewer.common.Comparator;
 import lcsb.mapviewer.common.Configuration;
 import lcsb.mapviewer.model.map.species.Element;
 import lcsb.mapviewer.model.map.species.ElementComparator;
 
-import org.apache.log4j.Logger;
-
 /**
- * This class implements comparator interface for {@link ElementSubmodelConnection}. 
+ * This class implements comparator interface for
+ * {@link ElementSubmodelConnection}.
  * 
  * @author Piotr Gawron
  * 
  */
-public class ElementSubmodelConnectionComparator implements Comparator<ElementSubmodelConnection> {
-	
-	/**
-	 * Default class logger.
-	 */
-	private static Logger	logger	= Logger.getLogger(ElementSubmodelConnectionComparator.class);
-
-	/**
-	 * Epsilon value used for comparison of doubles.
-	 */
-	private double				epsilon;
+public class ElementSubmodelConnectionComparator extends Comparator<ElementSubmodelConnection> {
 
-	/**
-	 * Constructor that requires {@link #epsilon} parameter.
-	 * 
-	 * @param epsilon
-	 *          {@link #epsilon}
-	 */
-	public ElementSubmodelConnectionComparator(double epsilon) {
-		this.epsilon = epsilon;
-	}
+  /**
+   * Default class logger.
+   */
+  private static Logger logger = Logger.getLogger(ElementSubmodelConnectionComparator.class);
 
-	/**
-	 * Default constructor.
-	 */
-	public ElementSubmodelConnectionComparator() {
-		this(Configuration.EPSILON);
-	}
+  /**
+   * Epsilon value used for comparison of doubles.
+   */
+  private double epsilon;
 
-	@Override
-	public int compare(ElementSubmodelConnection arg0, ElementSubmodelConnection arg1) {
-		if (arg0 == null) {
-			if (arg1 == null) {
-				return 0;
-			} else {
-				return 1;
-			}
-		} else if (arg1 == null) {
-			return -1;
-		}
+  /**
+   * Constructor that requires {@link #epsilon} parameter.
+   * 
+   * @param epsilon
+   *          {@link #epsilon}
+   */
+  public ElementSubmodelConnectionComparator(double epsilon) {
+    super(ElementSubmodelConnection.class);
+    this.epsilon = epsilon;
+  }
 
-		if (arg0.getClass().equals(arg1.getClass())) {
-			return internalCompare(arg0, arg1);
-		} else {
-			logger.debug("class different: " + arg0.getClass() + ", " + arg1.getClass());
-			return -1;
-		}
-	}
+  /**
+   * Default constructor.
+   */
+  public ElementSubmodelConnectionComparator() {
+    this(Configuration.EPSILON);
+  }
 
-	/**
-	 * This method compares only the fields that are defined in
-	 * {@link ElementSubmodelConnection} class in inheritence tree. It also calls
-	 * the {@link SubmodelConnectionComparator} for the super class (
-	 * {@link SubmodelConnection}).
-	 * 
-	 * @param arg0
-	 *          first object to compare
-	 * @param arg1
-	 *          second object to compare
-	 * @return if all fields are qual then returns 0. If they are different then
-	 *         -1/1 is returned.
-	 */
-	public int internalCompare(ElementSubmodelConnection arg0, ElementSubmodelConnection arg1) {
-		SubmodelConnectionComparator superComparator = new SubmodelConnectionComparator(epsilon);
+  @Override
+  protected Comparator<?> getParentComparator() {
+    return new SubmodelConnectionComparator(epsilon);
+  }
 
-		int result = superComparator.internalCompare(arg0, arg1);
-		if (result != 0) {
-			return result;
-		}
-		ElementComparator elementComparator = new ElementComparator(epsilon);
-		Element element1 = arg0.getFromElement();
-		Element element2 = arg1.getFromElement();
-		arg0.setFromElement(null);
-		arg1.setFromElement(null);
-		int status = elementComparator.compare(element1, element2);
-		arg0.setFromElement(element1);
-		arg1.setFromElement(element2);
-		if (status != 0) {
-			logger.debug("from element different: " + arg0.getFromElement() + ", " + arg1.getFromElement());
-			return status;
-		}
-		element1 = arg0.getToElement();
-		element2 = arg1.getToElement();
-		arg0.setToElement(null);
-		arg1.setToElement(null);
-		status = elementComparator.compare(element1, element2);
-		arg0.setToElement(element1);
-		arg1.setToElement(element2);
-		if (status != 0) {
-			logger.debug("to element different: " + arg0.getToElement() + ", " + arg1.getToElement());
-			return status;
-		}
+  @Override
+  protected int internalCompare(ElementSubmodelConnection arg0, ElementSubmodelConnection arg1) {
+    ElementComparator elementComparator = new ElementComparator(epsilon);
+    Element element1 = arg0.getFromElement();
+    Element element2 = arg1.getFromElement();
+    arg0.setFromElement(null);
+    arg1.setFromElement(null);
+    int status = elementComparator.compare(element1, element2);
+    arg0.setFromElement(element1);
+    arg1.setFromElement(element2);
+    if (status != 0) {
+      logger.debug("from element different: " + arg0.getFromElement() + ", " + arg1.getFromElement());
+      return status;
+    }
+    element1 = arg0.getToElement();
+    element2 = arg1.getToElement();
+    arg0.setToElement(null);
+    arg1.setToElement(null);
+    status = elementComparator.compare(element1, element2);
+    arg0.setToElement(element1);
+    arg1.setToElement(element2);
+    if (status != 0) {
+      logger.debug("to element different: " + arg0.getToElement() + ", " + arg1.getToElement());
+      return status;
+    }
 
-		return 0;
-	}
+    return 0;
+  }
 
 }
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/model/ModelComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/model/ModelComparator.java
index cd1fee24d3d0081760c6e74233f7871b2ad606ae..dc8eb6f002c64b30c22fa122b153c01e1abeeca1 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/model/ModelComparator.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/model/ModelComparator.java
@@ -1,7 +1,6 @@
 package lcsb.mapviewer.model.map.model;
 
 import java.util.Collection;
-import java.util.Comparator;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -9,6 +8,7 @@ import java.util.Set;
 
 import org.apache.log4j.Logger;
 
+import lcsb.mapviewer.common.Comparator;
 import lcsb.mapviewer.common.Configuration;
 import lcsb.mapviewer.common.comparator.DoubleComparator;
 import lcsb.mapviewer.common.comparator.IntegerComparator;
@@ -29,377 +29,352 @@ import lcsb.mapviewer.model.map.species.ElementComparator;
  * @author Piotr Gawron
  * 
  */
-public class ModelComparator implements Comparator<Model> {
-	/**
-	 * Default class logger.
-	 */
-	private Logger logger	= Logger.getLogger(ModelComparator.class);
-
-	/**
-	 * Epsilon value used for comparison of doubles.
-	 */
-	private double epsilon;
-
-	/**
-	 * Constructor that requires {@link #epsilon} parameter.
-	 * 
-	 * @param epsilon
-	 *          {@link #epsilon}
-	 */
-	public ModelComparator(double epsilon) {
-		this.epsilon = epsilon;
-	}
-
-	/**
-	 * Default constructor.
-	 */
-	public ModelComparator() {
-		this(Configuration.EPSILON);
-	}
-
-	@Override
-	public int compare(Model arg0, Model arg1) {
-		if (arg0 == null) {
-			if (arg1 == null) {
-				return 0;
-			} else {
-				return 1;
-			}
-		} else if (arg1 == null) {
-			return -1;
-		}
-
-		if (arg0.getClass().equals(arg1.getClass())) {
-			return internalCompare(arg0, arg1);
-		} else {
-			return -1;
-		}
-	}
-
-	/**
-	 * This method compares only the fields that are defined in {@link Model}
-	 * class.
-	 * 
-	 * @param arg0
-	 *          first object to compare
-	 * @param arg1
-	 *          second object to compare
-	 * @return if all fields are equal then returns 0. If they are different then
-	 *         -1/1 is returned.
-	 */
-	private int internalCompare(Model arg0, Model arg1) {
-		StringComparator stringComparator = new StringComparator();
-		DoubleComparator doubleComparator = new DoubleComparator(epsilon);
-		IntegerComparator integerComparator = new IntegerComparator();
-
-		if (stringComparator.compare(arg0.getIdModel(), arg1.getIdModel()) != 0) {
-			logger.debug("Id different: " + arg0.getIdModel() + ", " + arg1.getIdModel());
-			return stringComparator.compare(arg0.getIdModel(), arg1.getIdModel());
-		}
-
-		if (stringComparator.compare(arg0.getName(), arg1.getName()) != 0) {
-			logger.debug("Name different: " + arg0.getName() + ", " + arg1.getName());
-			return stringComparator.compare(arg0.getName(), arg1.getName());
-		}
-
-		if (stringComparator.compare(arg0.getNotes(), arg1.getNotes(), true) != 0) {
-			logger.debug(arg0.getNotes());
-			logger.debug(arg1.getNotes());
-			logger.debug("Notes different:\n" + arg0.getNotes() + "\n---\n" + arg1.getNotes() + "\n---");
-			return stringComparator.compare(arg0.getNotes(), arg1.getNotes(), true);
-		}
-
-		if (doubleComparator.compare(arg0.getWidth(), arg1.getWidth()) != 0) {
-			logger.debug("Width different: " + arg0.getWidth() + ", " + arg1.getWidth());
-			return doubleComparator.compare(arg0.getWidth(), arg1.getWidth());
-		}
-
-		if (doubleComparator.compare(arg0.getHeight(), arg1.getHeight()) != 0) {
-			logger.debug("Height different: " + arg0.getHeight() + ", " + arg1.getHeight());
-			return doubleComparator.compare(arg0.getHeight(), arg1.getHeight());
-		}
-
-		if (integerComparator.compare(arg0.getZoomLevels(), arg1.getZoomLevels()) != 0) {
-			logger.debug("Zoom levels different: " + arg0.getZoomLevels() + ", " + arg1.getZoomLevels());
-			return integerComparator.compare(arg0.getZoomLevels(), arg1.getZoomLevels());
-		}
-
-		if (integerComparator.compare(arg0.getTileSize(), arg1.getTileSize()) != 0) {
-			logger.debug("Tile size different: " + arg0.getTileSize() + ", " + arg1.getTileSize());
-			return integerComparator.compare(arg0.getTileSize(), arg1.getTileSize());
-		}
-
-		int status = compareElements(arg0.getElements(), arg1.getElements());
-		if (status != 0) {
-			logger.debug("Set of elements different");
-			return status;
-		}
-
-		status = compareLayers(arg0.getLayers(), arg1.getLayers());
-		if (status != 0) {
-			logger.debug("Set of layers different");
-			return status;
-		}
-
-		status = compareReaction(arg0.getReactions(), arg1.getReactions());
-		if (status != 0) {
-			logger.debug("Set of reactions different");
-			return status;
-		}
-
-		status = compareLayouts(arg0.getLayouts(), arg1.getLayouts());
-		if (status != 0) {
-			logger.debug("Set of layouts different");
-			return status;
-		}
-
-		status = compareSubmodels(arg0.getSubmodelConnections(), arg1.getSubmodelConnections());
-		if (status != 0) {
-			logger.debug("Set of submodels different");
-			return status;
-		}
-
-		status = integerComparator.compare(arg0.getDataMiningSets().size(), arg1.getDataMiningSets().size());
-		if (status != 0) {
-			logger.debug("Set of data mining sets different");
-			return status;
-		}
-		DataMiningSetComparator dataMiningSetComparator = new DataMiningSetComparator();
-		for (int i = 0; i < arg0.getDataMiningSets().size(); i++) {
-			status = dataMiningSetComparator.compare(arg0.getDataMiningSets().get(i), arg1.getDataMiningSets().get(i));
-			if (status != 0) {
-				logger.debug("Set of data mining sets different");
-				return status;
-			}
-
-		}
-		return 0;
-	}
-
-	/**
-	 * Compares two set of reactions.
-	 * 
-	 * @param reactions
-	 *          first set of reactions
-	 * @param reactions2
-	 *          second set of reactions
-	 * @return if sets are equal then returns 0. If they are different then -1/1
-	 *         is returned.
-	 */
-	private int compareReaction(Set<Reaction> reactions, Set<Reaction> reactions2) {
-		ReactionComparator comparator = new ReactionComparator(epsilon);
-
-		Map<String, Reaction> map = new HashMap<String, Reaction>();
-		Map<String, Reaction> map2 = new HashMap<String, Reaction>();
-
-		for (Reaction reaction : reactions) {
-			map.put(reaction.getIdReaction(), reaction);
-		}
-		for (Reaction reaction : reactions2) {
-			map2.put(reaction.getIdReaction(), reaction);
-		}
-
-		for (Reaction reaction : reactions) {
-			int status = comparator.compare(reaction, map2.get(reaction.getIdReaction()));
-			if (status != 0) {
-				logger.debug("Different reaction " + reaction.getIdReaction() + ": " + map2.get(reaction.getIdReaction()));
-				return status;
-			}
-		}
-
-		for (Reaction reaction : reactions2) {
-			int status = comparator.compare(reaction, map.get(reaction.getIdReaction()));
-			if (status != 0) {
-				logger.debug("Different reaction " + reaction.getIdReaction());
-				return status;
-			}
-		}
-		return 0;
-	}
-
-	/**
-	 * Compares two sets of layers.
-	 * 
-	 * @param layers
-	 *          first set of layers
-	 * @param layers2
-	 *          second set of layers
-	 * @return if sets are equal then returns 0. If they are different then -1/1
-	 *         is returned.
-	 */
-	private int compareLayers(Set<Layer> layers, Set<Layer> layers2) {
-		LayerComparator layerComparator = new LayerComparator(epsilon);
-		for (Layer layer : layers) {
-			boolean found = false;
-			for (Layer layer2 : layers2) {
-				if (layerComparator.compare(layer, layer2) == 0) {
-					found = true;
-				}
-			}
-			if (!found) {
-				return 1;
-			}
-		}
-		for (Layer layer : layers2) {
-			boolean found = false;
-			for (Layer layer2 : layers) {
-				if (layerComparator.compare(layer, layer2) == 0) {
-					found = true;
-				}
-			}
-			if (!found) {
-				return -1;
-			}
-		}
-		return 0;
-	}
-
-	/**
-	 * Compares two sets of layouts.
-	 * 
-	 * @param layouts
-	 *          first set of layouts
-	 * @param layouts2
-	 *          second set of layouts
-	 * @return if sets are equal then returns 0. If they are different then -1/1
-	 *         is returned.
-	 */
-	private int compareLayouts(List<Layout> layouts, List<Layout> layouts2) {
-		LayoutComparator layoutComparator = new LayoutComparator(epsilon);
-		for (Layout layout : layouts) {
-			boolean found = false;
-			for (Layout layout2 : layouts2) {
-				if (layoutComparator.compare(layout, layout2) == 0) {
-					found = true;
-				}
-			}
-			if (!found) {
-				return 1;
-			}
-		}
-		for (Layout layout : layouts2) {
-			boolean found = false;
-			for (Layout layout2 : layouts) {
-				if (layoutComparator.compare(layout, layout2) == 0) {
-					found = true;
-				}
-			}
-			if (!found) {
-				return -1;
-			}
-		}
-		return 0;
-	}
-
-	/**
-	 * Compares two sets of elements.
-	 * 
-	 * @param elements
-	 *          first set of elements
-	 * @param elements2
-	 *          second set of elements
-	 * @return if sets are equal then returns 0. If they are different then -1/1
-	 *         is returned.
-	 */
-	private int compareElements(Set<Element> elements, Set<Element> elements2) {
-		ElementComparator elementComparator = new ElementComparator(epsilon);
-
-		Map<String, Element> map1 = new HashMap<>();
-		Map<String, Element> map2 = new HashMap<>();
-
-		if (elements.size() != elements2.size()) {
-			logger.debug("Number of elements different: " + elements.size() + ", " + elements2.size());
-			return ((Integer) elements.size()).compareTo(elements2.size());
-		}
-
-		for (Element element : elements) {
-			map1.put(element.getElementId(), element);
-		}
-
-		for (Element element : elements2) {
-			map2.put(element.getElementId(), element);
-		}
-
-		for (Element element : elements) {
-			int status = elementComparator.compare(element, map2.get(element.getElementId()));
-			if (status != 0) {
-				logger.debug("Element doesn't have a match: " + element.getElementId() + ", " + map2.get(element.getElementId()));
-				return status;
-			}
-		}
-
-		for (Element element : elements2) {
-			int status = elementComparator.compare(element, map1.get(element.getElementId()));
-			if (status != 0) {
-				logger.debug("Element doesn't have a match: " + element.getElementId() + ", " + map2.get(element.getElementId()));
-				return status;
-			}
-		}
-		return 0;
-	}
-
-	/**
-	 * Compares two collection of models.
-	 * 
-	 * @param collection1
-	 *          first collection to compare
-	 * @param collection2
-	 *          second collection to compare
-	 * @return 0 if the collections are identical, -1/1 otherwise
-	 */
-	private int compareSubmodels(Collection<ModelSubmodelConnection> collection1, Collection<ModelSubmodelConnection> collection2) {
-		IntegerComparator integerComparator = new IntegerComparator();
-		if (integerComparator.compare(collection1.size(), collection2.size()) != 0) {
-			logger.debug("collection of submodels doesn't match: " + collection1.size() + ", " + collection2.size());
-			return integerComparator.compare(collection1.size(), collection2.size());
-		}
-		ModelSubmodelConnectionComparator comparator = new ModelSubmodelConnectionComparator(epsilon);
-		for (ModelSubmodelConnection submodel1 : collection1) {
-			boolean found = false;
-			for (ModelSubmodelConnection submodel2 : collection2) {
-				ModelData parent1 = submodel1.getParentModel();
-				submodel1.setParentModel((ModelData) null);
-				ModelData parent2 = submodel2.getParentModel();
-				submodel2.setParentModel((ModelData) null);
-
-				if (comparator.compare(submodel1, submodel2) == 0) {
-					found = true;
-				}
-				submodel1.setParentModel(parent1);
-				submodel2.setParentModel(parent2);
-				if (found) {
-					break;
-				}
-			}
-			if (!found) {
-				logger.debug("collection of submodels doesn't match. " + submodel1 + " cannot be found in the second model");
-				return 1;
-			}
-		}
-
-		for (ModelSubmodelConnection submodel1 : collection2) {
-			boolean found = false;
-			for (ModelSubmodelConnection submodel2 : collection1) {
-				ModelData parent1 = submodel1.getParentModel();
-				submodel1.setParentModel((ModelData) null);
-				ModelData parent2 = submodel2.getParentModel();
-				submodel2.setParentModel((ModelData) null);
-
-				if (comparator.compare(submodel1, submodel2) == 0) {
-					found = true;
-				}
-				submodel1.setParentModel(parent1);
-				submodel2.setParentModel(parent2);
-				if (found) {
-					break;
-				}
-			}
-			if (!found) {
-				logger.debug("collection of submodels doesn't match. " + submodel1 + " cannot be found in the first model");
-				return -1;
-			}
-		}
-
-		return 0;
-	}
+public class ModelComparator extends Comparator<Model> {
+  /**
+   * Default class logger.
+   */
+  private Logger logger = Logger.getLogger(ModelComparator.class);
+
+  /**
+   * Epsilon value used for comparison of doubles.
+   */
+  private double epsilon;
+
+  /**
+   * Constructor that requires {@link #epsilon} parameter.
+   * 
+   * @param epsilon
+   *          {@link #epsilon}
+   */
+  public ModelComparator(double epsilon) {
+    super(Model.class);
+    this.epsilon = epsilon;
+  }
+
+  /**
+   * Default constructor.
+   */
+  public ModelComparator() {
+    this(Configuration.EPSILON);
+  }
+
+  @Override
+  protected int internalCompare(Model arg0, Model arg1) {
+    StringComparator stringComparator = new StringComparator();
+    DoubleComparator doubleComparator = new DoubleComparator(epsilon);
+    IntegerComparator integerComparator = new IntegerComparator();
+
+    if (stringComparator.compare(arg0.getIdModel(), arg1.getIdModel()) != 0) {
+      logger.debug("Id different: " + arg0.getIdModel() + ", " + arg1.getIdModel());
+      return stringComparator.compare(arg0.getIdModel(), arg1.getIdModel());
+    }
+
+    if (stringComparator.compare(arg0.getName(), arg1.getName()) != 0) {
+      logger.debug("Name different: " + arg0.getName() + ", " + arg1.getName());
+      return stringComparator.compare(arg0.getName(), arg1.getName());
+    }
+
+    if (stringComparator.compare(arg0.getNotes(), arg1.getNotes(), true) != 0) {
+      logger.debug(arg0.getNotes());
+      logger.debug(arg1.getNotes());
+      logger.debug("Notes different:\n" + arg0.getNotes() + "\n---\n" + arg1.getNotes() + "\n---");
+      return stringComparator.compare(arg0.getNotes(), arg1.getNotes(), true);
+    }
+
+    if (doubleComparator.compare(arg0.getWidth(), arg1.getWidth()) != 0) {
+      logger.debug("Width different: " + arg0.getWidth() + ", " + arg1.getWidth());
+      return doubleComparator.compare(arg0.getWidth(), arg1.getWidth());
+    }
+
+    if (doubleComparator.compare(arg0.getHeight(), arg1.getHeight()) != 0) {
+      logger.debug("Height different: " + arg0.getHeight() + ", " + arg1.getHeight());
+      return doubleComparator.compare(arg0.getHeight(), arg1.getHeight());
+    }
+
+    if (integerComparator.compare(arg0.getZoomLevels(), arg1.getZoomLevels()) != 0) {
+      logger.debug("Zoom levels different: " + arg0.getZoomLevels() + ", " + arg1.getZoomLevels());
+      return integerComparator.compare(arg0.getZoomLevels(), arg1.getZoomLevels());
+    }
+
+    if (integerComparator.compare(arg0.getTileSize(), arg1.getTileSize()) != 0) {
+      logger.debug("Tile size different: " + arg0.getTileSize() + ", " + arg1.getTileSize());
+      return integerComparator.compare(arg0.getTileSize(), arg1.getTileSize());
+    }
+
+    int status = compareElements(arg0.getElements(), arg1.getElements());
+    if (status != 0) {
+      logger.debug("Set of elements different");
+      return status;
+    }
+
+    status = compareLayers(arg0.getLayers(), arg1.getLayers());
+    if (status != 0) {
+      logger.debug("Set of layers different");
+      return status;
+    }
+
+    status = compareReaction(arg0.getReactions(), arg1.getReactions());
+    if (status != 0) {
+      logger.debug("Set of reactions different");
+      return status;
+    }
+
+    status = compareLayouts(arg0.getLayouts(), arg1.getLayouts());
+    if (status != 0) {
+      logger.debug("Set of layouts different");
+      return status;
+    }
+
+    status = compareSubmodels(arg0.getSubmodelConnections(), arg1.getSubmodelConnections());
+    if (status != 0) {
+      logger.debug("Set of submodels different");
+      return status;
+    }
+
+    status = integerComparator.compare(arg0.getDataMiningSets().size(), arg1.getDataMiningSets().size());
+    if (status != 0) {
+      logger.debug("Set of data mining sets different");
+      return status;
+    }
+    DataMiningSetComparator dataMiningSetComparator = new DataMiningSetComparator();
+    for (int i = 0; i < arg0.getDataMiningSets().size(); i++) {
+      status = dataMiningSetComparator.compare(arg0.getDataMiningSets().get(i), arg1.getDataMiningSets().get(i));
+      if (status != 0) {
+        logger.debug("Set of data mining sets different");
+        return status;
+      }
+
+    }
+    return 0;
+  }
+
+  /**
+   * Compares two set of reactions.
+   * 
+   * @param reactions
+   *          first set of reactions
+   * @param reactions2
+   *          second set of reactions
+   * @return if sets are equal then returns 0. If they are different then -1/1 is
+   *         returned.
+   */
+  private int compareReaction(Set<Reaction> reactions, Set<Reaction> reactions2) {
+    ReactionComparator comparator = new ReactionComparator(epsilon);
+
+    Map<String, Reaction> map = new HashMap<String, Reaction>();
+    Map<String, Reaction> map2 = new HashMap<String, Reaction>();
+
+    for (Reaction reaction : reactions) {
+      map.put(reaction.getIdReaction(), reaction);
+    }
+    for (Reaction reaction : reactions2) {
+      map2.put(reaction.getIdReaction(), reaction);
+    }
+
+    for (Reaction reaction : reactions) {
+      int status = comparator.compare(reaction, map2.get(reaction.getIdReaction()));
+      if (status != 0) {
+        logger.debug("Different reaction " + reaction.getIdReaction() + ": " + map2.get(reaction.getIdReaction()));
+        return status;
+      }
+    }
+
+    for (Reaction reaction : reactions2) {
+      int status = comparator.compare(reaction, map.get(reaction.getIdReaction()));
+      if (status != 0) {
+        logger.debug("Different reaction " + reaction.getIdReaction());
+        return status;
+      }
+    }
+    return 0;
+  }
+
+  /**
+   * Compares two sets of layers.
+   * 
+   * @param layers
+   *          first set of layers
+   * @param layers2
+   *          second set of layers
+   * @return if sets are equal then returns 0. If they are different then -1/1 is
+   *         returned.
+   */
+  private int compareLayers(Set<Layer> layers, Set<Layer> layers2) {
+    LayerComparator layerComparator = new LayerComparator(epsilon);
+    for (Layer layer : layers) {
+      boolean found = false;
+      for (Layer layer2 : layers2) {
+        if (layerComparator.compare(layer, layer2) == 0) {
+          found = true;
+        }
+      }
+      if (!found) {
+        return 1;
+      }
+    }
+    for (Layer layer : layers2) {
+      boolean found = false;
+      for (Layer layer2 : layers) {
+        if (layerComparator.compare(layer, layer2) == 0) {
+          found = true;
+        }
+      }
+      if (!found) {
+        return -1;
+      }
+    }
+    return 0;
+  }
+
+  /**
+   * Compares two sets of layouts.
+   * 
+   * @param layouts
+   *          first set of layouts
+   * @param layouts2
+   *          second set of layouts
+   * @return if sets are equal then returns 0. If they are different then -1/1 is
+   *         returned.
+   */
+  private int compareLayouts(List<Layout> layouts, List<Layout> layouts2) {
+    LayoutComparator layoutComparator = new LayoutComparator(epsilon);
+    for (Layout layout : layouts) {
+      boolean found = false;
+      for (Layout layout2 : layouts2) {
+        if (layoutComparator.compare(layout, layout2) == 0) {
+          found = true;
+        }
+      }
+      if (!found) {
+        return 1;
+      }
+    }
+    for (Layout layout : layouts2) {
+      boolean found = false;
+      for (Layout layout2 : layouts) {
+        if (layoutComparator.compare(layout, layout2) == 0) {
+          found = true;
+        }
+      }
+      if (!found) {
+        return -1;
+      }
+    }
+    return 0;
+  }
+
+  /**
+   * Compares two sets of elements.
+   * 
+   * @param elements
+   *          first set of elements
+   * @param elements2
+   *          second set of elements
+   * @return if sets are equal then returns 0. If they are different then -1/1 is
+   *         returned.
+   */
+  private int compareElements(Set<Element> elements, Set<Element> elements2) {
+    ElementComparator elementComparator = new ElementComparator(epsilon);
+
+    Map<String, Element> map1 = new HashMap<>();
+    Map<String, Element> map2 = new HashMap<>();
+
+    if (elements.size() != elements2.size()) {
+      logger.debug("Number of elements different: " + elements.size() + ", " + elements2.size());
+      return ((Integer) elements.size()).compareTo(elements2.size());
+    }
+
+    for (Element element : elements) {
+      map1.put(element.getElementId(), element);
+    }
+
+    for (Element element : elements2) {
+      map2.put(element.getElementId(), element);
+    }
+
+    for (Element element : elements) {
+      int status = elementComparator.compare(element, map2.get(element.getElementId()));
+      if (status != 0) {
+        logger
+            .debug("Element doesn't have a match: " + element.getElementId() + ", " + map2.get(element.getElementId()));
+        return status;
+      }
+    }
+
+    for (Element element : elements2) {
+      int status = elementComparator.compare(element, map1.get(element.getElementId()));
+      if (status != 0) {
+        logger
+            .debug("Element doesn't have a match: " + element.getElementId() + ", " + map2.get(element.getElementId()));
+        return status;
+      }
+    }
+    return 0;
+  }
+
+  /**
+   * Compares two collection of models.
+   * 
+   * @param collection1
+   *          first collection to compare
+   * @param collection2
+   *          second collection to compare
+   * @return 0 if the collections are identical, -1/1 otherwise
+   */
+  private int compareSubmodels(Collection<ModelSubmodelConnection> collection1,
+      Collection<ModelSubmodelConnection> collection2) {
+    IntegerComparator integerComparator = new IntegerComparator();
+    if (integerComparator.compare(collection1.size(), collection2.size()) != 0) {
+      logger.debug("collection of submodels doesn't match: " + collection1.size() + ", " + collection2.size());
+      return integerComparator.compare(collection1.size(), collection2.size());
+    }
+    ModelSubmodelConnectionComparator comparator = new ModelSubmodelConnectionComparator(epsilon);
+    for (ModelSubmodelConnection submodel1 : collection1) {
+      boolean found = false;
+      for (ModelSubmodelConnection submodel2 : collection2) {
+        ModelData parent1 = submodel1.getParentModel();
+        submodel1.setParentModel((ModelData) null);
+        ModelData parent2 = submodel2.getParentModel();
+        submodel2.setParentModel((ModelData) null);
+
+        if (comparator.compare(submodel1, submodel2) == 0) {
+          found = true;
+        }
+        submodel1.setParentModel(parent1);
+        submodel2.setParentModel(parent2);
+        if (found) {
+          break;
+        }
+      }
+      if (!found) {
+        logger.debug("collection of submodels doesn't match. " + submodel1 + " cannot be found in the second model");
+        return 1;
+      }
+    }
+
+    for (ModelSubmodelConnection submodel1 : collection2) {
+      boolean found = false;
+      for (ModelSubmodelConnection submodel2 : collection1) {
+        ModelData parent1 = submodel1.getParentModel();
+        submodel1.setParentModel((ModelData) null);
+        ModelData parent2 = submodel2.getParentModel();
+        submodel2.setParentModel((ModelData) null);
+
+        if (comparator.compare(submodel1, submodel2) == 0) {
+          found = true;
+        }
+        submodel1.setParentModel(parent1);
+        submodel2.setParentModel(parent2);
+        if (found) {
+          break;
+        }
+      }
+      if (!found) {
+        logger.debug("collection of submodels doesn't match. " + submodel1 + " cannot be found in the first model");
+        return -1;
+      }
+    }
+
+    return 0;
+  }
 }
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/model/ModelSubmodelConnectionComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/model/ModelSubmodelConnectionComparator.java
index a92d69f28aa37ed4614e4d9b9ecaa4bd8ca92c30..f6dff4bdb97f94f8f19e058e72c738d18c7ed876 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/model/ModelSubmodelConnectionComparator.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/model/ModelSubmodelConnectionComparator.java
@@ -1,11 +1,10 @@
 package lcsb.mapviewer.model.map.model;
 
-import java.util.Comparator;
+import org.apache.log4j.Logger;
 
+import lcsb.mapviewer.common.Comparator;
 import lcsb.mapviewer.common.Configuration;
 
-import org.apache.log4j.Logger;
-
 /**
  * This class implements comparator interface for
  * {@link ModelSubmodelConnection}.
@@ -13,95 +12,62 @@ import org.apache.log4j.Logger;
  * @author Piotr Gawron
  * 
  */
-public class ModelSubmodelConnectionComparator implements Comparator<ModelSubmodelConnection> {
-	/**
-	 * Default class logger.
-	 */
-	private static Logger	logger	= Logger.getLogger(ModelSubmodelConnectionComparator.class);
-
-	/**
-	 * Epsilon value used for comparison of doubles.
-	 */
-	private double				epsilon;
-
-	/**
-	 * Constructor that requires {@link #epsilon} parameter.
-	 * 
-	 * @param epsilon
-	 *          {@link #epsilon}
-	 */
-	public ModelSubmodelConnectionComparator(double epsilon) {
-		this.epsilon = epsilon;
-	}
-
-	/**
-	 * Default constructor.
-	 */
-	public ModelSubmodelConnectionComparator() {
-		this(Configuration.EPSILON);
-	}
+public class ModelSubmodelConnectionComparator extends Comparator<ModelSubmodelConnection> {
+  /**
+   * Default class logger.
+   */
+  private static Logger logger = Logger.getLogger(ModelSubmodelConnectionComparator.class);
 
-	@Override
-	public int compare(ModelSubmodelConnection arg0, ModelSubmodelConnection arg1) {
-		if (arg0 == null) {
-			if (arg1 == null) {
-				return 0;
-			} else {
-				return 1;
-			}
-		} else if (arg1 == null) {
-			return -1;
-		}
+  /**
+   * Epsilon value used for comparison of doubles.
+   */
+  private double epsilon;
 
-		if (arg0.getClass().equals(arg1.getClass())) {
-			return internalCompare(arg0, arg1);
-		} else {
-			logger.debug("class different: " + arg0.getClass() + ", " + arg1.getClass());
-			return -1;
-		}
-	}
+  /**
+   * Constructor that requires {@link #epsilon} parameter.
+   * 
+   * @param epsilon
+   *          {@link #epsilon}
+   */
+  public ModelSubmodelConnectionComparator(double epsilon) {
+    super(ModelSubmodelConnection.class);
+    this.epsilon = epsilon;
+  }
 
-	/**
-	 * This method compares only the fields that are defined in
-	 * {@link ModelSubmodelConnection} class in inheritence tree. It also calls
-	 * the {@link SubmodelConnectionComparator} for the super class (
-	 * {@link SubmodelConnection}).
-	 * 
-	 * @param arg0
-	 *          first object to compare
-	 * @param arg1
-	 *          second object to compare
-	 * @return if all fields are qual then returns 0. If they are different then
-	 *         -1/1 is returned.
-	 */
-	protected int internalCompare(ModelSubmodelConnection arg0, ModelSubmodelConnection arg1) {
+  /**
+   * Default constructor.
+   */
+  public ModelSubmodelConnectionComparator() {
+    this(Configuration.EPSILON);
+  }
 
-		SubmodelConnectionComparator superComparator = new SubmodelConnectionComparator(epsilon);
-		int result = superComparator.internalCompare(arg0, arg1);
-		if (result != 0) {
-			return result;
-		}
+  @Override
+  protected Comparator<?> getParentComparator() {
+    return new SubmodelConnectionComparator(epsilon);
+  }
 
-		ModelComparator comparator = new ModelComparator(epsilon);
+  @Override
+  protected int internalCompare(ModelSubmodelConnection arg0, ModelSubmodelConnection arg1) {
+    ModelComparator comparator = new ModelComparator(epsilon);
 
-		if (arg0.getParentModel() != null && arg1.getParentModel() != null) {
-			int status = comparator.compare(arg0.getParentModel().getModel(), arg1.getParentModel().getModel());
-			if (status != 0) {
-				logger.debug("Model different: " + arg0.getParentModel() + ", " + arg1.getParentModel());
-				return status;
-			}
-		} else {
-			if (arg0.getParentModel() != null) {
-				logger.debug("Model different: " + arg0.getParentModel() + ", " + arg1.getParentModel());
-				return -1;
-			}
-			if (arg1.getParentModel() != null) {
-				logger.debug("Model different: " + arg0.getParentModel() + ", " + arg1.getParentModel());
-				return 1;
-			}
-		}
+    if (arg0.getParentModel() != null && arg1.getParentModel() != null) {
+      int status = comparator.compare(arg0.getParentModel().getModel(), arg1.getParentModel().getModel());
+      if (status != 0) {
+        logger.debug("Model different: " + arg0.getParentModel() + ", " + arg1.getParentModel());
+        return status;
+      }
+    } else {
+      if (arg0.getParentModel() != null) {
+        logger.debug("Model different: " + arg0.getParentModel() + ", " + arg1.getParentModel());
+        return -1;
+      }
+      if (arg1.getParentModel() != null) {
+        logger.debug("Model different: " + arg0.getParentModel() + ", " + arg1.getParentModel());
+        return 1;
+      }
+    }
 
-		return 0;
-	}
+    return 0;
+  }
 
 }
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/model/SubmodelConnectionComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/model/SubmodelConnectionComparator.java
index b4227814d436ef0bdacf79958c5e0a820009a59c..9fc00be4322af6568f0990aefb59de5b3a1dff7e 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/model/SubmodelConnectionComparator.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/model/SubmodelConnectionComparator.java
@@ -1,12 +1,10 @@
 package lcsb.mapviewer.model.map.model;
 
-import java.util.Comparator;
-
 import org.apache.log4j.Logger;
 
+import lcsb.mapviewer.common.Comparator;
 import lcsb.mapviewer.common.Configuration;
 import lcsb.mapviewer.common.comparator.StringComparator;
-import lcsb.mapviewer.common.exception.NotImplementedException;
 
 /**
  * This class implements comparator interface for {@link SubmodelConnection}. It
@@ -15,136 +13,89 @@ import lcsb.mapviewer.common.exception.NotImplementedException;
  * @author Piotr Gawron
  * 
  */
-public class SubmodelConnectionComparator implements Comparator<SubmodelConnection> {
-	/**
-	 * Default class logger.
-	 */
-	private static Logger	logger = Logger.getLogger(SubmodelConnection.class);
-
-	/**
-	 * Epsilon value used for comparison of doubles.
-	 */
-	private double				epsilon;
-
-	/**
-	 * Constructor that requires {@link #epsilon} parameter.
-	 * 
-	 * @param epsilon
-	 *          {@link #epsilon}
-	 */
-	public SubmodelConnectionComparator(double epsilon) {
-		this.epsilon = epsilon;
-		modelSubmodelConnectionComparator = new ModelSubmodelConnectionComparator(epsilon);
-		elementSubmodelConnectionComparator = new ElementSubmodelConnectionComparator(epsilon);
-	}
-
-	/**
-	 * Comparator used to compare {@link ModelSubmodelConnection} subclasses.
-	 */
-	private ModelSubmodelConnectionComparator	modelSubmodelConnectionComparator	= null;
-
-	/**
-	 * Comparator used to compare {@link ElementSubmodelConnection} subclasses.
-	 */
-	private ElementSubmodelConnectionComparator	elementSubmodelConnectionComparator	= null;
-
-	/**
-	 * Default constructor.
-	 */
-	public SubmodelConnectionComparator() {
-		this(Configuration.EPSILON);
-	}
-
-	/**
-	 * This method compares only the fields that are defined in
-	 * {@link SubmodelConnection} class in inheritence tree. It should be called
-	 * by the super class comparators, like
-	 * {@link ModelSubmodelConnectionComparator} and
-	 * {@link ElementSubmodelConnectionComparator}.
-	 * 
-	 * @param arg0
-	 *          first object to compare
-	 * @param arg1
-	 *          second object to compare
-	 * @return if all fields are qual then returns 0. If they are different then
-	 *         -1/1 is returned.
-	 */
-	protected int internalCompare(SubmodelConnection arg0, SubmodelConnection arg1) {
-		StringComparator stringComparator = new StringComparator();
-		if (arg0 == null) {
-			if (arg1 == null) {
-				return 0;
-			} else {
-				return 1;
-			}
-		} else if (arg1 == null) {
-			return -1;
-		}
-
-		if (stringComparator.compare(arg0.getName(), arg1.getName()) != 0) {
-			logger.debug("Name different: " + arg0.getName() + ", " + arg1.getName());
-			return stringComparator.compare(arg0.getName(), arg1.getName());
-		}
-
-		if (arg0.getType() == null && arg1.getType() != null) {
-			logger.debug("Type different: " + arg0.getType() + ", " + arg1.getType());
-			return -1;
-		}
-		if (arg0.getType() != null) {
-			if (arg1.getType() == null) {
-				logger.debug("Type different: " + arg0.getType() + ", " + arg1.getType());
-				return -1;
-			}
-			if (arg0.getType().compareTo(arg1.getType()) != 0) {
-				logger.debug("Type different: " + arg0.getType() + ", " + arg1.getType());
-				return arg0.getType().compareTo(arg1.getType());
-			}
-		}
-
-		ModelComparator modelComparator = new ModelComparator(epsilon);
-		if (arg0.getSubmodel() != null && arg1.getSubmodel() != null) {
-			int status = modelComparator.compare(arg0.getSubmodel().getModel(), arg1.getSubmodel().getModel());
-			if (status != 0) {
-				logger.debug("Model different: " + arg0.getSubmodel() + ", " + arg1.getSubmodel());
-				return status;
-			}
-		} else {
-			if (arg0.getSubmodel() != null) {
-				logger.debug("Model different: " + arg0.getSubmodel() + ", " + arg1.getSubmodel());
-				return 1;
-			}
-			if (arg1.getSubmodel() != null) {
-				logger.debug("Model different: " + arg0.getSubmodel() + ", " + arg1.getSubmodel());
-				return -1;
-			}
-		}
-
-		return 0;
-	}
-
-	@Override
-	public int compare(SubmodelConnection arg0, SubmodelConnection arg1) {
-		if (arg0 == null) {
-			if (arg1 == null) {
-				return 0;
-			} else {
-				return 1;
-			}
-		} else if (arg1 == null) {
-			return -1;
-		}
-
-		if (arg0.getClass().equals(arg1.getClass())) {
-			if (arg0 instanceof ModelSubmodelConnection) {
-				return modelSubmodelConnectionComparator.compare((ModelSubmodelConnection) arg0, (ModelSubmodelConnection) arg1);
-			} else if (arg0 instanceof ElementSubmodelConnection) {
-				return elementSubmodelConnectionComparator.compare((ElementSubmodelConnection) arg0, (ElementSubmodelConnection) arg1);
-			} else {
-				throw new NotImplementedException("Don't know how to compare classes: " + arg0.getClass());
-			}
-		} else {
-			return -1;
-		}
-	}
+public class SubmodelConnectionComparator extends Comparator<SubmodelConnection> {
+  /**
+   * Default class logger.
+   */
+  private static Logger logger = Logger.getLogger(SubmodelConnection.class);
+
+  /**
+   * Epsilon value used for comparison of doubles.
+   */
+  private double epsilon;
+
+  /**
+   * Constructor that requires {@link #epsilon} parameter.
+   * 
+   * @param epsilon
+   *          {@link #epsilon}
+   */
+  public SubmodelConnectionComparator(double epsilon) {
+    super(SubmodelConnection.class, true);
+    this.epsilon = epsilon;
+    addSubClassComparator(new ModelSubmodelConnectionComparator(epsilon));
+    addSubClassComparator(new ElementSubmodelConnectionComparator(epsilon));
+  }
+
+  /**
+   * Default constructor.
+   */
+  public SubmodelConnectionComparator() {
+    this(Configuration.EPSILON);
+  }
+
+  @Override
+  protected int internalCompare(SubmodelConnection arg0, SubmodelConnection arg1) {
+    StringComparator stringComparator = new StringComparator();
+    if (arg0 == null) {
+      if (arg1 == null) {
+        return 0;
+      } else {
+        return 1;
+      }
+    } else if (arg1 == null) {
+      return -1;
+    }
+
+    if (stringComparator.compare(arg0.getName(), arg1.getName()) != 0) {
+      logger.debug("Name different: " + arg0.getName() + ", " + arg1.getName());
+      return stringComparator.compare(arg0.getName(), arg1.getName());
+    }
+
+    if (arg0.getType() == null && arg1.getType() != null) {
+      logger.debug("Type different: " + arg0.getType() + ", " + arg1.getType());
+      return -1;
+    }
+    if (arg0.getType() != null) {
+      if (arg1.getType() == null) {
+        logger.debug("Type different: " + arg0.getType() + ", " + arg1.getType());
+        return -1;
+      }
+      if (arg0.getType().compareTo(arg1.getType()) != 0) {
+        logger.debug("Type different: " + arg0.getType() + ", " + arg1.getType());
+        return arg0.getType().compareTo(arg1.getType());
+      }
+    }
+
+    ModelComparator modelComparator = new ModelComparator(epsilon);
+    if (arg0.getSubmodel() != null && arg1.getSubmodel() != null) {
+      int status = modelComparator.compare(arg0.getSubmodel().getModel(), arg1.getSubmodel().getModel());
+      if (status != 0) {
+        logger.debug("Model different: " + arg0.getSubmodel() + ", " + arg1.getSubmodel());
+        return status;
+      }
+    } else {
+      if (arg0.getSubmodel() != null) {
+        logger.debug("Model different: " + arg0.getSubmodel() + ", " + arg1.getSubmodel());
+        return 1;
+      }
+      if (arg1.getSubmodel() != null) {
+        logger.debug("Model different: " + arg0.getSubmodel() + ", " + arg1.getSubmodel());
+        return -1;
+      }
+    }
+
+    return 0;
+  }
 
 }
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/reaction/AbstractNodeComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/reaction/AbstractNodeComparator.java
index c51dee52a746d420d5c04c19f39fe0aec62622dd..693855bee60c6b07afb6e7f559f8c58aac4dc2b4 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/reaction/AbstractNodeComparator.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/reaction/AbstractNodeComparator.java
@@ -1,6 +1,6 @@
 package lcsb.mapviewer.model.map.reaction;
 
-import java.util.Comparator;
+import lcsb.mapviewer.common.Comparator;
 
 import lcsb.mapviewer.common.Configuration;
 import lcsb.mapviewer.common.exception.InvalidClassException;
@@ -15,7 +15,7 @@ import org.apache.log4j.Logger;
  * @author Piotr Gawron
  * 
  */
-public class AbstractNodeComparator implements Comparator<AbstractNode> {
+public class AbstractNodeComparator extends Comparator<AbstractNode> {
   /**
    * Default class logger.
    */
@@ -33,7 +33,10 @@ public class AbstractNodeComparator implements Comparator<AbstractNode> {
    *          {@link #epsilon}
    */
   public AbstractNodeComparator(double epsilon) {
+    super(AbstractNode.class, true);
     this.epsilon = epsilon;
+    addSubClassComparator(new NodeOperatorComparator(epsilon));
+    addSubClassComparator(new ReactionNodeComparator(epsilon));
   }
 
   /**
@@ -44,46 +47,6 @@ public class AbstractNodeComparator implements Comparator<AbstractNode> {
   }
 
   @Override
-  public int compare(AbstractNode arg0, AbstractNode arg1) {
-    // check null values
-    if (arg0 == null) {
-      if (arg1 == null) {
-        return 0;
-      } else {
-        return 1;
-      }
-    } else if (arg1 == null) {
-      return -1;
-    }
-
-    // now check class types
-    if (arg0.getClass().equals(arg1.getClass())) {
-      // and call comparator of appropriate subclass
-      if (arg0 instanceof NodeOperator) {
-        NodeOperatorComparator nodeOperatorComparator = new NodeOperatorComparator(epsilon);
-        return nodeOperatorComparator.compare((NodeOperator) arg0, (NodeOperator) arg1);
-      } else if (arg0 instanceof ReactionNode) {
-        ReactionNodeComparator reactionNodeComparator = new ReactionNodeComparator(epsilon);
-        return reactionNodeComparator.compare((ReactionNode) arg0, (ReactionNode) arg1);
-      } else {
-        throw new InvalidClassException("Don't know how to compare classes: " + arg0.getClass());
-      }
-    } else {
-      return -1;
-    }
-  }
-
-  /**
-   * This method compares only the fields that are defined in AbstractNode class
-   * in inheritance tree. By the design it is called by subclass comparator.
-   * 
-   * @param arg0
-   *          first object to compare
-   * @param arg1
-   *          second object to compare
-   * @return if all fields are equal then returns 0. If they are different then
-   *         -1/1 is returned.
-   */
   protected int internalCompare(AbstractNode arg0, AbstractNode arg1) {
     PolylineDataComparator pdComparator = new PolylineDataComparator(epsilon);
     if (pdComparator.compare(arg0.getLine(), arg1.getLine()) != 0) {
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/reaction/NodeOperatorComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/reaction/NodeOperatorComparator.java
index 97b0927379243605a7051b4ffb0ae52ab659fc19..cbe96d36925f9deba6a9a9b0e55221763c8655ff 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/reaction/NodeOperatorComparator.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/reaction/NodeOperatorComparator.java
@@ -1,9 +1,8 @@
 package lcsb.mapviewer.model.map.reaction;
 
-import java.util.Comparator;
-
 import org.apache.log4j.Logger;
 
+import lcsb.mapviewer.common.Comparator;
 import lcsb.mapviewer.common.Configuration;
 import lcsb.mapviewer.common.comparator.IntegerComparator;
 
@@ -15,121 +14,88 @@ import lcsb.mapviewer.common.comparator.IntegerComparator;
  * @author Piotr Gawron
  * 
  */
-public class NodeOperatorComparator implements Comparator<NodeOperator> {
-	/**
-	 * Default class logger.
-	 */
-	private Logger logger	= Logger.getLogger(NodeOperatorComparator.class);
-
-	/**
-	 * Epsilon value used for comparison of doubles.
-	 */
-	private double epsilon;
-
-	/**
-	 * Constructor that requires {@link #epsilon} parameter.
-	 * 
-	 * @param epsilon
-	 *          {@link #epsilon}
-	 */
-	public NodeOperatorComparator(double epsilon) {
-		this.epsilon = epsilon;
-	}
-
-	/**
-	 * Default constructor.
-	 */
-	public NodeOperatorComparator() {
-		this(Configuration.EPSILON);
-	}
-
-	@Override
-	public int compare(NodeOperator arg0, NodeOperator arg1) {
-		if (arg0 == null) {
-			if (arg1 == null) {
-				return 0;
-			} else {
-				return 1;
-			}
-		} else if (arg1 == null) {
-			return -1;
-		}
-
-		if (arg0.getClass().equals(arg1.getClass())) {
-			return internalCompare(arg0, arg1);
-		} else {
-			logger.debug("Different classes.");
-			return -1;
-		}
-	}
-
-	/**
-	 * This method compare all fields of two node operators and return 0 if they
-	 * are the same or 1/-1 if the objects are different. Also comparator for
-	 * super class ({@link AbstractNode}) is called.
-	 * 
-	 * @param arg0
-	 *          first object to compare
-	 * @param arg1
-	 *          second object to compare
-	 * @return 0 if objects are equal,<br>
-	 *         -1/1 otherwise
-	 */
-
-	private int internalCompare(NodeOperator arg0, NodeOperator arg1) {
-		AbstractNodeComparator anComparator = new AbstractNodeComparator(epsilon);
-
-		int result = anComparator.internalCompare(arg0, arg1);
-		if (result != 0) {
-			logger.debug("Different Abstract Nodes: " + arg0 + ", " + arg1);
-			return result;
-		}
-
-		IntegerComparator integerComparator = new IntegerComparator();
-
-		if (integerComparator.compare(arg0.getInputs().size(), arg1.getInputs().size()) != 0) {
-			logger.debug("Different input size: " + arg0.getInputs().size() + ", " + arg1.getInputs().size());
-			return integerComparator.compare(arg0.getInputs().size(), arg1.getInputs().size());
-		}
-		if (integerComparator.compare(arg0.getOutputs().size(), arg1.getOutputs().size()) != 0) {
-			logger.debug("Different output size: " + arg0.getOutputs().size() + ", " + arg1.getOutputs().size());
-			return integerComparator.compare(arg0.getOutputs().size(), arg1.getOutputs().size());
-		}
-
-		for (int i = 0; i < arg0.getInputs().size(); i++) {
-			AbstractNode node1 = arg0.getInputs().get(i);
-			int status = -1;
-			for (int j = 0; j < arg1.getInputs().size(); j++) {
-				AbstractNode node2 = arg1.getInputs().get(j);
-				int tmpStatus = anComparator.compare(node1, node2);
-				if (tmpStatus == 0) {
-					status = 0;
-					break;
-				}
-			}
-			if (status != 0) {
-				logger.debug("Can't find match in inputs.");
-				return status;
-			}
-		}
-		for (int i = 0; i < arg0.getOutputs().size(); i++) {
-			AbstractNode node1 = arg0.getOutputs().get(i);
-			int status = -1;
-			for (int j = 0; j < arg1.getOutputs().size(); j++) {
-				AbstractNode node2 = arg1.getOutputs().get(j);
-				int tmpStatus = anComparator.compare(node1, node2);
-				if (tmpStatus == 0) {
-					status = 0;
-					break;
-				}
-			}
-			if (status != 0) {
-				logger.debug("Can't find match in outputs.");
-				return status;
-			}
-		}
-
-		return 0;
-	}
+public class NodeOperatorComparator extends Comparator<NodeOperator> {
+  /**
+   * Default class logger.
+   */
+  private Logger logger = Logger.getLogger(NodeOperatorComparator.class);
+
+  /**
+   * Epsilon value used for comparison of doubles.
+   */
+  private double epsilon;
+
+  /**
+   * Constructor that requires {@link #epsilon} parameter.
+   * 
+   * @param epsilon
+   *          {@link #epsilon}
+   */
+  public NodeOperatorComparator(double epsilon) {
+    super(NodeOperator.class);
+    this.epsilon = epsilon;
+  }
+
+  protected Comparator<?> getParentComparator() {
+    return new AbstractNodeComparator(epsilon);
+  }
+
+  /**
+   * Default constructor.
+   */
+  public NodeOperatorComparator() {
+    this(Configuration.EPSILON);
+  }
+
+  @Override
+  protected int internalCompare(NodeOperator arg0, NodeOperator arg1) {
+    AbstractNodeComparator anComparator = new AbstractNodeComparator(epsilon);
+
+    IntegerComparator integerComparator = new IntegerComparator();
+
+    if (integerComparator.compare(arg0.getInputs().size(), arg1.getInputs().size()) != 0) {
+      logger.debug("Different input size: " + arg0.getInputs().size() + ", " + arg1.getInputs().size());
+      return integerComparator.compare(arg0.getInputs().size(), arg1.getInputs().size());
+    }
+    if (integerComparator.compare(arg0.getOutputs().size(), arg1.getOutputs().size()) != 0) {
+      logger.debug("Different output size: " + arg0.getOutputs().size() + ", " + arg1.getOutputs().size());
+      return integerComparator.compare(arg0.getOutputs().size(), arg1.getOutputs().size());
+    }
+
+    for (int i = 0; i < arg0.getInputs().size(); i++) {
+      AbstractNode node1 = arg0.getInputs().get(i);
+      int status = -1;
+      for (int j = 0; j < arg1.getInputs().size(); j++) {
+        AbstractNode node2 = arg1.getInputs().get(j);
+        int tmpStatus = anComparator.compare(node1, node2);
+        if (tmpStatus == 0) {
+          status = 0;
+          break;
+        }
+      }
+      if (status != 0) {
+        logger.debug("Can't find match in inputs.");
+        return status;
+      }
+    }
+    for (int i = 0; i < arg0.getOutputs().size(); i++) {
+      AbstractNode node1 = arg0.getOutputs().get(i);
+      int status = -1;
+      for (int j = 0; j < arg1.getOutputs().size(); j++) {
+        AbstractNode node2 = arg1.getOutputs().get(j);
+        int tmpStatus = anComparator.compare(node1, node2);
+        if (tmpStatus == 0) {
+          status = 0;
+          break;
+        }
+      }
+      if (status != 0) {
+        logger.debug("Can't find match in outputs.");
+        return status;
+      }
+    }
+
+    return 0;
+  }
 
 }
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 78691472086ea094781e84009280198703156401..eb812a44ed20d709da02458ba92e4e609c846d39 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
@@ -1,11 +1,11 @@
 package lcsb.mapviewer.model.map.reaction;
 
-import java.util.Comparator;
 import java.util.HashSet;
 import java.util.Set;
 
 import org.apache.log4j.Logger;
 
+import lcsb.mapviewer.common.Comparator;
 import lcsb.mapviewer.common.Configuration;
 import lcsb.mapviewer.common.comparator.BooleanComparator;
 import lcsb.mapviewer.common.comparator.DoubleComparator;
@@ -14,6 +14,7 @@ import lcsb.mapviewer.common.comparator.StringComparator;
 import lcsb.mapviewer.common.comparator.StringListComparator;
 import lcsb.mapviewer.common.comparator.StringSetComparator;
 import lcsb.mapviewer.model.map.MiriamData;
+import lcsb.mapviewer.model.map.kinetics.SbmlKineticsComparator;
 
 /**
  * This class implements comparator interface for {@link Reaction}.
@@ -21,7 +22,7 @@ import lcsb.mapviewer.model.map.MiriamData;
  * @author Piotr Gawron
  * 
  */
-public class ReactionComparator implements Comparator<Reaction> {
+public class ReactionComparator extends Comparator<Reaction> {
   /**
    * Default class logger.
    */
@@ -39,6 +40,7 @@ public class ReactionComparator implements Comparator<Reaction> {
    *          {@link #epsilon}
    */
   public ReactionComparator(double epsilon) {
+    super(Reaction.class);
     this.epsilon = epsilon;
   }
 
@@ -50,37 +52,7 @@ public class ReactionComparator implements Comparator<Reaction> {
   }
 
   @Override
-  public int compare(Reaction arg0, Reaction arg1) {
-    if (arg0 == null) {
-      if (arg1 == null) {
-        return 0;
-      } else {
-        return 1;
-      }
-    } else if (arg1 == null) {
-      return -1;
-    }
-
-    if (arg0.getClass().equals(arg1.getClass())) {
-      return internalCompare(arg0, arg1);
-    } else {
-      logger.debug("Different class: " + arg0.getClass() + ", " + arg1.getClass());
-      return -1;
-    }
-  }
-
-  /**
-   * This method compares only the fields that are defined in {@link Reaction}
-   * class in inheritence tree.
-   * 
-   * @param arg0
-   *          first object to compare
-   * @param arg1
-   *          second object to compare
-   * @return if all fields are qual then returns 0. If they are different then
-   *         -1/1 is returned.
-   */
-  public int internalCompare(Reaction arg0, Reaction arg1) {
+  protected int internalCompare(Reaction arg0, Reaction arg1) {
     StringComparator stringComparator = new StringComparator();
     BooleanComparator booleanComparator = new BooleanComparator();
     AbstractNodeComparator aNodeComparator = new AbstractNodeComparator(epsilon);
@@ -202,6 +174,11 @@ public class ReactionComparator implements Comparator<Reaction> {
       }
     }
 
+    SbmlKineticsComparator kineticsComparator = new SbmlKineticsComparator();
+    if (kineticsComparator.compare(arg0.getKinetics(), arg1.getKinetics()) != 0) {
+      logger.debug("Kinetics different");
+      return kineticsComparator.compare(arg0.getKinetics(), arg1.getKinetics());
+    }
     return 0;
   }
 
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/reaction/ReactionNodeComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/reaction/ReactionNodeComparator.java
index 5c22f844761ec30af1c7402ed80d0cfbbeb73e66..7abecd825ce3a0932e7c9b28dbec1a1940e7eefc 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/reaction/ReactionNodeComparator.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/reaction/ReactionNodeComparator.java
@@ -1,9 +1,8 @@
 package lcsb.mapviewer.model.map.reaction;
 
-import java.util.Comparator;
-
 import org.apache.log4j.Logger;
 
+import lcsb.mapviewer.common.Comparator;
 import lcsb.mapviewer.common.Configuration;
 import lcsb.mapviewer.model.map.species.ElementComparator;
 
@@ -15,80 +14,54 @@ import lcsb.mapviewer.model.map.species.ElementComparator;
  * @author Piotr Gawron
  * 
  */
-public class ReactionNodeComparator implements Comparator<ReactionNode> {
-	/**
-	 * Default class logger.
-	 */
-	private Logger logger	= Logger.getLogger(ReactionNodeComparator.class);
-
-	/**
-	 * Epsilon value used for comparison of doubles.
-	 */
-	private double epsilon;
+public class ReactionNodeComparator extends Comparator<ReactionNode> {
+  /**
+   * Default class logger.
+   */
+  private Logger logger = Logger.getLogger(ReactionNodeComparator.class);
 
-	/**
-	 * Constructor that requires {@link #epsilon} parameter.
-	 * 
-	 * @param epsilon
-	 *          {@link #epsilon}
-	 */
-	public ReactionNodeComparator(double epsilon) {
-		this.epsilon = epsilon;
-	}
+  /**
+   * Epsilon value used for comparison of doubles.
+   */
+  private double epsilon;
 
-	/**
-	 * Default constructor.
-	 */
-	public ReactionNodeComparator() {
-		this(Configuration.EPSILON);
-	}
+  /**
+   * Constructor that requires {@link #epsilon} parameter.
+   * 
+   * @param epsilon
+   *          {@link #epsilon}
+   */
+  public ReactionNodeComparator(double epsilon) {
+    super(ReactionNode.class);
+    this.epsilon = epsilon;
+  }
 
-	@Override
-	public int compare(ReactionNode arg0, ReactionNode arg1) {
-		if (arg0 == null) {
-			if (arg1 == null) {
-				return 0;
-			} else {
-				return 1;
-			}
-		} else if (arg1 == null) {
-			return -1;
-		}
+  protected Comparator<?> getParentComparator() {
+    return new AbstractNodeComparator(epsilon);
+  }
 
-		if (arg0.getClass().equals(arg1.getClass())) {
-			return internalCompare(arg0, arg1);
-		} else {
-			logger.debug("Different classes.");
-			return -1;
-		}
-	}
+  /**
+   * Default constructor.
+   */
+  public ReactionNodeComparator() {
+    this(Configuration.EPSILON);
+  }
 
-	/**
-	 * This method compare all fields of two node operators and return 0 if they
-	 * are the same or 1/-1 if the objects are different. Also comparator for
-	 * super class ({@link AbstractNode}) is called.
-	 * 
-	 * @param arg0
-	 *          first object to compare
-	 * @param arg1
-	 *          second object to compare
-	 * @return 0 if objects are equal,<br>
-	 *         -1/1 otherwise
-	 */
-	private int internalCompare(ReactionNode arg0, ReactionNode arg1) {
-		AbstractNodeComparator anComparator = new AbstractNodeComparator(epsilon);
-		ElementComparator elementComparator = new ElementComparator(epsilon);
+  @Override
+  protected int internalCompare(ReactionNode arg0, ReactionNode arg1) {
+    AbstractNodeComparator anComparator = new AbstractNodeComparator(epsilon);
+    ElementComparator elementComparator = new ElementComparator(epsilon);
 
-		int result = anComparator.internalCompare(arg0, arg1);
-		if (result != 0) {
-			return result;
-		}
+    int result = anComparator.internalCompare(arg0, arg1);
+    if (result != 0) {
+      return result;
+    }
 
-		if (elementComparator.compare(arg0.getElement(), arg1.getElement()) != 0) {
-			logger.debug("Element different");
-			return elementComparator.compare(arg0.getElement(), arg1.getElement());
-		}
+    if (elementComparator.compare(arg0.getElement(), arg1.getElement()) != 0) {
+      logger.debug("Element different");
+      return elementComparator.compare(arg0.getElement(), arg1.getElement());
+    }
 
-		return 0;
-	}
+    return 0;
+  }
 }
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/species/AntisenseRnaComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/species/AntisenseRnaComparator.java
index e5c2a69cfba58e0b861e9cf25481313289cb5a36..95e2a358541cc7f2eec77865c0aeb23607793708 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/species/AntisenseRnaComparator.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/species/AntisenseRnaComparator.java
@@ -1,14 +1,13 @@
 package lcsb.mapviewer.model.map.species;
 
-import java.util.Comparator;
 import java.util.HashSet;
 import java.util.Set;
 
 import org.apache.log4j.Logger;
 
+import lcsb.mapviewer.common.Comparator;
 import lcsb.mapviewer.common.Configuration;
 import lcsb.mapviewer.common.comparator.StringSetComparator;
-import lcsb.mapviewer.common.exception.NotImplementedException;
 import lcsb.mapviewer.model.map.species.field.AntisenseRnaRegion;
 
 /**
@@ -17,94 +16,61 @@ import lcsb.mapviewer.model.map.species.field.AntisenseRnaRegion;
  * @author Piotr Gawron
  *
  */
-public class AntisenseRnaComparator implements Comparator<AntisenseRna> {
-
-	/**
-	 * Default class logger.
-	 */
-	@SuppressWarnings("unused")
-	private static Logger	logger = Logger.getLogger(AntisenseRnaComparator.class);
-
-	/**
-	 * Epsilon value used for comparison of doubles.
-	 */
-	private double				epsilon;
-
-	/**
-	 * Constructor that requires {@link #epsilon} parameter.
-	 * 
-	 * @param epsilon
-	 *          {@link #epsilon}
-	 */
-	public AntisenseRnaComparator(double epsilon) {
-		this.epsilon = epsilon;
-	}
-
-	/**
-	 * Default constructor.
-	 */
-	public AntisenseRnaComparator() {
-		this(Configuration.EPSILON);
-	}
-
-	@Override
-	public int compare(AntisenseRna arg0, AntisenseRna arg1) {
-		if (arg0 == null) {
-			if (arg1 == null) {
-				return 0;
-			} else {
-				return 1;
-			}
-		} else if (arg1 == null) {
-			return -1;
-		}
-
-		if (arg0.getClass().equals(arg1.getClass())) {
-			if (arg0.getClass().equals(AntisenseRna.class)) {
-				return internalCompare(arg0, arg1);
-			} else {
-				throw new NotImplementedException("Don't know how to compare classes: " + arg0.getClass());
-			}
-		} else {
-			return -1;
-		}
-	}
-
-	/**
-	 * This method compares only the fields that are defined in
-	 * {@link AntisenseRna} class in inheritence tree. By the design it calls also
-	 * comparator of the upper ({@link Species}) class.
-	 * 
-	 * @param arg0
-	 *          first object to compare
-	 * @param arg1
-	 *          second object to compare
-	 * @return if all fields are qual then returns 0. If they are different then
-	 *         -1/1 is returned.
-	 */
-	private int internalCompare(AntisenseRna arg0, AntisenseRna arg1) {
-		SpeciesComparator speciesComparator = new SpeciesComparator(epsilon);
-		int result = speciesComparator.internalCompare(arg0, arg1);
-		if (result != 0) {
-			return result;
-		}
-		StringSetComparator stringSetComparator = new StringSetComparator();
-
-		Set<String> set1 = new HashSet<String>();
-		Set<String> set2 = new HashSet<String>();
-
-		for (AntisenseRnaRegion region : arg0.getRegions()) {
-			set1.add(region.toString());
-		}
-
-		for (AntisenseRnaRegion region : arg1.getRegions()) {
-			set2.add(region.toString());
-		}
-
-		if (stringSetComparator.compare(set1, set2) != 0) {
-			return stringSetComparator.compare(set1, set2);
-		}
-
-		return 0;
-	}
+public class AntisenseRnaComparator extends Comparator<AntisenseRna> {
+
+  /**
+   * Default class logger.
+   */
+  @SuppressWarnings("unused")
+  private static Logger logger = Logger.getLogger(AntisenseRnaComparator.class);
+
+  /**
+   * Epsilon value used for comparison of doubles.
+   */
+  private double epsilon;
+
+  /**
+   * Constructor that requires {@link #epsilon} parameter.
+   * 
+   * @param epsilon
+   *          {@link #epsilon}
+   */
+  public AntisenseRnaComparator(double epsilon) {
+    super(AntisenseRna.class, true);
+    this.epsilon = epsilon;
+  }
+
+  /**
+   * Default constructor.
+   */
+  public AntisenseRnaComparator() {
+    this(Configuration.EPSILON);
+  }
+
+  @Override
+  protected Comparator<?> getParentComparator() {
+    return new SpeciesComparator(epsilon);
+  }
+
+  @Override
+  protected int internalCompare(AntisenseRna arg0, AntisenseRna arg1) {
+    StringSetComparator stringSetComparator = new StringSetComparator();
+
+    Set<String> set1 = new HashSet<String>();
+    Set<String> set2 = new HashSet<String>();
+
+    for (AntisenseRnaRegion region : arg0.getRegions()) {
+      set1.add(region.toString());
+    }
+
+    for (AntisenseRnaRegion region : arg1.getRegions()) {
+      set2.add(region.toString());
+    }
+
+    if (stringSetComparator.compare(set1, set2) != 0) {
+      return stringSetComparator.compare(set1, set2);
+    }
+
+    return 0;
+  }
 }
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/species/ChemicalComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/species/ChemicalComparator.java
index ec844f1f271432853edebf005b0b110e4c7af641..14601f6a0fd3a43105361382ad16c51afa64e999 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/species/ChemicalComparator.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/species/ChemicalComparator.java
@@ -1,12 +1,10 @@
 package lcsb.mapviewer.model.map.species;
 
-import java.util.Comparator;
-
 import org.apache.log4j.Logger;
 
+import lcsb.mapviewer.common.Comparator;
 import lcsb.mapviewer.common.Configuration;
 import lcsb.mapviewer.common.comparator.StringComparator;
-import lcsb.mapviewer.common.exception.NotImplementedException;
 
 /**
  * Comparator class used for comparing {@link Chemical} objects.
@@ -14,107 +12,62 @@ import lcsb.mapviewer.common.exception.NotImplementedException;
  * @author Piotr Gawron
  *
  */
-public class ChemicalComparator implements Comparator<Chemical> {
-
-	/**
-	 * Default class logger.
-	 */
-	private static Logger						 logger	= Logger.getLogger(ChemicalComparator.class);
-
-	/**
-	 * Epsilon value used for comparison of doubles.
-	 */
-	private double									 epsilon;
-
-	/**
-	 * Comparator for {@link Ion} implementation of {@link Chemical}.
-	 */
-	private IonComparator						 ionComparator;
-
-	/**
-	 * Comparator for {@link SimpleMolecule} implementation of {@link Chemical}.
-	 */
-	private SimpleMoleculeComparator simpleMoleculeComparator;
-
-	/**
-	 * Constructor that requires {@link #epsilon} parameter.
-	 * 
-	 * @param epsilon
-	 *          {@link #epsilon}
-	 */
-	public ChemicalComparator(double epsilon) {
-		this.epsilon = epsilon;
-		ionComparator = new IonComparator(epsilon);
-		simpleMoleculeComparator = new SimpleMoleculeComparator(epsilon);
-	}
-
-	/**
-	 * Default constructor.
-	 */
-	public ChemicalComparator() {
-		this(Configuration.EPSILON);
-	}
-
-	@Override
-	public int compare(Chemical arg0, Chemical arg1) {
-		if (arg0 == null) {
-			if (arg1 == null) {
-				return 0;
-			} else {
-				return 1;
-			}
-		} else if (arg1 == null) {
-			return -1;
-		}
-
-		if (arg0.getClass().equals(arg1.getClass())) {
-			if (arg0.getClass().equals(Ion.class)) {
-				return ionComparator.compare((Ion) arg0, (Ion) arg1);
-			} else if (arg0.getClass().equals(SimpleMolecule.class)) {
-				return simpleMoleculeComparator.compare((SimpleMolecule) arg0, (SimpleMolecule) arg1);
-			} else {
-				throw new NotImplementedException("Don't know how to compare classes: " + arg0.getClass());
-			}
-		} else {
-			return -1;
-		}
-	}
-
-	/**
-	 * This method compares only the fields that are defined in {@link Chemical}
-	 * class in inheritence tree. By the design it calls also comparator of the
-	 * upper ({@link Species}) class.
-	 * 
-	 * @param arg0
-	 *          first object to compare
-	 * @param arg1
-	 *          second object to compare
-	 * @return if all fields are qual then returns 0. If they are different then
-	 *         -1/1 is returned.
-	 */
-	int internalCompare(Chemical arg0, Chemical arg1) {
-		SpeciesComparator speciesComparator = new SpeciesComparator(epsilon);
-		int result = speciesComparator.internalCompare(arg0, arg1);
-		if (result != 0) {
-			return result;
-		}
-		StringComparator stringComparator = new StringComparator();
-
-		if (stringComparator.compare(arg0.getSmiles(), arg1.getSmiles()) != 0) {
-			logger.debug("Smiles different: " + arg0.getSmiles() + ", " + arg1.getSmiles());
-			return stringComparator.compare(arg0.getSmiles(), arg1.getSmiles());
-		}
-
-		if (stringComparator.compare(arg0.getInChIKey(), arg1.getInChIKey()) != 0) {
-			logger.debug("InChIKey different: " + arg0.getInChIKey() + ", " + arg1.getInChIKey());
-			return stringComparator.compare(arg0.getInChIKey(), arg1.getInChIKey());
-		}
-
-		if (stringComparator.compare(arg0.getInChI(), arg1.getInChI()) != 0) {
-			logger.debug("InChI different: " + arg0.getInChI() + ", " + arg1.getInChI());
-			return stringComparator.compare(arg0.getInChI(), arg1.getInChI());
-		}
-
-		return 0;
-	}
+public class ChemicalComparator extends Comparator<Chemical> {
+
+  /**
+   * Default class logger.
+   */
+  private static Logger logger = Logger.getLogger(ChemicalComparator.class);
+
+  /**
+   * Epsilon value used for comparison of doubles.
+   */
+  private double epsilon;
+
+  /**
+   * Constructor that requires {@link #epsilon} parameter.
+   * 
+   * @param epsilon
+   *          {@link #epsilon}
+   */
+  public ChemicalComparator(double epsilon) {
+    super(Chemical.class, true);
+    this.epsilon = epsilon;
+    addSubClassComparator(new IonComparator(epsilon));
+    addSubClassComparator(new SimpleMoleculeComparator(epsilon));
+  }
+
+  @Override
+  protected Comparator<?> getParentComparator() {
+    return new SpeciesComparator(epsilon);
+  }
+
+  /**
+   * Default constructor.
+   */
+  public ChemicalComparator() {
+    this(Configuration.EPSILON);
+  }
+
+  @Override
+  protected int internalCompare(Chemical arg0, Chemical arg1) {
+    StringComparator stringComparator = new StringComparator();
+
+    if (stringComparator.compare(arg0.getSmiles(), arg1.getSmiles()) != 0) {
+      logger.debug("Smiles different: " + arg0.getSmiles() + ", " + arg1.getSmiles());
+      return stringComparator.compare(arg0.getSmiles(), arg1.getSmiles());
+    }
+
+    if (stringComparator.compare(arg0.getInChIKey(), arg1.getInChIKey()) != 0) {
+      logger.debug("InChIKey different: " + arg0.getInChIKey() + ", " + arg1.getInChIKey());
+      return stringComparator.compare(arg0.getInChIKey(), arg1.getInChIKey());
+    }
+
+    if (stringComparator.compare(arg0.getInChI(), arg1.getInChI()) != 0) {
+      logger.debug("InChI different: " + arg0.getInChI() + ", " + arg1.getInChI());
+      return stringComparator.compare(arg0.getInChI(), arg1.getInChI());
+    }
+
+    return 0;
+  }
 }
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/species/ComplexComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/species/ComplexComparator.java
index e7a29c9ddbc43e583a4808e471c4c316c05cae8b..b452ec2ceac2ebdf836befe1ed5b4c910505e1c1 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/species/ComplexComparator.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/species/ComplexComparator.java
@@ -1,16 +1,15 @@
 package lcsb.mapviewer.model.map.species;
 
-import java.util.Comparator;
 import java.util.HashMap;
 import java.util.Map;
 
 import org.apache.log4j.Logger;
 
+import lcsb.mapviewer.common.Comparator;
 import lcsb.mapviewer.common.Configuration;
 import lcsb.mapviewer.common.comparator.IntegerComparator;
 import lcsb.mapviewer.common.comparator.StringComparator;
 import lcsb.mapviewer.common.exception.InvalidArgumentException;
-import lcsb.mapviewer.common.exception.NotImplementedException;
 
 /**
  * This class implements comparator interface for {@link Complex}.
@@ -18,117 +17,84 @@ import lcsb.mapviewer.common.exception.NotImplementedException;
  * @author Piotr Gawron
  * 
  */
-public class ComplexComparator implements Comparator<Complex> {
-	/**
-	 * Default class logger.
-	 */
-	private static Logger	logger = Logger.getLogger(ComplexComparator.class);
-
-	/**
-	 * Epsilon value used for comparison of doubles.
-	 */
-	private double				epsilon;
-
-	/**
-	 * Constructor that requires {@link #epsilon} parameter.
-	 * 
-	 * @param epsilon
-	 *          {@link #epsilon}
-	 */
-	public ComplexComparator(double epsilon) {
-		this.epsilon = epsilon;
-	}
-
-	/**
-	 * Default constructor.
-	 */
-	public ComplexComparator() {
-		this(Configuration.EPSILON);
-	}
-
-	@Override
-	public int compare(Complex arg0, Complex arg1) {
-		if (arg0 == null) {
-			if (arg1 == null) {
-				return 0;
-			} else {
-				return 1;
-			}
-		} else if (arg1 == null) {
-			return -1;
-		}
-
-		if (arg0.getClass().equals(arg1.getClass())) {
-			if (arg0.getClass().equals(Complex.class)) {
-				return internalCompare(arg0, arg1);
-			} else {
-				throw new NotImplementedException("Don't know how to compare classes: " + arg0.getClass());
-			}
-		} else {
-			return -1;
-		}
-	}
-
-	/**
-	 * This method compares only the fields that are defined in {@link Complex}
-	 * class in inheritence tree. By the design it calls also comparator of the
-	 * upper ({@link Species}) class.
-	 * 
-	 * @param arg0
-	 *          first object to compare
-	 * @param arg1
-	 *          second object to compare
-	 * @return if all fields are qual then returns 0. If they are different then
-	 *         -1/1 is returned.
-	 */
-	private int internalCompare(Complex arg0, Complex arg1) {
-		SpeciesComparator speciesComparator = new SpeciesComparator(epsilon);
-		ElementComparator elementComparator = new ElementComparator(epsilon);
-		int result = speciesComparator.internalCompare(arg0, arg1);
-		if (result != 0) {
-			return result;
-		}
-
-		IntegerComparator integerComparator = new IntegerComparator();
-
-		if (integerComparator.compare(arg0.getElements().size(), arg1.getElements().size()) != 0) {
-			logger.debug("children elements size different: " + arg0.getElements().size() + ", " + arg1.getElements().size());
-			return integerComparator.compare(arg0.getElements().size(), arg1.getElements().size());
-		}
-
-		Map<String, Element> map1 = new HashMap<>();
-		Map<String, Element> map2 = new HashMap<>();
-
-		for (Element element : arg0.getElements()) {
-			if (map1.get(element.getElementId()) != null) {
-				throw new InvalidArgumentException("Few elements with the same id: " + element.getElementId());
-			}
-			map1.put(element.getElementId(), element);
-		}
-
-		for (Element element : arg1.getElements()) {
-			if (map2.get(element.getElementId()) != null) {
-				throw new InvalidArgumentException("Few elements with the same id: " + element.getElementId());
-			}
-			map2.put(element.getElementId(), element);
-		}
-
-		for (Element element : arg0.getElements()) {
-			Element element2 = map2.get(element.getElementId());
-			int status = elementComparator.compare(element, element2);
-			if (status != 0) {
-				logger.debug("child doesn't have a match: " + element.getElementId());
-				return status;
-			}
-		}
-
-		StringComparator stringComparator = new StringComparator();
-
-		if (stringComparator.compare(arg0.getStructuralState(), arg1.getStructuralState()) != 0) {
-			logger.debug("Species structuralState different: " + arg0.getStructuralState() + ", " + arg1.getStructuralState());
-			return stringComparator.compare(arg0.getStructuralState(), arg1.getStructuralState());
-		}
-
-		return 0;
-	}
+public class ComplexComparator extends Comparator<Complex> {
+  /**
+   * Default class logger.
+   */
+  private static Logger logger = Logger.getLogger(ComplexComparator.class);
+
+  /**
+   * Epsilon value used for comparison of doubles.
+   */
+  private double epsilon;
+
+  /**
+   * Constructor that requires {@link #epsilon} parameter.
+   * 
+   * @param epsilon
+   *          {@link #epsilon}
+   */
+  public ComplexComparator(double epsilon) {
+    super(Complex.class, true);
+    this.epsilon = epsilon;
+  }
+
+  @Override
+  protected Comparator<?> getParentComparator() {
+    return new SpeciesComparator(epsilon);
+  }
+
+  /**
+   * Default constructor.
+   */
+  public ComplexComparator() {
+    this(Configuration.EPSILON);
+  }
+
+  @Override
+  protected int internalCompare(Complex arg0, Complex arg1) {
+    ElementComparator elementComparator = new ElementComparator(epsilon);
+    IntegerComparator integerComparator = new IntegerComparator();
+
+    if (integerComparator.compare(arg0.getElements().size(), arg1.getElements().size()) != 0) {
+      logger.debug("children elements size different: " + arg0.getElements().size() + ", " + arg1.getElements().size());
+      return integerComparator.compare(arg0.getElements().size(), arg1.getElements().size());
+    }
+
+    Map<String, Element> map1 = new HashMap<>();
+    Map<String, Element> map2 = new HashMap<>();
+
+    for (Element element : arg0.getElements()) {
+      if (map1.get(element.getElementId()) != null) {
+        throw new InvalidArgumentException("Few elements with the same id: " + element.getElementId());
+      }
+      map1.put(element.getElementId(), element);
+    }
+
+    for (Element element : arg1.getElements()) {
+      if (map2.get(element.getElementId()) != null) {
+        throw new InvalidArgumentException("Few elements with the same id: " + element.getElementId());
+      }
+      map2.put(element.getElementId(), element);
+    }
+
+    for (Element element : arg0.getElements()) {
+      Element element2 = map2.get(element.getElementId());
+      int status = elementComparator.compare(element, element2);
+      if (status != 0) {
+        logger.debug("child doesn't have a match: " + element.getElementId());
+        return status;
+      }
+    }
+
+    StringComparator stringComparator = new StringComparator();
+
+    if (stringComparator.compare(arg0.getStructuralState(), arg1.getStructuralState()) != 0) {
+      logger
+          .debug("Species structuralState different: " + arg0.getStructuralState() + ", " + arg1.getStructuralState());
+      return stringComparator.compare(arg0.getStructuralState(), arg1.getStructuralState());
+    }
+
+    return 0;
+  }
 }
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/species/DegradedComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/species/DegradedComparator.java
index e7161064267021662914e55ac0c1fc7e346a1bce..51333b2e03ff566ce3ff47b8d304e923ea342aae 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/species/DegradedComparator.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/species/DegradedComparator.java
@@ -1,11 +1,9 @@
 package lcsb.mapviewer.model.map.species;
 
-import java.util.Comparator;
-
 import org.apache.log4j.Logger;
 
+import lcsb.mapviewer.common.Comparator;
 import lcsb.mapviewer.common.Configuration;
-import lcsb.mapviewer.common.exception.NotImplementedException;
 
 /**
  * Comparator class used for comparing {@link Degraded} objects.
@@ -13,77 +11,44 @@ import lcsb.mapviewer.common.exception.NotImplementedException;
  * @author Piotr Gawron
  *
  */
-public class DegradedComparator implements Comparator<Degraded> {
-
-	/**
-	 * Default class logger.
-	 */
-	@SuppressWarnings("unused")
-	private static Logger	logger = Logger.getLogger(DegradedComparator.class);
-
-	/**
-	 * Epsilon value used for comparison of doubles.
-	 */
-	private double				epsilon;
-
-	/**
-	 * Constructor that requires {@link #epsilon} parameter.
-	 * 
-	 * @param epsilon
-	 *          {@link #epsilon}
-	 */
-	public DegradedComparator(double epsilon) {
-		this.epsilon = epsilon;
-	}
-
-	/**
-	 * Default constructor.
-	 */
-	public DegradedComparator() {
-		this(Configuration.EPSILON);
-	}
-
-	@Override
-	public int compare(Degraded arg0, Degraded arg1) {
-		if (arg0 == null) {
-			if (arg1 == null) {
-				return 0;
-			} else {
-				return 1;
-			}
-		} else if (arg1 == null) {
-			return -1;
-		}
-
-		if (arg0.getClass().equals(arg1.getClass())) {
-			if (arg0.getClass().equals(Degraded.class)) {
-				return internalCompare(arg0, arg1);
-			} else {
-				throw new NotImplementedException("Don't know how to compare classes: " + arg0.getClass());
-			}
-		} else {
-			return -1;
-		}
-	}
-
-	/**
-	 * This method compares only the fields that are defined in {@link Degraded}
-	 * class in inheritence tree. By the design it calls also comparator of the
-	 * upper ({@link Species}) class.
-	 * 
-	 * @param arg0
-	 *          first object to compare
-	 * @param arg1
-	 *          second object to compare
-	 * @return if all fields are qual then returns 0. If they are different then
-	 *         -1/1 is returned.
-	 */
-	private int internalCompare(Degraded arg0, Degraded arg1) {
-		SpeciesComparator speciesComparator = new SpeciesComparator(epsilon);
-		int result = speciesComparator.internalCompare(arg0, arg1);
-		if (result != 0) {
-			return result;
-		}
-		return 0;
-	}
+public class DegradedComparator extends Comparator<Degraded> {
+
+  /**
+   * Default class logger.
+   */
+  @SuppressWarnings("unused")
+  private static Logger logger = Logger.getLogger(DegradedComparator.class);
+
+  /**
+   * Epsilon value used for comparison of doubles.
+   */
+  private double epsilon;
+
+  /**
+   * Constructor that requires {@link #epsilon} parameter.
+   * 
+   * @param epsilon
+   *          {@link #epsilon}
+   */
+  public DegradedComparator(double epsilon) {
+    super(Degraded.class, true);
+    this.epsilon = epsilon;
+  }
+
+  @Override
+  protected Comparator<?> getParentComparator() {
+    return new SpeciesComparator(epsilon);
+  }
+
+  /**
+   * Default constructor.
+   */
+  public DegradedComparator() {
+    this(Configuration.EPSILON);
+  }
+
+  @Override
+  protected int internalCompare(Degraded arg0, Degraded arg1) {
+    return 0;
+  }
 }
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/species/DrugComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/species/DrugComparator.java
index 3732d4c347db1d63d8e8129ee733aa586f49cedd..7f0173f5f44056acb09d8ee849a8953f67147556 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/species/DrugComparator.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/species/DrugComparator.java
@@ -1,11 +1,9 @@
 package lcsb.mapviewer.model.map.species;
 
-import java.util.Comparator;
-
 import org.apache.log4j.Logger;
 
+import lcsb.mapviewer.common.Comparator;
 import lcsb.mapviewer.common.Configuration;
-import lcsb.mapviewer.common.exception.NotImplementedException;
 
 /**
  * Comparator class used for comparing {@link Drug} objects.
@@ -13,77 +11,44 @@ import lcsb.mapviewer.common.exception.NotImplementedException;
  * @author Piotr Gawron
  *
  */
-public class DrugComparator implements Comparator<Drug> {
-
-	/**
-	 * Default class logger.
-	 */
-	@SuppressWarnings("unused")
-	private static Logger	logger = Logger.getLogger(DrugComparator.class);
-
-	/**
-	 * Epsilon value used for comparison of doubles.
-	 */
-	private double				epsilon;
-
-	/**
-	 * Constructor that requires {@link #epsilon} parameter.
-	 * 
-	 * @param epsilon
-	 *          {@link #epsilon}
-	 */
-	public DrugComparator(double epsilon) {
-		this.epsilon = epsilon;
-	}
-
-	/**
-	 * Default constructor.
-	 */
-	public DrugComparator() {
-		this(Configuration.EPSILON);
-	}
-
-	@Override
-	public int compare(Drug arg0, Drug arg1) {
-		if (arg0 == null) {
-			if (arg1 == null) {
-				return 0;
-			} else {
-				return 1;
-			}
-		} else if (arg1 == null) {
-			return -1;
-		}
-
-		if (arg0.getClass().equals(arg1.getClass())) {
-			if (arg0.getClass().equals(Drug.class)) {
-				return internalCompare(arg0, arg1);
-			} else {
-				throw new NotImplementedException("Don't know how to compare classes: " + arg0.getClass());
-			}
-		} else {
-			return -1;
-		}
-	}
-
-	/**
-	 * This method compares only the fields that are defined in {@link Drug} class
-	 * in inheritence tree. By the design it calls also comparator of the upper (
-	 * {@link Species}) class.
-	 * 
-	 * @param arg0
-	 *          first object to compare
-	 * @param arg1
-	 *          second object to compare
-	 * @return if all fields are qual then returns 0. If they are different then
-	 *         -1/1 is returned.
-	 */
-	private int internalCompare(Drug arg0, Drug arg1) {
-		SpeciesComparator speciesComparator = new SpeciesComparator(epsilon);
-		int result = speciesComparator.internalCompare(arg0, arg1);
-		if (result != 0) {
-			return result;
-		}
-		return 0;
-	}
+public class DrugComparator extends Comparator<Drug> {
+
+  /**
+   * Default class logger.
+   */
+  @SuppressWarnings("unused")
+  private static Logger logger = Logger.getLogger(DrugComparator.class);
+
+  /**
+   * Epsilon value used for comparison of doubles.
+   */
+  private double epsilon;
+
+  /**
+   * Constructor that requires {@link #epsilon} parameter.
+   * 
+   * @param epsilon
+   *          {@link #epsilon}
+   */
+  public DrugComparator(double epsilon) {
+    super(Drug.class, true);
+    this.epsilon = epsilon;
+  }
+
+  /**
+   * Default constructor.
+   */
+  public DrugComparator() {
+    this(Configuration.EPSILON);
+  }
+
+  @Override
+  protected Comparator<?> getParentComparator() {
+    return new SpeciesComparator(epsilon);
+  }
+
+  @Override
+  protected int internalCompare(Drug arg0, Drug arg1) {
+    return 0;
+  }
 }
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/species/ElementComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/species/ElementComparator.java
index a462b0538a649343670dab32c89c2862997da132..098c7d1f679bea0fb9e0d617ad77d2e4dd745f09 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/species/ElementComparator.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/species/ElementComparator.java
@@ -1,20 +1,19 @@
 package lcsb.mapviewer.model.map.species;
 
-import java.util.Comparator;
 import java.util.HashSet;
 import java.util.Set;
 
 import org.apache.log4j.Logger;
 
+import lcsb.mapviewer.common.Comparator;
 import lcsb.mapviewer.common.Configuration;
+import lcsb.mapviewer.common.comparator.ColorComparator;
 import lcsb.mapviewer.common.comparator.DoubleComparator;
 import lcsb.mapviewer.common.comparator.IntegerComparator;
 import lcsb.mapviewer.common.comparator.StringComparator;
 import lcsb.mapviewer.common.comparator.StringListComparator;
 import lcsb.mapviewer.common.comparator.StringSetComparator;
-import lcsb.mapviewer.common.exception.NotImplementedException;
 import lcsb.mapviewer.model.map.MiriamData;
-import lcsb.mapviewer.model.map.compartment.Compartment;
 import lcsb.mapviewer.model.map.compartment.CompartmentComparator;
 import lcsb.mapviewer.model.map.model.ElementSubmodelConnectionComparator;
 
@@ -24,218 +23,181 @@ import lcsb.mapviewer.model.map.model.ElementSubmodelConnectionComparator;
  * @author Piotr Gawron
  *
  */
-public class ElementComparator implements Comparator<Element> {
-	/**
-	 * Default class logger.
-	 */
-	private static Logger	logger = Logger.getLogger(ElementComparator.class);
-
-	/**
-	 * Epsilon value used for comparison of doubles.
-	 */
-	private double				epsilon;
-
-	/**
-	 * Constructor that requires {@link #epsilon} parameter.
-	 * 
-	 * @param epsilon
-	 *          {@link #epsilon}
-	 */
-	public ElementComparator(double epsilon) {
-		this.epsilon = epsilon;
-	}
-
-	/**
-	 * Default constructor.
-	 */
-	public ElementComparator() {
-		this(Configuration.EPSILON);
-	}
-
-	@Override
-	public int compare(Element arg0, Element arg1) {
-		if (arg0 == null) {
-			if (arg1 == null) {
-				return 0;
-			} else {
-				return 1;
-			}
-		} else if (arg1 == null) {
-			return -1;
-		}
-
-		if (arg0.getClass().equals(arg1.getClass())) {
-			if (arg0 instanceof Complex) {
-				ComplexComparator caComparator = new ComplexComparator(epsilon);
-				return caComparator.compare((Complex) arg0, (Complex) arg1);
-			} else if (arg0 instanceof Compartment) {
-				CompartmentComparator caComparator = new CompartmentComparator(epsilon);
-				return caComparator.compare((Compartment) arg0, (Compartment) arg1);
-			} else if (arg0 instanceof Species) {
-				SpeciesComparator caComparator = new SpeciesComparator(epsilon);
-				return caComparator.compare((Species) arg0, (Species) arg1);
-			} else {
-				throw new NotImplementedException("Don't know how to compare classes: " + arg0.getClass());
-			}
-		} else {
-			logger.debug("Mismatch class type: " + arg0.getClass() + ", " + arg1.getClass());
-			return -1;
-		}
-	}
-
-	/**
-	 * This method compares only the fields that are defined in {@link Element}
-	 * class in inheritence tree. By the design it is called by subclass
-	 * comparator.
-	 * 
-	 * @param arg0
-	 *          first object to compare
-	 * @param arg1
-	 *          second object to compare
-	 * @return if all fields are qual then returns 0. If they are different then
-	 *         -1/1 is returned.
-	 */
-	public int internalCompare(Element arg0, Element arg1) {
-		if (arg0 == null) {
-			if (arg1 == null) {
-				return 0;
-			} else {
-				return 1;
-			}
-		} else if (arg1 == null) {
-			return -1;
-		}
-
-		StringComparator stringComparator = new StringComparator();
-		IntegerComparator integerComparator = new IntegerComparator();
-		DoubleComparator doubleComparator = new DoubleComparator(epsilon);
-
-		if (stringComparator.compare(arg0.getElementId(), arg1.getElementId()) != 0) {
-			logger.debug("ElementId different: " + arg0.getElementId() + ", " + arg1.getElementId());
-			return stringComparator.compare(arg0.getElementId(), arg1.getElementId());
-		}
-
-		if (doubleComparator.compare(arg0.getX(), arg1.getX()) != 0) {
-			logger.debug("X different: " + arg0.getX() + ", " + arg1.getX());
-			return doubleComparator.compare(arg0.getX(), arg1.getX());
-		}
-
-		if (doubleComparator.compare(arg0.getY(), arg1.getY()) != 0) {
-			logger.debug("Y different: " + arg0.getY() + ", " + arg1.getY());
-			return doubleComparator.compare(arg0.getY(), arg1.getY());
-		}
-
-		if (doubleComparator.compare(arg0.getWidth(), arg1.getWidth()) != 0) {
-			logger.debug("Width different: " + arg0.getWidth() + ", " + arg1.getWidth());
-			return doubleComparator.compare(arg0.getWidth(), arg1.getWidth());
-		}
-
-		if (doubleComparator.compare(arg0.getHeight(), arg1.getHeight()) != 0) {
-			logger.debug("Height different: " + arg0.getHeight() + ", " + arg1.getHeight());
-			return doubleComparator.compare(arg0.getHeight(), arg1.getHeight());
-		}
-
-		if (doubleComparator.compare(arg0.getFontSize(), arg1.getFontSize()) != 0) {
-			logger.debug("Font size different: " + arg0.getFontSize() + ", " + arg1.getFontSize());
-			return doubleComparator.compare(arg0.getFontSize(), arg1.getFontSize());
-		}
-
-		if (stringComparator.compare(arg0.getVisibilityLevel(), arg1.getVisibilityLevel()) != 0) {
-			logger.debug("Visibility level different: " + arg0.getVisibilityLevel() + ", " + arg1.getVisibilityLevel());
-			return stringComparator.compare(arg0.getVisibilityLevel(), arg1.getVisibilityLevel());
-		}
-
-		if (integerComparator.compare(arg0.getColor().getRGB(), arg1.getColor().getRGB()) != 0) {
-			logger.debug("Color different: " + arg0.getColor().getRGB() + ", " + arg1.getColor().getRGB());
-			return integerComparator.compare(arg0.getColor().getRGB(), arg1.getColor().getRGB());
-		}
-
-		// this should be somehow modified, because it can create a situation where
-		// comparison will fall into infinite loop (in cyclic submodels)
-		ElementSubmodelConnectionComparator ascc = new ElementSubmodelConnectionComparator(epsilon);
-		int status = ascc.compare(arg0.getSubmodel(), arg1.getSubmodel());
-		if (status != 0) {
-			logger.debug("Element submodel different: " + arg0.getSubmodel() + ", " + arg1.getSubmodel());
-			return status;
-		}
-
-		if (stringComparator.compare(arg0.getName(), arg1.getName()) != 0) {
-			logger.debug("Name different: " + arg0.getName() + ", " + arg1.getName());
-			return stringComparator.compare(arg0.getName(), arg1.getName());
-		}
-
-		if (stringComparator.compare(arg0.getNotes(), arg1.getNotes(), true) != 0) {
-			logger.debug("notes different: \n\"" + arg0.getNotes() + "\"\n\"" + arg1.getNotes() + "\"");
-			return stringComparator.compare(arg0.getNotes(), arg1.getNotes());
-		}
-
-		if (stringComparator.compare(arg0.getSymbol(), arg1.getSymbol()) != 0) {
-			logger.debug("symbol different: \"" + arg0.getSymbol() + "\", \"" + arg1.getSymbol() + "\"");
-			return stringComparator.compare(arg0.getSymbol(), arg1.getSymbol());
-		}
-
-		if (stringComparator.compare(arg0.getFullName(), arg1.getFullName()) != 0) {
-			logger.debug("full name different: \"" + arg0.getFullName() + "\", \"" + arg1.getFullName() + "\"");
-			return stringComparator.compare(arg0.getFullName(), arg1.getFullName());
-		}
-
-		if (stringComparator.compare(arg0.getAbbreviation(), arg1.getAbbreviation()) != 0) {
-			logger.debug("Abbreviation different: \"" + arg0.getAbbreviation() + "\", \"" + arg1.getAbbreviation() + "\"");
-			return stringComparator.compare(arg0.getAbbreviation(), arg1.getAbbreviation());
-		}
-
-		if (stringComparator.compare(arg0.getFormula(), arg1.getFormula()) != 0) {
-			logger.debug("formula different: \"" + arg0.getFormula() + "\", \"" + arg1.getFormula() + "\"");
-			return stringComparator.compare(arg0.getFormula(), arg1.getFormula());
-		}
-
-		StringSetComparator stringSetComparator = new StringSetComparator();
-		StringListComparator stringListComparator = new StringListComparator();
-
-		if (stringListComparator.compare(arg0.getSynonyms(), arg1.getSynonyms()) != 0) {
-			logger.debug("List of synonyms different");
-			return stringListComparator.compare(arg0.getSynonyms(), arg1.getSynonyms());
-		}
-
-		if (stringListComparator.compare(arg0.getFormerSymbols(), arg1.getFormerSymbols()) != 0) {
-			logger.debug("List of former symbols different");
-			return stringListComparator.compare(arg0.getFormerSymbols(), arg1.getFormerSymbols());
-		}
-
-		Set<String> hashCode1 = new HashSet<>();
-		Set<String> hashCode2 = new HashSet<>();
-
-		if (arg0.getMiriamData().size() != arg1.getMiriamData().size()) {
-			logger.debug("different number of annotations: " + arg0.getMiriamData().size() + ", " + arg1.getMiriamData().size());
-			return ((Integer) arg0.getMiriamData().size()).compareTo(arg1.getMiriamData().size());
-		}
-
-		for (MiriamData md : arg0.getMiriamData()) {
-			String hash = md.getRelationType() + "  " + md.getDataType() + "  " + md.getResource();
-			hashCode1.add(hash);
-		}
-
-		for (MiriamData md : arg1.getMiriamData()) {
-			String hash = md.getRelationType() + "  " + md.getDataType() + "  " + md.getResource();
-			hashCode2.add(hash);
-		}
-
-		if (stringSetComparator.compare(hashCode1, hashCode2) != 0) {
-			logger.debug("different annotations: ");
-			logger.debug("A:");
-			for (String string : hashCode1) {
-				logger.debug("|" + string + "|");
-			}
-			logger.debug("B:");
-			for (String string : hashCode2) {
-				logger.debug("|" + string + "|");
-			}
-			logger.debug("--");
-			return stringSetComparator.compare(hashCode1, hashCode2);
-
-		}
-
-		return 0;
-	}
+public class ElementComparator extends Comparator<Element> {
+  /**
+   * Default class logger.
+   */
+  private static Logger logger = Logger.getLogger(ElementComparator.class);
+
+  /**
+   * Epsilon value used for comparison of doubles.
+   */
+  private double epsilon;
+
+  /**
+   * Constructor that requires {@link #epsilon} parameter.
+   * 
+   * @param epsilon
+   *          {@link #epsilon}
+   */
+  public ElementComparator(double epsilon) {
+    super(Element.class, true);
+    this.epsilon = epsilon;
+    addSubClassComparator(new ComplexComparator(epsilon));
+    addSubClassComparator(new CompartmentComparator(epsilon));
+    addSubClassComparator(new SpeciesComparator(epsilon));
+  }
+
+  /**
+   * Default constructor.
+   */
+  public ElementComparator() {
+    this(Configuration.EPSILON);
+  }
+
+  @Override
+  protected int internalCompare(Element arg0, Element arg1) {
+    if (arg0 == null) {
+      if (arg1 == null) {
+        return 0;
+      } else {
+        return 1;
+      }
+    } else if (arg1 == null) {
+      return -1;
+    }
+
+    StringComparator stringComparator = new StringComparator();
+    ColorComparator colorComparator = new ColorComparator();
+    DoubleComparator doubleComparator = new DoubleComparator(epsilon);
+
+    if (stringComparator.compare(arg0.getElementId(), arg1.getElementId()) != 0) {
+      logger.debug("ElementId different: " + arg0.getElementId() + ", " + arg1.getElementId());
+      return stringComparator.compare(arg0.getElementId(), arg1.getElementId());
+    }
+
+    if (doubleComparator.compare(arg0.getX(), arg1.getX()) != 0) {
+      logger.debug("X different: " + arg0.getX() + ", " + arg1.getX());
+      return doubleComparator.compare(arg0.getX(), arg1.getX());
+    }
+
+    if (doubleComparator.compare(arg0.getY(), arg1.getY()) != 0) {
+      logger.debug("Y different: " + arg0.getY() + ", " + arg1.getY());
+      return doubleComparator.compare(arg0.getY(), arg1.getY());
+    }
+
+    if (doubleComparator.compare(arg0.getWidth(), arg1.getWidth()) != 0) {
+      logger.debug("Width different: " + arg0.getWidth() + ", " + arg1.getWidth());
+      return doubleComparator.compare(arg0.getWidth(), arg1.getWidth());
+    }
+
+    if (doubleComparator.compare(arg0.getHeight(), arg1.getHeight()) != 0) {
+      logger.debug("Height different: " + arg0.getHeight() + ", " + arg1.getHeight());
+      return doubleComparator.compare(arg0.getHeight(), arg1.getHeight());
+    }
+
+    if (doubleComparator.compare(arg0.getFontSize(), arg1.getFontSize()) != 0) {
+      logger.debug("Font size different: " + arg0.getFontSize() + ", " + arg1.getFontSize());
+      return doubleComparator.compare(arg0.getFontSize(), arg1.getFontSize());
+    }
+
+    if (stringComparator.compare(arg0.getVisibilityLevel(), arg1.getVisibilityLevel()) != 0) {
+      logger.debug("Visibility level different: " + arg0.getVisibilityLevel() + ", " + arg1.getVisibilityLevel());
+      return stringComparator.compare(arg0.getVisibilityLevel(), arg1.getVisibilityLevel());
+    }
+
+    if (colorComparator.compare(arg0.getColor(), arg1.getColor()) != 0) {
+      logger.debug("Color different: " + arg0.getColor() + ", " + arg1.getColor());
+      return colorComparator.compare(arg0.getColor(), arg1.getColor());
+    }
+
+    // this should be somehow modified, because it can create a situation where
+    // comparison will fall into infinite loop (in cyclic submodels)
+    ElementSubmodelConnectionComparator ascc = new ElementSubmodelConnectionComparator(epsilon);
+    int status = ascc.compare(arg0.getSubmodel(), arg1.getSubmodel());
+    if (status != 0) {
+      logger.debug("Element submodel different: " + arg0.getSubmodel() + ", " + arg1.getSubmodel());
+      return status;
+    }
+
+    if (stringComparator.compare(arg0.getName(), arg1.getName()) != 0) {
+      logger.debug("Name different: " + arg0.getName() + ", " + arg1.getName());
+      return stringComparator.compare(arg0.getName(), arg1.getName());
+    }
+
+    if (stringComparator.compare(arg0.getNotes(), arg1.getNotes(), true) != 0) {
+      logger.debug("notes different: \n\"" + arg0.getNotes() + "\"\n\"" + arg1.getNotes() + "\"");
+      return stringComparator.compare(arg0.getNotes(), arg1.getNotes());
+    }
+
+    if (stringComparator.compare(arg0.getSymbol(), arg1.getSymbol()) != 0) {
+      logger.debug("symbol different: \"" + arg0.getSymbol() + "\", \"" + arg1.getSymbol() + "\"");
+      return stringComparator.compare(arg0.getSymbol(), arg1.getSymbol());
+    }
+
+    if (stringComparator.compare(arg0.getFullName(), arg1.getFullName()) != 0) {
+      logger.debug("full name different: \"" + arg0.getFullName() + "\", \"" + arg1.getFullName() + "\"");
+      return stringComparator.compare(arg0.getFullName(), arg1.getFullName());
+    }
+
+    if (stringComparator.compare(arg0.getAbbreviation(), arg1.getAbbreviation()) != 0) {
+      logger.debug("Abbreviation different: \"" + arg0.getAbbreviation() + "\", \"" + arg1.getAbbreviation() + "\"");
+      return stringComparator.compare(arg0.getAbbreviation(), arg1.getAbbreviation());
+    }
+
+    if (stringComparator.compare(arg0.getFormula(), arg1.getFormula()) != 0) {
+      logger.debug("formula different: \"" + arg0.getFormula() + "\", \"" + arg1.getFormula() + "\"");
+      return stringComparator.compare(arg0.getFormula(), arg1.getFormula());
+    }
+
+    StringSetComparator stringSetComparator = new StringSetComparator();
+    StringListComparator stringListComparator = new StringListComparator();
+
+    if (stringListComparator.compare(arg0.getSynonyms(), arg1.getSynonyms()) != 0) {
+      logger.debug("List of synonyms different");
+      return stringListComparator.compare(arg0.getSynonyms(), arg1.getSynonyms());
+    }
+
+    if (stringListComparator.compare(arg0.getFormerSymbols(), arg1.getFormerSymbols()) != 0) {
+      logger.debug("List of former symbols different");
+      return stringListComparator.compare(arg0.getFormerSymbols(), arg1.getFormerSymbols());
+    }
+
+    Set<String> hashCode1 = new HashSet<>();
+    Set<String> hashCode2 = new HashSet<>();
+
+    if (arg0.getMiriamData().size() != arg1.getMiriamData().size()) {
+      logger.debug(
+          "different number of annotations: " + arg0.getMiriamData().size() + ", " + arg1.getMiriamData().size());
+      return ((Integer) arg0.getMiriamData().size()).compareTo(arg1.getMiriamData().size());
+    }
+
+    for (MiriamData md : arg0.getMiriamData()) {
+      String hash = md.getRelationType() + "  " + md.getDataType() + "  " + md.getResource();
+      hashCode1.add(hash);
+    }
+
+    for (MiriamData md : arg1.getMiriamData()) {
+      String hash = md.getRelationType() + "  " + md.getDataType() + "  " + md.getResource();
+      hashCode2.add(hash);
+    }
+
+    if (stringSetComparator.compare(hashCode1, hashCode2) != 0) {
+      logger.debug("different annotations: ");
+      logger.debug("A:");
+      for (String string : hashCode1) {
+        logger.debug("|" + string + "|");
+      }
+      logger.debug("B:");
+      for (String string : hashCode2) {
+        logger.debug("|" + string + "|");
+      }
+      logger.debug("--");
+      return stringSetComparator.compare(hashCode1, hashCode2);
+
+    }
+
+    return 0;
+  }
 
 }
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/species/GeneComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/species/GeneComparator.java
index 044e7f059f66da106463734a55716c220b541bb8..89b0aa38e0296cdd2206d121d925d35e6fafbfc5 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/species/GeneComparator.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/species/GeneComparator.java
@@ -1,14 +1,13 @@
 package lcsb.mapviewer.model.map.species;
 
-import java.util.Comparator;
 import java.util.HashSet;
 import java.util.Set;
 
 import org.apache.log4j.Logger;
 
+import lcsb.mapviewer.common.Comparator;
 import lcsb.mapviewer.common.Configuration;
 import lcsb.mapviewer.common.comparator.StringSetComparator;
-import lcsb.mapviewer.common.exception.NotImplementedException;
 import lcsb.mapviewer.model.map.species.field.ModificationResidue;
 
 /**
@@ -17,95 +16,61 @@ import lcsb.mapviewer.model.map.species.field.ModificationResidue;
  * @author Piotr Gawron
  *
  */
-public class GeneComparator implements Comparator<Gene> {
-
-	/**
-	 * Default class logger.
-	 */
-	@SuppressWarnings("unused")
-	private static Logger	logger = Logger.getLogger(GeneComparator.class);
-
-	/**
-	 * Epsilon value used for comparison of doubles.
-	 */
-	private double				epsilon;
-
-	/**
-	 * Constructor that requires {@link #epsilon} parameter.
-	 * 
-	 * @param epsilon
-	 *          {@link #epsilon}
-	 */
-	public GeneComparator(double epsilon) {
-		this.epsilon = epsilon;
-	}
-
-	/**
-	 * Default constructor.
-	 */
-	public GeneComparator() {
-		this(Configuration.EPSILON);
-	}
-
-	@Override
-	public int compare(Gene arg0, Gene arg1) {
-		if (arg0 == null) {
-			if (arg1 == null) {
-				return 0;
-			} else {
-				return 1;
-			}
-		} else if (arg1 == null) {
-			return -1;
-		}
-
-		if (arg0.getClass().equals(arg1.getClass())) {
-			if (arg0.getClass().equals(Gene.class)) {
-				return internalCompare(arg0, arg1);
-			} else {
-				throw new NotImplementedException("Don't know how to compare classes: " + arg0.getClass());
-			}
-		} else {
-			return -1;
-		}
-	}
-
-	/**
-	 * This method compares only the fields that are defined in {@link Gene} class
-	 * in inheritence tree. By the design it calls also comparator of the upper (
-	 * {@link Species}) class.
-	 * 
-	 * @param arg0
-	 *          first object to compare
-	 * @param arg1
-	 *          second object to compare
-	 * @return if all fields are qual then returns 0. If they are different then
-	 *         -1/1 is returned.
-	 */
-	private int internalCompare(Gene arg0, Gene arg1) {
-		SpeciesComparator speciesComparator = new SpeciesComparator(epsilon);
-		int result = speciesComparator.internalCompare(arg0, arg1);
-		if (result != 0) {
-			return result;
-		}
-
-		StringSetComparator stringSetComparator = new StringSetComparator();
-
-		Set<String> set1 = new HashSet<>();
-		Set<String> set2 = new HashSet<>();
-
-		for (ModificationResidue region : arg0.getModificationResidues()) {
-			set1.add(region.toString());
-		}
-
-		for (ModificationResidue region : arg1.getModificationResidues()) {
-			set2.add(region.toString());
-		}
-
-		if (stringSetComparator.compare(set1, set2) != 0) {
-			return stringSetComparator.compare(set1, set2);
-		}
-
-		return 0;
-	}
+public class GeneComparator extends Comparator<Gene> {
+
+  /**
+   * Default class logger.
+   */
+  @SuppressWarnings("unused")
+  private static Logger logger = Logger.getLogger(GeneComparator.class);
+
+  /**
+   * Epsilon value used for comparison of doubles.
+   */
+  private double epsilon;
+
+  /**
+   * Constructor that requires {@link #epsilon} parameter.
+   * 
+   * @param epsilon
+   *          {@link #epsilon}
+   */
+  public GeneComparator(double epsilon) {
+    super(Gene.class, true);
+    this.epsilon = epsilon;
+  }
+
+  /**
+   * Default constructor.
+   */
+  public GeneComparator() {
+    this(Configuration.EPSILON);
+  }
+
+  @Override
+  protected Comparator<?> getParentComparator() {
+    return new SpeciesComparator(epsilon);
+  }
+
+  @Override
+  protected int internalCompare(Gene arg0, Gene arg1) {
+    StringSetComparator stringSetComparator = new StringSetComparator();
+
+    Set<String> set1 = new HashSet<>();
+    Set<String> set2 = new HashSet<>();
+
+    for (ModificationResidue region : arg0.getModificationResidues()) {
+      set1.add(region.toString());
+    }
+
+    for (ModificationResidue region : arg1.getModificationResidues()) {
+      set2.add(region.toString());
+    }
+
+    if (stringSetComparator.compare(set1, set2) != 0) {
+      return stringSetComparator.compare(set1, set2);
+    }
+
+    return 0;
+  }
 }
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/species/GenericProteinComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/species/GenericProteinComparator.java
index ce6e0c5c2cafa37934e9ace0ccfda9b2a9d27eb8..694a41e8d6a7d61785e84aa63f9a088f31f9f937 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/species/GenericProteinComparator.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/species/GenericProteinComparator.java
@@ -1,11 +1,9 @@
 package lcsb.mapviewer.model.map.species;
 
-import java.util.Comparator;
-
 import org.apache.log4j.Logger;
 
+import lcsb.mapviewer.common.Comparator;
 import lcsb.mapviewer.common.Configuration;
-import lcsb.mapviewer.common.exception.NotImplementedException;
 
 /**
  * Comparator class used for comparing {@link GenericProtein} objects.
@@ -13,78 +11,44 @@ import lcsb.mapviewer.common.exception.NotImplementedException;
  * @author Piotr Gawron
  *
  */
-public class GenericProteinComparator implements Comparator<GenericProtein> {
-
-	/**
-	 * Default class logger.
-	 */
-	@SuppressWarnings("unused")
-	private static Logger	 logger	= Logger.getLogger(GenericProteinComparator.class);
-
-	/**
-	 * Epsilon value used for comparison of doubles.
-	 */
-	private double				 epsilon;
-
-
-	/**
-	 * Constructor that requires {@link #epsilon} parameter.
-	 * 
-	 * @param epsilon
-	 *          {@link #epsilon}
-	 */
-	public GenericProteinComparator(double epsilon) {
-		this.epsilon = epsilon;
-	}
-
-	/**
-	 * Default constructor.
-	 */
-	public GenericProteinComparator() {
-		this(Configuration.EPSILON);
-	}
-
-	@Override
-	public int compare(GenericProtein arg0, GenericProtein arg1) {
-		if (arg0 == null) {
-			if (arg1 == null) {
-				return 0;
-			} else {
-				return 1;
-			}
-		} else if (arg1 == null) {
-			return -1;
-		}
-
-		if (arg0.getClass().equals(arg1.getClass())) {
-			if (arg0.getClass().equals(GenericProtein.class)) {
-				return internalCompare(arg0, arg1);
-			} else {
-				throw new NotImplementedException("Don't know how to compare classes: " + arg0.getClass());
-			}
-		} else {
-			return -1;
-		}
-	}
-
-	/**
-	 * This method compares only the fields that are defined in
-	 * {@link GenericProtein} class in inheritence tree. By the design it
-	 * calls also comparator of the upper ({@link Protein}) class.
-	 * 
-	 * @param arg0
-	 *          first object to compare
-	 * @param arg1
-	 *          second object to compare
-	 * @return if all fields are qual then returns 0. If they are different then
-	 *         -1/1 is returned.
-	 */
-	private int internalCompare(GenericProtein arg0, GenericProtein arg1) {
-		ProteinComparator proteinComparator = new ProteinComparator(epsilon);
-		int result = proteinComparator.internalCompare(arg0, arg1);
-		if (result != 0) {
-			return result;
-		}
-		return 0;
-	}
+public class GenericProteinComparator extends Comparator<GenericProtein> {
+
+  /**
+   * Default class logger.
+   */
+  @SuppressWarnings("unused")
+  private static Logger logger = Logger.getLogger(GenericProteinComparator.class);
+
+  /**
+   * Epsilon value used for comparison of doubles.
+   */
+  private double epsilon;
+
+  /**
+   * Constructor that requires {@link #epsilon} parameter.
+   * 
+   * @param epsilon
+   *          {@link #epsilon}
+   */
+  public GenericProteinComparator(double epsilon) {
+    super(GenericProtein.class, true);
+    this.epsilon = epsilon;
+  }
+
+  /**
+   * Default constructor.
+   */
+  public GenericProteinComparator() {
+    this(Configuration.EPSILON);
+  }
+
+  @Override
+  protected Comparator<?> getParentComparator() {
+    return new ProteinComparator(epsilon);
+  }
+
+  @Override
+  protected int internalCompare(GenericProtein arg0, GenericProtein arg1) {
+    return 0;
+  }
 }
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/species/IonChannelProteinComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/species/IonChannelProteinComparator.java
index 8f6c3f4b8a27d76c615cf75f445f9bc18c98327d..3fead0056fb3b28bfca446c01f83c48cfe18ca5e 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/species/IonChannelProteinComparator.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/species/IonChannelProteinComparator.java
@@ -1,11 +1,9 @@
 package lcsb.mapviewer.model.map.species;
 
-import java.util.Comparator;
-
 import org.apache.log4j.Logger;
 
+import lcsb.mapviewer.common.Comparator;
 import lcsb.mapviewer.common.Configuration;
-import lcsb.mapviewer.common.exception.NotImplementedException;
 
 /**
  * Comparator class used for comparing {@link IonChannelProtein} objects.
@@ -13,77 +11,44 @@ import lcsb.mapviewer.common.exception.NotImplementedException;
  * @author Piotr Gawron
  *
  */
-public class IonChannelProteinComparator implements Comparator<IonChannelProtein> {
-
-	/**
-	 * Default class logger.
-	 */
-	@SuppressWarnings("unused")
-	private static Logger	logger = Logger.getLogger(IonChannelProteinComparator.class);
-
-	/**
-	 * Epsilon value used for comparison of doubles.
-	 */
-	private double				epsilon;
-
-	/**
-	 * Constructor that requires {@link #epsilon} parameter.
-	 * 
-	 * @param epsilon
-	 *          {@link #epsilon}
-	 */
-	public IonChannelProteinComparator(double epsilon) {
-		this.epsilon = epsilon;
-	}
-
-	/**
-	 * Default constructor.
-	 */
-	public IonChannelProteinComparator() {
-		this(Configuration.EPSILON);
-	}
-
-	@Override
-	public int compare(IonChannelProtein arg0, IonChannelProtein arg1) {
-		if (arg0 == null) {
-			if (arg1 == null) {
-				return 0;
-			} else {
-				return 1;
-			}
-		} else if (arg1 == null) {
-			return -1;
-		}
-
-		if (arg0.getClass().equals(arg1.getClass())) {
-			if (arg0.getClass().equals(IonChannelProtein.class)) {
-				return internalCompare(arg0, arg1);
-			} else {
-				throw new NotImplementedException("Don't know how to compare classes: " + arg0.getClass());
-			}
-		} else {
-			return -1;
-		}
-	}
-
-	/**
-	 * This method compares only the fields that are defined in
-	 * {@link IonChannelProtein} class in inheritence tree. By the design it calls
-	 * also comparator of the upper ({@link Species}) class.
-	 * 
-	 * @param arg0
-	 *          first object to compare
-	 * @param arg1
-	 *          second object to compare
-	 * @return if all fields are qual then returns 0. If they are different then
-	 *         -1/1 is returned.
-	 */
-	private int internalCompare(IonChannelProtein arg0, IonChannelProtein arg1) {
-		SpeciesComparator speciesComparator = new SpeciesComparator(epsilon);
-		int result = speciesComparator.internalCompare(arg0, arg1);
-		if (result != 0) {
-			return result;
-		}
-		return 0;
-	}
+public class IonChannelProteinComparator extends Comparator<IonChannelProtein> {
+
+  /**
+   * Default class logger.
+   */
+  @SuppressWarnings("unused")
+  private static Logger logger = Logger.getLogger(IonChannelProteinComparator.class);
+
+  /**
+   * Epsilon value used for comparison of doubles.
+   */
+  private double epsilon;
+
+  /**
+   * Constructor that requires {@link #epsilon} parameter.
+   * 
+   * @param epsilon
+   *          {@link #epsilon}
+   */
+  public IonChannelProteinComparator(double epsilon) {
+    super(IonChannelProtein.class, true);
+    this.epsilon = epsilon;
+  }
+
+  /**
+   * Default constructor.
+   */
+  public IonChannelProteinComparator() {
+    this(Configuration.EPSILON);
+  }
+
+  @Override
+  protected Comparator<?> getParentComparator() {
+    return new ProteinComparator(epsilon);
+  }
+
+  @Override
+  protected int internalCompare(IonChannelProtein arg0, IonChannelProtein arg1) {
+    return 0;
+  }
 }
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/species/IonComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/species/IonComparator.java
index 365f5de9f8fe5995b90e9b62e3c07410f005e194..d1a1f8ec3be548b36c65edd88d1a410ee4749a3a 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/species/IonComparator.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/species/IonComparator.java
@@ -1,11 +1,9 @@
 package lcsb.mapviewer.model.map.species;
 
-import java.util.Comparator;
-
 import org.apache.log4j.Logger;
 
+import lcsb.mapviewer.common.Comparator;
 import lcsb.mapviewer.common.Configuration;
-import lcsb.mapviewer.common.exception.NotImplementedException;
 
 /**
  * Comparator class used for comparing {@link Ion} objects.
@@ -13,77 +11,44 @@ import lcsb.mapviewer.common.exception.NotImplementedException;
  * @author Piotr Gawron
  *
  */
-public class IonComparator implements Comparator<Ion> {
-
-	/**
-	 * Default class logger.
-	 */
-	@SuppressWarnings("unused")
-	private static Logger	logger = Logger.getLogger(IonComparator.class);
-
-	/**
-	 * Epsilon value used for comparison of doubles.
-	 */
-	private double				epsilon;
-
-	/**
-	 * Constructor that requires {@link #epsilon} parameter.
-	 * 
-	 * @param epsilon
-	 *          {@link #epsilon}
-	 */
-	public IonComparator(double epsilon) {
-		this.epsilon = epsilon;
-	}
-
-	/**
-	 * Default constructor.
-	 */
-	public IonComparator() {
-		this(Configuration.EPSILON);
-	}
-
-	@Override
-	public int compare(Ion arg0, Ion arg1) {
-		if (arg0 == null) {
-			if (arg1 == null) {
-				return 0;
-			} else {
-				return 1;
-			}
-		} else if (arg1 == null) {
-			return -1;
-		}
-
-		if (arg0.getClass().equals(arg1.getClass())) {
-			if (arg0.getClass().equals(Ion.class)) {
-				return internalCompare(arg0, arg1);
-			} else {
-				throw new NotImplementedException("Don't know how to compare classes: " + arg0.getClass());
-			}
-		} else {
-			return -1;
-		}
-	}
-
-	/**
-	 * This method compares only the fields that are defined in {@link Ion} class
-	 * in inheritence tree. By the design it calls also comparator of the upper
-	 * {@link Chemical} class.
-	 * 
-	 * @param arg0
-	 *          first object to compare
-	 * @param arg1
-	 *          second object to compare
-	 * @return if all fields are qual then returns 0. If they are different then
-	 *         -1/1 is returned.
-	 */
-	private int internalCompare(Ion arg0, Ion arg1) {
-		ChemicalComparator speciesComparator = new ChemicalComparator(epsilon);
-		int result = speciesComparator.internalCompare(arg0, arg1);
-		if (result != 0) {
-			return result;
-		}
-		return 0;
-	}
+public class IonComparator extends Comparator<Ion> {
+
+  /**
+   * Default class logger.
+   */
+  @SuppressWarnings("unused")
+  private static Logger logger = Logger.getLogger(IonComparator.class);
+
+  /**
+   * Epsilon value used for comparison of doubles.
+   */
+  private double epsilon;
+
+  /**
+   * Constructor that requires {@link #epsilon} parameter.
+   * 
+   * @param epsilon
+   *          {@link #epsilon}
+   */
+  public IonComparator(double epsilon) {
+    super(Ion.class, true);
+    this.epsilon = epsilon;
+  }
+
+  /**
+   * Default constructor.
+   */
+  public IonComparator() {
+    this(Configuration.EPSILON);
+  }
+
+  @Override
+  protected Comparator<?> getParentComparator() {
+    return new ChemicalComparator(epsilon);
+  }
+
+  @Override
+  protected int internalCompare(Ion arg0, Ion arg1) {
+    return 0;
+  }
 }
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/species/PhenotypeComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/species/PhenotypeComparator.java
index 8b7af90f58594eaffed7cd61baff51b04a13f3b2..93be6412390919aa06374fc459ac8b38a4e1c840 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/species/PhenotypeComparator.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/species/PhenotypeComparator.java
@@ -1,11 +1,9 @@
 package lcsb.mapviewer.model.map.species;
 
-import java.util.Comparator;
-
 import org.apache.log4j.Logger;
 
+import lcsb.mapviewer.common.Comparator;
 import lcsb.mapviewer.common.Configuration;
-import lcsb.mapviewer.common.exception.NotImplementedException;
 
 /**
  * Comparator class used for comparing {@link Phenotype} objects.
@@ -13,77 +11,45 @@ import lcsb.mapviewer.common.exception.NotImplementedException;
  * @author Piotr Gawron
  *
  */
-public class PhenotypeComparator implements Comparator<Phenotype> {
-
-	/**
-	 * Default class logger.
-	 */
-	@SuppressWarnings("unused")
-	private static Logger	logger = Logger.getLogger(PhenotypeComparator.class);
-
-	/**
-	 * Epsilon value used for comparison of doubles.
-	 */
-	private double				epsilon;
-
-	/**
-	 * Constructor that requires {@link #epsilon} parameter.
-	 * 
-	 * @param epsilon
-	 *          {@link #epsilon}
-	 */
-	public PhenotypeComparator(double epsilon) {
-		this.epsilon = epsilon;
-	}
-
-	/**
-	 * Default constructor.
-	 */
-	public PhenotypeComparator() {
-		this(Configuration.EPSILON);
-	}
-
-	@Override
-	public int compare(Phenotype arg0, Phenotype arg1) {
-		if (arg0 == null) {
-			if (arg1 == null) {
-				return 0;
-			} else {
-				return 1;
-			}
-		} else if (arg1 == null) {
-			return -1;
-		}
-
-		if (arg0.getClass().equals(arg1.getClass())) {
-			if (arg0.getClass().equals(Phenotype.class)) {
-				return internalCompare(arg0, arg1);
-			} else {
-				throw new NotImplementedException("Don't know how to compare classes: " + arg0.getClass());
-			}
-		} else {
-			return -1;
-		}
-	}
-
-	/**
-	 * This method compares only the fields that are defined in {@link Phenotype}
-	 * class in inheritence tree. By the design it calls also comparator of the
-	 * upper ({@link Species}) class.
-	 * 
-	 * @param arg0
-	 *          first object to compare
-	 * @param arg1
-	 *          second object to compare
-	 * @return if all fields are qual then returns 0. If they are different then
-	 *         -1/1 is returned.
-	 */
-	private int internalCompare(Phenotype arg0, Phenotype arg1) {
-		SpeciesComparator speciesComparator = new SpeciesComparator(epsilon);
-		int result = speciesComparator.internalCompare(arg0, arg1);
-		if (result != 0) {
-			return result;
-		}
-		return 0;
-	}
+public class PhenotypeComparator extends Comparator<Phenotype> {
+
+  /**
+   * Default class logger.
+   */
+  @SuppressWarnings("unused")
+  private static Logger logger = Logger.getLogger(PhenotypeComparator.class);
+
+  /**
+   * Epsilon value used for comparison of doubles.
+   */
+  private double epsilon;
+
+  /**
+   * Constructor that requires {@link #epsilon} parameter.
+   * 
+   * @param epsilon
+   *          {@link #epsilon}
+   */
+  public PhenotypeComparator(double epsilon) {
+    super(Phenotype.class, true);
+    this.epsilon = epsilon;
+  }
+
+  /**
+   * Default constructor.
+   */
+  public PhenotypeComparator() {
+    this(Configuration.EPSILON);
+  }
+
+  @Override
+  protected Comparator<?> getParentComparator() {
+    return new SpeciesComparator(epsilon);
+  }
+
+  
+  @Override
+  protected int internalCompare(Phenotype arg0, Phenotype arg1) {
+    return 0;
+  }
 }
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/species/ProteinComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/species/ProteinComparator.java
index 53cee7bdba96b9f0268509e390073158ab466fb7..b397b9b4f3b38f956c0a93a9232b45cc6e9e5fb8 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/species/ProteinComparator.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/species/ProteinComparator.java
@@ -1,15 +1,14 @@
 package lcsb.mapviewer.model.map.species;
 
-import java.util.Comparator;
 import java.util.HashSet;
 import java.util.Set;
 
 import org.apache.log4j.Logger;
 
+import lcsb.mapviewer.common.Comparator;
 import lcsb.mapviewer.common.Configuration;
 import lcsb.mapviewer.common.comparator.StringComparator;
 import lcsb.mapviewer.common.comparator.StringSetComparator;
-import lcsb.mapviewer.common.exception.NotImplementedException;
 import lcsb.mapviewer.model.map.species.field.ModificationResidue;
 
 /**
@@ -18,131 +17,71 @@ import lcsb.mapviewer.model.map.species.field.ModificationResidue;
  * @author Piotr Gawron
  *
  */
-public class ProteinComparator implements Comparator<Protein> {
-
-	/**
-	 * Default class logger.
-	 */
-	private static Logger								logger = Logger.getLogger(ProteinComparator.class);
-
-	/**
-	 * Epsilon value used for comparison of doubles.
-	 */
-	private double											epsilon;
-
-	/**
-	 * Comparator for {@link GenericProtein} implementation of {@link Protein}.
-	 */
-	private GenericProteinComparator		genericProteinComparator;
-
-	/**
-	 * Comparator for {@link IonChannelProtein} implementation of {@link Protein}.
-	 */
-	private IonChannelProteinComparator	ionChannelProteinComparator;
-
-	/**
-	 * Comparator for {@link ReceptorProtein} implementation of {@link Protein}.
-	 */
-	private ReceptorProteinComparator		receptorProteinComparator;
-
-	/**
-	 * Comparator for {@link TruncatedProtein} implementation of {@link Protein}.
-	 */
-	private TruncatedProteinComparator	truncatedProteinComparator;
-
-	/**
-	 * Constructor that requires {@link #epsilon} parameter.
-	 * 
-	 * @param epsilon
-	 *          {@link #epsilon}
-	 */
-	public ProteinComparator(double epsilon) {
-		this.epsilon = epsilon;
-		genericProteinComparator = new GenericProteinComparator(epsilon);
-		ionChannelProteinComparator = new IonChannelProteinComparator(epsilon);
-		receptorProteinComparator = new ReceptorProteinComparator(epsilon);
-		truncatedProteinComparator = new TruncatedProteinComparator(epsilon);
-	}
-
-	/**
-	 * Default constructor.
-	 */
-	public ProteinComparator() {
-		this(Configuration.EPSILON);
-	}
-
-	@Override
-	public int compare(Protein arg0, Protein arg1) {
-		if (arg0 == null) {
-			if (arg1 == null) {
-				return 0;
-			} else {
-				return 1;
-			}
-		} else if (arg1 == null) {
-			return -1;
-		}
-
-		if (arg0.getClass().equals(arg1.getClass())) {
-			if (arg0.getClass().equals(GenericProtein.class)) {
-				return genericProteinComparator.compare((GenericProtein) arg0, (GenericProtein) arg1);
-			} else if (arg0.getClass().equals(IonChannelProtein.class)) {
-				return ionChannelProteinComparator.compare((IonChannelProtein) arg0, (IonChannelProtein) arg1);
-			} else if (arg0.getClass().equals(ReceptorProtein.class)) {
-				return receptorProteinComparator.compare((ReceptorProtein) arg0, (ReceptorProtein) arg1);
-			} else if (arg0.getClass().equals(TruncatedProtein.class)) {
-				return truncatedProteinComparator.compare((TruncatedProtein) arg0, (TruncatedProtein) arg1);
-			} else {
-				throw new NotImplementedException("Don't know how to compare classes: " + arg0.getClass());
-			}
-		} else {
-			return -1;
-		}
-	}
-
-	/**
-	 * This method compares only the fields that are defined in {@link Protein}
-	 * class in inheritence tree. By the design it calls also comparator of the
-	 * upper ({@link Species}) class.
-	 * 
-	 * @param arg0
-	 *          first object to compare
-	 * @param arg1
-	 *          second object to compare
-	 * @return if all fields are qual then returns 0. If they are different then
-	 *         -1/1 is returned.
-	 */
-	int internalCompare(Protein arg0, Protein arg1) {
-		SpeciesComparator speciesComparator = new SpeciesComparator(epsilon);
-		int result = speciesComparator.internalCompare(arg0, arg1);
-		if (result != 0) {
-			return result;
-		}
-
-		StringComparator stringComparator = new StringComparator();
-		StringSetComparator stringSetComparator = new StringSetComparator();
-
-		if (stringComparator.compare(arg0.getStructuralState(), arg1.getStructuralState()) != 0) {
-			logger.debug("structural state different: " + arg0.getStructuralState() + ", " + arg1.getStructuralState());
-			return stringComparator.compare(arg0.getStructuralState(), arg1.getStructuralState());
-		}
-
-		Set<String> set1 = new HashSet<>();
-		Set<String> set2 = new HashSet<>();
-
-		for (ModificationResidue region : arg0.getModificationResidues()) {
-			set1.add(region.toString());
-		}
-
-		for (ModificationResidue region : arg1.getModificationResidues()) {
-			set2.add(region.toString());
-		}
-
-		if (stringSetComparator.compare(set1, set2) != 0) {
-			logger.debug("modification residues different");
-			return stringSetComparator.compare(set1, set2);
-		}
-
-		return 0;
-	}
+public class ProteinComparator extends Comparator<Protein> {
+
+  /**
+   * Default class logger.
+   */
+  private static Logger logger = Logger.getLogger(ProteinComparator.class);
+
+  /**
+   * Epsilon value used for comparison of doubles.
+   */
+  private double epsilon;
+
+  /**
+   * Constructor that requires {@link #epsilon} parameter.
+   * 
+   * @param epsilon
+   *          {@link #epsilon}
+   */
+  public ProteinComparator(double epsilon) {
+    super(Protein.class, true);
+    this.epsilon = epsilon;
+    addSubClassComparator(new GenericProteinComparator(epsilon));
+    addSubClassComparator(new IonChannelProteinComparator(epsilon));
+    addSubClassComparator(new ReceptorProteinComparator(epsilon));
+    addSubClassComparator(new TruncatedProteinComparator(epsilon));
+  }
+
+  /**
+   * Default constructor.
+   */
+  public ProteinComparator() {
+    this(Configuration.EPSILON);
+  }
+
+  @Override
+  protected Comparator<?> getParentComparator() {
+    return new SpeciesComparator(epsilon);
+  }
+
+  @Override
+  protected int internalCompare(Protein arg0, Protein arg1) {
+    StringComparator stringComparator = new StringComparator();
+    StringSetComparator stringSetComparator = new StringSetComparator();
+
+    if (stringComparator.compare(arg0.getStructuralState(), arg1.getStructuralState()) != 0) {
+      logger.debug("structural state different: " + arg0.getStructuralState() + ", " + arg1.getStructuralState());
+      return stringComparator.compare(arg0.getStructuralState(), arg1.getStructuralState());
+    }
+
+    Set<String> set1 = new HashSet<>();
+    Set<String> set2 = new HashSet<>();
+
+    for (ModificationResidue region : arg0.getModificationResidues()) {
+      set1.add(region.toString());
+    }
+
+    for (ModificationResidue region : arg1.getModificationResidues()) {
+      set2.add(region.toString());
+    }
+
+    if (stringSetComparator.compare(set1, set2) != 0) {
+      logger.debug("modification residues different");
+      return stringSetComparator.compare(set1, set2);
+    }
+
+    return 0;
+  }
 }
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/species/ReceptorProteinComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/species/ReceptorProteinComparator.java
index 186498d9fc344c043ca46a0995ed35dec8e28873..8fef3d5d0c0db03c28cb7887ed00229111654ef9 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/species/ReceptorProteinComparator.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/species/ReceptorProteinComparator.java
@@ -1,11 +1,9 @@
 package lcsb.mapviewer.model.map.species;
 
-import java.util.Comparator;
-
 import org.apache.log4j.Logger;
 
+import lcsb.mapviewer.common.Comparator;
 import lcsb.mapviewer.common.Configuration;
-import lcsb.mapviewer.common.exception.NotImplementedException;
 
 /**
  * Comparator class used for comparing {@link ReceptorProtein} objects.
@@ -13,77 +11,44 @@ import lcsb.mapviewer.common.exception.NotImplementedException;
  * @author Piotr Gawron
  *
  */
-public class ReceptorProteinComparator implements Comparator<ReceptorProtein> {
-
-	/**
-	 * Default class logger.
-	 */
-	@SuppressWarnings("unused")
-	private static Logger	logger = Logger.getLogger(ReceptorProteinComparator.class);
-
-	/**
-	 * Epsilon value used for comparison of doubles.
-	 */
-	private double				epsilon;
-
-	/**
-	 * Constructor that requires {@link #epsilon} parameter.
-	 * 
-	 * @param epsilon
-	 *          {@link #epsilon}
-	 */
-	public ReceptorProteinComparator(double epsilon) {
-		this.epsilon = epsilon;
-	}
-
-	/**
-	 * Default constructor.
-	 */
-	public ReceptorProteinComparator() {
-		this(Configuration.EPSILON);
-	}
-
-	@Override
-	public int compare(ReceptorProtein arg0, ReceptorProtein arg1) {
-		if (arg0 == null) {
-			if (arg1 == null) {
-				return 0;
-			} else {
-				return 1;
-			}
-		} else if (arg1 == null) {
-			return -1;
-		}
-
-		if (arg0.getClass().equals(arg1.getClass())) {
-			if (arg0.getClass().equals(ReceptorProtein.class)) {
-				return internalCompare(arg0, arg1);
-			} else {
-				throw new NotImplementedException("Don't know how to compare classes: " + arg0.getClass());
-			}
-		} else {
-			return -1;
-		}
-	}
-
-	/**
-	 * This method compares only the fields that are defined in
-	 * {@link ReceptorProtein} class in inheritence tree. By the design it calls
-	 * also comparator of the upper ({@link Species}) class.
-	 * 
-	 * @param arg0
-	 *          first object to compare
-	 * @param arg1
-	 *          second object to compare
-	 * @return if all fields are qual then returns 0. If they are different then
-	 *         -1/1 is returned.
-	 */
-	private int internalCompare(ReceptorProtein arg0, ReceptorProtein arg1) {
-		ProteinComparator proteinComparator = new ProteinComparator(epsilon);
-		int result = proteinComparator.internalCompare(arg0, arg1);
-		if (result != 0) {
-			return result;
-		}
-		return 0;
-	}
+public class ReceptorProteinComparator extends Comparator<ReceptorProtein> {
+
+  /**
+   * Default class logger.
+   */
+  @SuppressWarnings("unused")
+  private static Logger logger = Logger.getLogger(ReceptorProteinComparator.class);
+
+  /**
+   * Epsilon value used for comparison of doubles.
+   */
+  private double epsilon;
+
+  /**
+   * Constructor that requires {@link #epsilon} parameter.
+   * 
+   * @param epsilon
+   *          {@link #epsilon}
+   */
+  public ReceptorProteinComparator(double epsilon) {
+    super(ReceptorProtein.class, true);
+    this.epsilon = epsilon;
+  }
+
+  /**
+   * Default constructor.
+   */
+  public ReceptorProteinComparator() {
+    this(Configuration.EPSILON);
+  }
+
+  @Override
+  protected Comparator<?> getParentComparator() {
+    return new ProteinComparator(epsilon);
+  }
+
+  @Override
+  protected int internalCompare(ReceptorProtein arg0, ReceptorProtein arg1) {
+    return 0;
+  }
 }
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/species/RnaComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/species/RnaComparator.java
index 25f8e4de9bbef561513dc0df1ae16418407b2efc..a16fbb967e9cdc64cb31a4f67b8bb8aecb0c0f54 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/species/RnaComparator.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/species/RnaComparator.java
@@ -1,14 +1,13 @@
 package lcsb.mapviewer.model.map.species;
 
-import java.util.Comparator;
 import java.util.HashSet;
 import java.util.Set;
 
 import org.apache.log4j.Logger;
 
+import lcsb.mapviewer.common.Comparator;
 import lcsb.mapviewer.common.Configuration;
 import lcsb.mapviewer.common.comparator.StringSetComparator;
-import lcsb.mapviewer.common.exception.NotImplementedException;
 import lcsb.mapviewer.model.map.species.field.RnaRegion;
 
 /**
@@ -17,95 +16,61 @@ import lcsb.mapviewer.model.map.species.field.RnaRegion;
  * @author Piotr Gawron
  *
  */
-public class RnaComparator implements Comparator<Rna> {
-
-	/**
-	 * Default class logger.
-	 */
-	@SuppressWarnings("unused")
-	private static Logger	logger = Logger.getLogger(RnaComparator.class);
-
-	/**
-	 * Epsilon value used for comparison of doubles.
-	 */
-	private double				epsilon;
-
-	/**
-	 * Constructor that requires {@link #epsilon} parameter.
-	 * 
-	 * @param epsilon
-	 *          {@link #epsilon}
-	 */
-	public RnaComparator(double epsilon) {
-		this.epsilon = epsilon;
-	}
-
-	/**
-	 * Default constructor.
-	 */
-	public RnaComparator() {
-		this(Configuration.EPSILON);
-	}
-
-	@Override
-	public int compare(Rna arg0, Rna arg1) {
-		if (arg0 == null) {
-			if (arg1 == null) {
-				return 0;
-			} else {
-				return 1;
-			}
-		} else if (arg1 == null) {
-			return -1;
-		}
-
-		if (arg0.getClass().equals(arg1.getClass())) {
-			if (arg0.getClass().equals(Rna.class)) {
-				return internalCompare(arg0, arg1);
-			} else {
-				throw new NotImplementedException("Don't know how to compare classes: " + arg0.getClass());
-			}
-		} else {
-			return -1;
-		}
-	}
-
-	/**
-	 * This method compares only the fields that are defined in {@link Rna} class
-	 * in inheritence tree. By the design it calls also comparator of the upper (
-	 * {@link Species}) class.
-	 * 
-	 * @param arg0
-	 *          first object to compare
-	 * @param arg1
-	 *          second object to compare
-	 * @return if all fields are qual then returns 0. If they are different then
-	 *         -1/1 is returned.
-	 */
-	private int internalCompare(Rna arg0, Rna arg1) {
-		SpeciesComparator speciesComparator = new SpeciesComparator(epsilon);
-		int result = speciesComparator.internalCompare(arg0, arg1);
-		if (result != 0) {
-			return result;
-		}
-
-		StringSetComparator stringSetComparator = new StringSetComparator();
-
-		Set<String> set1 = new HashSet<>();
-		Set<String> set2 = new HashSet<>();
-
-		for (RnaRegion region : arg0.getRegions()) {
-			set1.add(region.toString());
-		}
-
-		for (RnaRegion region : arg1.getRegions()) {
-			set2.add(region.toString());
-		}
-
-		if (stringSetComparator.compare(set1, set2) != 0) {
-			return stringSetComparator.compare(set1, set2);
-		}
-
-		return 0;
-	}
+public class RnaComparator extends Comparator<Rna> {
+
+  /**
+   * Default class logger.
+   */
+  @SuppressWarnings("unused")
+  private static Logger logger = Logger.getLogger(RnaComparator.class);
+
+  /**
+   * Epsilon value used for comparison of doubles.
+   */
+  private double epsilon;
+
+  /**
+   * Constructor that requires {@link #epsilon} parameter.
+   * 
+   * @param epsilon
+   *          {@link #epsilon}
+   */
+  public RnaComparator(double epsilon) {
+    super(Rna.class, true);
+    this.epsilon = epsilon;
+  }
+
+  /**
+   * Default constructor.
+   */
+  public RnaComparator() {
+    this(Configuration.EPSILON);
+  }
+
+  @Override
+  protected Comparator<?> getParentComparator() {
+    return new SpeciesComparator(epsilon);
+  }
+
+  @Override
+  protected int internalCompare(Rna arg0, Rna arg1) {
+    StringSetComparator stringSetComparator = new StringSetComparator();
+
+    Set<String> set1 = new HashSet<>();
+    Set<String> set2 = new HashSet<>();
+
+    for (RnaRegion region : arg0.getRegions()) {
+      set1.add(region.toString());
+    }
+
+    for (RnaRegion region : arg1.getRegions()) {
+      set2.add(region.toString());
+    }
+
+    if (stringSetComparator.compare(set1, set2) != 0) {
+      return stringSetComparator.compare(set1, set2);
+    }
+
+    return 0;
+  }
 }
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/species/SimpleMoleculeComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/species/SimpleMoleculeComparator.java
index 776941b69814e3149d406cabace5b98f4479041d..ef10a99608a1c8a8c893dd680031b9a4c4cab191 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/species/SimpleMoleculeComparator.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/species/SimpleMoleculeComparator.java
@@ -1,11 +1,9 @@
 package lcsb.mapviewer.model.map.species;
 
-import java.util.Comparator;
-
 import org.apache.log4j.Logger;
 
+import lcsb.mapviewer.common.Comparator;
 import lcsb.mapviewer.common.Configuration;
-import lcsb.mapviewer.common.exception.NotImplementedException;
 
 /**
  * Comparator class used for comparing {@link SimpleMolecule} objects.
@@ -13,78 +11,44 @@ import lcsb.mapviewer.common.exception.NotImplementedException;
  * @author Piotr Gawron
  *
  */
-public class SimpleMoleculeComparator implements Comparator<SimpleMolecule> {
-
-	/**
-	 * Default class logger.
-	 */
-	@SuppressWarnings("unused")
-	private static Logger	logger = Logger.getLogger(SimpleMoleculeComparator.class);
-
-	/**
-	 * Epsilon value used for comparison of doubles.
-	 */
-	private double				epsilon;
-
-	/**
-	 * Constructor that requires {@link #epsilon} parameter.
-	 * 
-	 * @param epsilon
-	 *          {@link #epsilon}
-	 */
-	public SimpleMoleculeComparator(double epsilon) {
-		this.epsilon = epsilon;
-	}
-
-	/**
-	 * Default constructor.
-	 */
-	public SimpleMoleculeComparator() {
-		this(Configuration.EPSILON);
-	}
-
-	@Override
-	public int compare(SimpleMolecule arg0, SimpleMolecule arg1) {
-		if (arg0 == null) {
-			if (arg1 == null) {
-				return 0;
-			} else {
-				return 1;
-			}
-		} else if (arg1 == null) {
-			return -1;
-		}
-
-		if (arg0.getClass().equals(arg1.getClass())) {
-			if (arg0.getClass().equals(SimpleMolecule.class)) {
-				return internalCompare(arg0, arg1);
-			} else {
-				throw new NotImplementedException("Don't know how to compare classes: " + arg0.getClass());
-			}
-		} else {
-			return -1;
-		}
-	}
-
-	/**
-	 * This method compares only the fields that are defined in
-	 * {@link SimpleMolecule} class in inheritence tree. By the design it calls
-	 * also comparator of the upper ({@link Species}) class.
-	 * 
-	 * @param arg0
-	 *          first object to compare
-	 * @param arg1
-	 *          second object to compare
-	 * @return if all fields are qual then returns 0. If they are different then
-	 *         -1/1 is returned.
-	 */
-	private int internalCompare(SimpleMolecule arg0, SimpleMolecule arg1) {
-		ChemicalComparator chemicalComparator = new ChemicalComparator(epsilon);
-		int result = chemicalComparator.internalCompare(arg0, arg1);
-		if (result != 0) {
-			return result;
-		}
-
-		return 0;
-	}
+public class SimpleMoleculeComparator extends Comparator<SimpleMolecule> {
+
+  /**
+   * Default class logger.
+   */
+  @SuppressWarnings("unused")
+  private static Logger logger = Logger.getLogger(SimpleMoleculeComparator.class);
+
+  /**
+   * Epsilon value used for comparison of doubles.
+   */
+  private double epsilon;
+
+  /**
+   * Constructor that requires {@link #epsilon} parameter.
+   * 
+   * @param epsilon
+   *          {@link #epsilon}
+   */
+  public SimpleMoleculeComparator(double epsilon) {
+    super(SimpleMolecule.class, true);
+    this.epsilon = epsilon;
+  }
+
+  /**
+   * Default constructor.
+   */
+  public SimpleMoleculeComparator() {
+    this(Configuration.EPSILON);
+  }
+
+  @Override
+  protected Comparator<?> getParentComparator() {
+    return new ChemicalComparator(epsilon);
+  }
+
+  @Override
+  protected int internalCompare(SimpleMolecule arg0, SimpleMolecule arg1) {
+    return 0;
+  }
 }
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 c790a81e46fcdd8804b20a707db94e389894eefd..c3e6141b3b7c8a617dabd4e661ea7d8cfa2b5b3e 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
@@ -1,15 +1,13 @@
 package lcsb.mapviewer.model.map.species;
 
-import java.util.Comparator;
-
 import org.apache.log4j.Logger;
 
+import lcsb.mapviewer.common.Comparator;
 import lcsb.mapviewer.common.Configuration;
 import lcsb.mapviewer.common.comparator.BooleanComparator;
 import lcsb.mapviewer.common.comparator.DoubleComparator;
 import lcsb.mapviewer.common.comparator.IntegerComparator;
 import lcsb.mapviewer.common.comparator.StringComparator;
-import lcsb.mapviewer.common.exception.NotImplementedException;
 
 /**
  * Comparator class used for comparing {@link Species} objects.
@@ -17,224 +15,126 @@ import lcsb.mapviewer.common.exception.NotImplementedException;
  * @author Piotr Gawron
  *
  */
-public class SpeciesComparator implements Comparator<Species> {
-
-	/**
-	 * Default class logger.
-	 */
-	private Logger								 logger	= Logger.getLogger(SpeciesComparator.class);
-
-	/**
-	 * Comparator for {@link AntisenseRna} implementation of {@link Species}.
-	 */
-	private AntisenseRnaComparator antisenseRnaComparator;
-
-	/**
-	 * Comparator for {@link Chemical} implementation of {@link Species}.
-	 */
-	private ChemicalComparator		 chemicalComparator;
-
-	/**
-	 * Comparator for {@link Complex} implementation of {@link Species}.
-	 */
-	private ComplexComparator			 complexComparator;
-
-	/**
-	 * Comparator for {@link Degraded} implementation of {@link Species}.
-	 */
-	private DegradedComparator		 degradedComparator;
-
-	/**
-	 * Comparator for {@link Drug} implementation of {@link Species}.
-	 */
-	private DrugComparator				 drugComparator;
-
-	/**
-	 * Comparator for {@link Gene} implementation of {@link Species}.
-	 */
-	private GeneComparator				 geneComparator;
-
-	/**
-	 * Comparator for {@link Phenotype} implementation of {@link Species}.
-	 */
-	private PhenotypeComparator		 phenotypeComparator;
-
-	/**
-	 * Comparator for {@link Protein} implementation of {@link Species}.
-	 */
-	private ProteinComparator			 proteinComparator;
-
-	/**
-	 * Comparator for {@link Rna} implementation of {@link Species}.
-	 */
-	private RnaComparator					 rnaComparator;
-
-	/**
-	 * Comparator for {@link Unknown} implementation of {@link Species}.
-	 */
-	private UnknownComparator			 unknownComparator;
-
-	/**
-	 * Epsilon value used for comparison of doubles.
-	 */
-	private double								 epsilon;
-
-	/**
-	 * Constructor that requires {@link #epsilon} parameter.
-	 * 
-	 * @param epsilon
-	 *          {@link #epsilon}
-	 */
-	public SpeciesComparator(double epsilon) {
-		this.epsilon = epsilon;
-		antisenseRnaComparator = new AntisenseRnaComparator(epsilon);
-		chemicalComparator = new ChemicalComparator(epsilon);
-		complexComparator = new ComplexComparator(epsilon);
-		degradedComparator = new DegradedComparator(epsilon);
-		drugComparator = new DrugComparator(epsilon);
-		geneComparator = new GeneComparator(epsilon);
-		phenotypeComparator = new PhenotypeComparator(epsilon);
-		proteinComparator = new ProteinComparator(epsilon);
-		rnaComparator = new RnaComparator(epsilon);
-		unknownComparator = new UnknownComparator(epsilon);
-	}
-
-	/**
-	 * Default constructor.
-	 */
-	public SpeciesComparator() {
-		this(Configuration.EPSILON);
-	}
-
-	@Override
-	public int compare(Species arg0, Species arg1) {
-		if (arg0 == null) {
-			if (arg1 == null) {
-				return 0;
-			} else {
-				return 1;
-			}
-		} else if (arg1 == null) {
-			return -1;
-		}
-
-		if (arg0.getClass().equals(arg1.getClass())) {
-			if (arg0.getClass().equals(AntisenseRna.class)) {
-				return antisenseRnaComparator.compare((AntisenseRna) arg0, (AntisenseRna) arg1);
-			} else if (arg0 instanceof Chemical) {
-				return chemicalComparator.compare((Chemical) arg0, (Chemical) arg1);
-			} else if (arg0.getClass().equals(Complex.class)) {
-				return complexComparator.compare((Complex) arg0, (Complex) arg1);
-			} else if (arg0.getClass().equals(Degraded.class)) {
-				return degradedComparator.compare((Degraded) arg0, (Degraded) arg1);
-			} else if (arg0.getClass().equals(Drug.class)) {
-				return drugComparator.compare((Drug) arg0, (Drug) arg1);
-			} else if (arg0.getClass().equals(Gene.class)) {
-				return geneComparator.compare((Gene) arg0, (Gene) arg1);
-			} else if (arg0.getClass().equals(Phenotype.class)) {
-				return phenotypeComparator.compare((Phenotype) arg0, (Phenotype) arg1);
-			} else if (arg0 instanceof Protein) {
-				return proteinComparator.compare((Protein) arg0, (Protein) arg1);
-			} else if (arg0.getClass().equals(Rna.class)) {
-				return rnaComparator.compare((Rna) arg0, (Rna) arg1);
-			} else if (arg0.getClass().equals(Unknown.class)) {
-				return unknownComparator.compare((Unknown) arg0, (Unknown) arg1);
-			} else {
-				throw new NotImplementedException("Don't know how to compare classes: " + arg0.getClass());
-			}
-		} else {
-			return -1;
-		}
-	}
-
-	/**
-	 * This method compares only the fields that are defined in {@link Species}
-	 * class in inheritence tree. By the design it calls also comparator of the
-	 * upper ({@link Element}) class.
-	 * 
-	 * @param arg0
-	 *          first object to compare
-	 * @param arg1
-	 *          second object to compare
-	 * @return if all fields are qual then returns 0. If they are different then
-	 *         -1/1 is returned.
-	 */
-	int internalCompare(Species arg0, Species arg1) {
-		ElementComparator elementComparator = new ElementComparator(epsilon);
-		int result = elementComparator.internalCompare(arg0, arg1);
-		if (result != 0) {
-			return result;
-		}
-
-		DoubleComparator doubleComparator = new DoubleComparator(epsilon);
-		BooleanComparator booleanComparator = new BooleanComparator();
-		IntegerComparator integerComparator = new IntegerComparator();
-
-		if (booleanComparator.compare(arg0.getActivity(), arg1.getActivity()) != 0) {
-			logger.debug("activity different: " + arg0.getActivity() + ", " + arg1.getActivity());
-			return booleanComparator.compare(arg0.getActivity(), arg1.getActivity());
-		}
-
-		if (doubleComparator.compare(arg0.getLineWidth(), arg1.getLineWidth()) != 0) {
-			logger.debug("line width different: " + arg0.getLineWidth() + ", " + arg1.getLineWidth());
-			return doubleComparator.compare(arg0.getLineWidth(), arg1.getLineWidth());
-		}
-		StringComparator stringComparator = new StringComparator();
-		if (stringComparator.compare(arg0.getStateLabel(), arg1.getStateLabel()) != 0) {
-			logger.debug("state label different: " + arg0.getStateLabel() + ", " + arg1.getStateLabel());
-			return stringComparator.compare(arg0.getStateLabel(), arg1.getStateLabel());
-		}
-
-		if (stringComparator.compare(arg0.getStatePrefix(), arg1.getStatePrefix()) != 0) {
-			logger.debug("state prefix different: " + arg0.getStatePrefix() + ", " + arg1.getStatePrefix());
-			return stringComparator.compare(arg0.getStatePrefix(), arg1.getStatePrefix());
-		}
-
-		if (integerComparator.compare(arg0.getInitialAmount(), arg1.getInitialAmount()) != 0) {
-			logger.debug("Initial amount different: " + arg0.getInitialAmount() + ", " + arg1.getInitialAmount());
-			return integerComparator.compare(arg0.getInitialAmount(), arg1.getInitialAmount());
-		}
-
-		if (integerComparator.compare(arg0.getCharge(), arg1.getCharge()) != 0) {
-			logger.debug("Charge different: " + arg0.getCharge() + ", " + arg1.getCharge());
-			return integerComparator.compare(arg0.getCharge(), arg1.getCharge());
-		}
-
-		if (integerComparator.compare(arg0.getHomodimer(), arg1.getHomodimer()) != 0) {
-			logger.debug("Homodimer different: " + arg0.getHomodimer() + ", " + arg1.getHomodimer());
-			return integerComparator.compare(arg0.getHomodimer(), arg1.getHomodimer());
-		}
-
-		if (integerComparator.compare(arg0.getInitialConcentration(), arg1.getInitialConcentration()) != 0) {
-			logger.debug("Initial concentration different: " + arg0.getInitialConcentration() + ", " + arg1.getInitialConcentration());
-			return integerComparator.compare(arg0.getInitialConcentration(), arg1.getInitialConcentration());
-		}
-
-		if (booleanComparator.compare(arg0.hasOnlySubstanceUnits(), arg1.hasOnlySubstanceUnits()) != 0) {
-			logger.debug("OnlySubstanceUnits different: " + arg0.hasOnlySubstanceUnits() + ", " + arg1.hasOnlySubstanceUnits());
-			return booleanComparator.compare(arg0.hasOnlySubstanceUnits(), arg1.hasOnlySubstanceUnits());
-		}
-
-		if (arg0.getPositionToCompartment() != null || arg1.getPositionToCompartment() != null) {
-			Integer pos0 = null;
-			Integer pos1 = null;
-			if (arg0.getPositionToCompartment() != null) {
-				pos0 = arg0.getPositionToCompartment().ordinal();
-			}
-			if (arg1.getPositionToCompartment() != null) {
-				pos1 = arg1.getPositionToCompartment().ordinal();
-			}
-			if (integerComparator.compare(pos0, pos1) != 0) {
-				logger.debug("PositionToCompartment different: \"" + arg0.getPositionToCompartment() + "\", \"" + arg1.getPositionToCompartment() + "\"");
-				return integerComparator.compare(pos0, pos1);
-			}
-		}
-
-		if (booleanComparator.compare(arg0.isHypothetical(), arg1.isHypothetical()) != 0) {
-			logger.debug("Hypothetical different: \"" + arg0.isHypothetical() + "\", \"" + arg1.isHypothetical() + "\"");
-			return booleanComparator.compare(arg0.isHypothetical(), arg1.isHypothetical());
-		}
-
-		return 0;
-	}
+public class SpeciesComparator extends Comparator<Species> {
+
+  /**
+   * Default class logger.
+   */
+  private Logger logger = Logger.getLogger(SpeciesComparator.class);
+
+  /**
+   * Epsilon value used for comparison of doubles.
+   */
+  private double epsilon;
+
+  /**
+   * Constructor that requires {@link #epsilon} parameter.
+   * 
+   * @param epsilon
+   *          {@link #epsilon}
+   */
+  public SpeciesComparator(double epsilon) {
+    super(Species.class, true);
+    this.epsilon = epsilon;
+    addSubClassComparator(new AntisenseRnaComparator(epsilon));
+    addSubClassComparator(new ChemicalComparator(epsilon));
+    addSubClassComparator(new ComplexComparator(epsilon));
+    addSubClassComparator(new DegradedComparator(epsilon));
+    addSubClassComparator(new DrugComparator(epsilon));
+    addSubClassComparator(new GeneComparator(epsilon));
+    addSubClassComparator(new PhenotypeComparator(epsilon));
+    addSubClassComparator(new ProteinComparator(epsilon));
+    addSubClassComparator(new RnaComparator(epsilon));
+    addSubClassComparator(new UnknownComparator(epsilon));
+  }
+
+  /**
+   * Default constructor.
+   */
+  public SpeciesComparator() {
+    this(Configuration.EPSILON);
+  }
+
+  @Override
+  protected int internalCompare(Species arg0, Species arg1) {
+    ElementComparator elementComparator = new ElementComparator(epsilon);
+    int result = elementComparator.internalCompare(arg0, arg1);
+    if (result != 0) {
+      return result;
+    }
+
+    DoubleComparator doubleComparator = new DoubleComparator(epsilon);
+    BooleanComparator booleanComparator = new BooleanComparator();
+    IntegerComparator integerComparator = new IntegerComparator();
+
+    if (booleanComparator.compare(arg0.getActivity(), arg1.getActivity()) != 0) {
+      logger.debug("activity different: " + arg0.getActivity() + ", " + arg1.getActivity());
+      return booleanComparator.compare(arg0.getActivity(), arg1.getActivity());
+    }
+
+    if (doubleComparator.compare(arg0.getLineWidth(), arg1.getLineWidth()) != 0) {
+      logger.debug("line width different: " + arg0.getLineWidth() + ", " + arg1.getLineWidth());
+      return doubleComparator.compare(arg0.getLineWidth(), arg1.getLineWidth());
+    }
+    StringComparator stringComparator = new StringComparator();
+    if (stringComparator.compare(arg0.getStateLabel(), arg1.getStateLabel()) != 0) {
+      logger.debug("state label different: " + arg0.getStateLabel() + ", " + arg1.getStateLabel());
+      return stringComparator.compare(arg0.getStateLabel(), arg1.getStateLabel());
+    }
+
+    if (stringComparator.compare(arg0.getStatePrefix(), arg1.getStatePrefix()) != 0) {
+      logger.debug("state prefix different: " + arg0.getStatePrefix() + ", " + arg1.getStatePrefix());
+      return stringComparator.compare(arg0.getStatePrefix(), arg1.getStatePrefix());
+    }
+
+    if (integerComparator.compare(arg0.getInitialAmount(), arg1.getInitialAmount()) != 0) {
+      logger.debug("Initial amount different: " + arg0.getInitialAmount() + ", " + arg1.getInitialAmount());
+      return integerComparator.compare(arg0.getInitialAmount(), arg1.getInitialAmount());
+    }
+
+    if (integerComparator.compare(arg0.getCharge(), arg1.getCharge()) != 0) {
+      logger.debug("Charge different: " + arg0.getCharge() + ", " + arg1.getCharge());
+      return integerComparator.compare(arg0.getCharge(), arg1.getCharge());
+    }
+
+    if (integerComparator.compare(arg0.getHomodimer(), arg1.getHomodimer()) != 0) {
+      logger.debug("Homodimer different: " + arg0.getHomodimer() + ", " + arg1.getHomodimer());
+      return integerComparator.compare(arg0.getHomodimer(), arg1.getHomodimer());
+    }
+
+    if (integerComparator.compare(arg0.getInitialConcentration(), arg1.getInitialConcentration()) != 0) {
+      logger.debug(
+          "Initial concentration different: " + arg0.getInitialConcentration() + ", " + arg1.getInitialConcentration());
+      return integerComparator.compare(arg0.getInitialConcentration(), arg1.getInitialConcentration());
+    }
+
+    if (booleanComparator.compare(arg0.hasOnlySubstanceUnits(), arg1.hasOnlySubstanceUnits()) != 0) {
+      logger
+          .debug("OnlySubstanceUnits different: " + arg0.hasOnlySubstanceUnits() + ", " + arg1.hasOnlySubstanceUnits());
+      return booleanComparator.compare(arg0.hasOnlySubstanceUnits(), arg1.hasOnlySubstanceUnits());
+    }
+
+    if (arg0.getPositionToCompartment() != null || arg1.getPositionToCompartment() != null) {
+      Integer pos0 = null;
+      Integer pos1 = null;
+      if (arg0.getPositionToCompartment() != null) {
+        pos0 = arg0.getPositionToCompartment().ordinal();
+      }
+      if (arg1.getPositionToCompartment() != null) {
+        pos1 = arg1.getPositionToCompartment().ordinal();
+      }
+      if (integerComparator.compare(pos0, pos1) != 0) {
+        logger.debug("PositionToCompartment different: \"" + arg0.getPositionToCompartment() + "\", \""
+            + arg1.getPositionToCompartment() + "\"");
+        return integerComparator.compare(pos0, pos1);
+      }
+    }
+
+    if (booleanComparator.compare(arg0.isHypothetical(), arg1.isHypothetical()) != 0) {
+      logger.debug("Hypothetical different: \"" + arg0.isHypothetical() + "\", \"" + arg1.isHypothetical() + "\"");
+      return booleanComparator.compare(arg0.isHypothetical(), arg1.isHypothetical());
+    }
+
+    return 0;
+  }
 }
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/species/TruncatedProteinComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/species/TruncatedProteinComparator.java
index 22483ca6f5a916c633f3b8076d971aa610881758..e05a1edf0e0efd006b2b273d473d77aeb392ec9a 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/species/TruncatedProteinComparator.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/species/TruncatedProteinComparator.java
@@ -1,11 +1,9 @@
 package lcsb.mapviewer.model.map.species;
 
-import java.util.Comparator;
-
 import org.apache.log4j.Logger;
 
+import lcsb.mapviewer.common.Comparator;
 import lcsb.mapviewer.common.Configuration;
-import lcsb.mapviewer.common.exception.NotImplementedException;
 
 /**
  * Comparator class used for comparing {@link TruncatedProtein} objects.
@@ -13,77 +11,44 @@ import lcsb.mapviewer.common.exception.NotImplementedException;
  * @author Piotr Gawron
  *
  */
-public class TruncatedProteinComparator implements Comparator<TruncatedProtein> {
-
-	/**
-	 * Default class logger.
-	 */
-	@SuppressWarnings("unused")
-	private static Logger	logger = Logger.getLogger(TruncatedProteinComparator.class);
-
-	/**
-	 * Epsilon value used for comparison of doubles.
-	 */
-	private double				epsilon;
-
-	/**
-	 * Constructor that requires {@link #epsilon} parameter.
-	 * 
-	 * @param epsilon
-	 *          {@link #epsilon}
-	 */
-	public TruncatedProteinComparator(double epsilon) {
-		this.epsilon = epsilon;
-	}
-
-	/**
-	 * Default constructor.
-	 */
-	public TruncatedProteinComparator() {
-		this(Configuration.EPSILON);
-	}
-
-	@Override
-	public int compare(TruncatedProtein arg0, TruncatedProtein arg1) {
-		if (arg0 == null) {
-			if (arg1 == null) {
-				return 0;
-			} else {
-				return 1;
-			}
-		} else if (arg1 == null) {
-			return -1;
-		}
-
-		if (arg0.getClass().equals(arg1.getClass())) {
-			if (arg0.getClass().equals(TruncatedProtein.class)) {
-				return internalCompare(arg0, arg1);
-			} else {
-				throw new NotImplementedException("Don't know how to compare classes: " + arg0.getClass());
-			}
-		} else {
-			return -1;
-		}
-	}
-
-	/**
-	 * This method compares only the fields that are defined in
-	 * {@link TruncatedProtein} class in inheritence tree. By the design it calls
-	 * also comparator of the upper ({@link Species}) class.
-	 * 
-	 * @param arg0
-	 *          first object to compare
-	 * @param arg1
-	 *          second object to compare
-	 * @return if all fields are qual then returns 0. If they are different then
-	 *         -1/1 is returned.
-	 */
-	private int internalCompare(TruncatedProtein arg0, TruncatedProtein arg1) {
-		SpeciesComparator speciesComparator = new SpeciesComparator(epsilon);
-		int result = speciesComparator.internalCompare(arg0, arg1);
-		if (result != 0) {
-			return result;
-		}
-		return 0;
-	}
+public class TruncatedProteinComparator extends Comparator<TruncatedProtein> {
+
+  /**
+   * Default class logger.
+   */
+  @SuppressWarnings("unused")
+  private static Logger logger = Logger.getLogger(TruncatedProteinComparator.class);
+
+  /**
+   * Epsilon value used for comparison of doubles.
+   */
+  private double epsilon;
+
+  /**
+   * Constructor that requires {@link #epsilon} parameter.
+   * 
+   * @param epsilon
+   *          {@link #epsilon}
+   */
+  public TruncatedProteinComparator(double epsilon) {
+    super(TruncatedProtein.class, true);
+    this.epsilon = epsilon;
+  }
+
+  /**
+   * Default constructor.
+   */
+  public TruncatedProteinComparator() {
+    this(Configuration.EPSILON);
+  }
+
+  @Override
+  protected Comparator<?> getParentComparator() {
+    return new ProteinComparator(epsilon);
+  }
+
+  @Override
+  protected int internalCompare(TruncatedProtein arg0, TruncatedProtein arg1) {
+    return 0;
+  }
 }
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/species/UnknownComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/species/UnknownComparator.java
index 96c0edce8513f350cf3a87dc5d4b3a4f57e44117..1c45054aea17468b8dbc9cbba15902311cc42c8b 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/species/UnknownComparator.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/species/UnknownComparator.java
@@ -1,11 +1,9 @@
 package lcsb.mapviewer.model.map.species;
 
-import java.util.Comparator;
-
 import org.apache.log4j.Logger;
 
+import lcsb.mapviewer.common.Comparator;
 import lcsb.mapviewer.common.Configuration;
-import lcsb.mapviewer.common.exception.NotImplementedException;
 
 /**
  * Comparator class used for comparing {@link Unknown} objects.
@@ -13,77 +11,44 @@ import lcsb.mapviewer.common.exception.NotImplementedException;
  * @author Piotr Gawron
  *
  */
-public class UnknownComparator implements Comparator<Unknown> {
-
-	/**
-	 * Default class logger.
-	 */
-	@SuppressWarnings("unused")
-	private static Logger	logger = Logger.getLogger(UnknownComparator.class);
-
-	/**
-	 * Epsilon value used for comparison of doubles.
-	 */
-	private double				epsilon;
-
-	/**
-	 * Constructor that requires {@link #epsilon} parameter.
-	 * 
-	 * @param epsilon
-	 *          {@link #epsilon}
-	 */
-	public UnknownComparator(double epsilon) {
-		this.epsilon = epsilon;
-	}
-
-	/**
-	 * Default constructor.
-	 */
-	public UnknownComparator() {
-		this(Configuration.EPSILON);
-	}
-
-	@Override
-	public int compare(Unknown arg0, Unknown arg1) {
-		if (arg0 == null) {
-			if (arg1 == null) {
-				return 0;
-			} else {
-				return 1;
-			}
-		} else if (arg1 == null) {
-			return -1;
-		}
-
-		if (arg0.getClass().equals(arg1.getClass())) {
-			if (arg0.getClass().equals(Unknown.class)) {
-				return internalCompare(arg0, arg1);
-			} else {
-				throw new NotImplementedException("Don't know how to compare classes: " + arg0.getClass());
-			}
-		} else {
-			return -1;
-		}
-	}
-
-	/**
-	 * This method compares only the fields that are defined in {@link Unknown}
-	 * class in inheritence tree. By the design it calls also comparator of the
-	 * upper ({@link Species}) class.
-	 * 
-	 * @param arg0
-	 *          first object to compare
-	 * @param arg1
-	 *          second object to compare
-	 * @return if all fields are qual then returns 0. If they are different then
-	 *         -1/1 is returned.
-	 */
-	private int internalCompare(Unknown arg0, Unknown arg1) {
-		SpeciesComparator speciesComparator = new SpeciesComparator(epsilon);
-		int result = speciesComparator.internalCompare(arg0, arg1);
-		if (result != 0) {
-			return result;
-		}
-		return 0;
-	}
+public class UnknownComparator extends Comparator<Unknown> {
+
+  /**
+   * Default class logger.
+   */
+  @SuppressWarnings("unused")
+  private static Logger logger = Logger.getLogger(UnknownComparator.class);
+
+  /**
+   * Epsilon value used for comparison of doubles.
+   */
+  private double epsilon;
+
+  /**
+   * Constructor that requires {@link #epsilon} parameter.
+   * 
+   * @param epsilon
+   *          {@link #epsilon}
+   */
+  public UnknownComparator(double epsilon) {
+    super(Unknown.class, true);
+    this.epsilon = epsilon;
+  }
+
+  /**
+   * Default constructor.
+   */
+  public UnknownComparator() {
+    this(Configuration.EPSILON);
+  }
+
+  @Override
+  protected Comparator<?> getParentComparator() {
+    return new SpeciesComparator(epsilon);
+  }
+
+  @Override
+  protected int internalCompare(Unknown arg0, Unknown arg1) {
+    return 0;
+  }
 }
diff --git a/model/src/test/java/lcsb/mapviewer/model/map/OverviewImageLinkComparatorTest.java b/model/src/test/java/lcsb/mapviewer/model/map/OverviewImageLinkComparatorTest.java
index 06a28a73d76151f01aa5bc8ac93c5c498a23a444..9e8cd8147268616b186edf5577bf353144ecd037 100644
--- a/model/src/test/java/lcsb/mapviewer/model/map/OverviewImageLinkComparatorTest.java
+++ b/model/src/test/java/lcsb/mapviewer/model/map/OverviewImageLinkComparatorTest.java
@@ -8,71 +8,90 @@ import org.junit.Test;
 
 public class OverviewImageLinkComparatorTest {
 
-	@Before
-	public void setUp() throws Exception {
-	}
-
-	@After
-	public void tearDown() throws Exception {
-	}
-
-	@Test
-	public void testEqual() throws Exception {
-		try {
-			OverviewImageLinkComparator oic = new OverviewImageLinkComparator();
-
-			OverviewImageLink oi = new OverviewImageLink();
-			OverviewImageLink oi2 = new OverviewImageLink();
-
-			assertEquals(0, oic.compare(oi, oi2));
-			assertEquals(0, oic.compare(null, null));
-
-			oi2.setLinkedOverviewImage(new OverviewImage());
-			oi.setLinkedOverviewImage(new OverviewImage());
-			assertEquals(0, oic.compare(oi, oi2));
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testDifferent() throws Exception {
-		try {
-			OverviewImageLinkComparator oic = new OverviewImageLinkComparator();
-
-			OverviewImageLink oi = new OverviewImageLink();
-			
-			OverviewImageLink oi2 = new OverviewImageLink();
-			oi2.setLinkedOverviewImage(new OverviewImage());
-
-			assertTrue(0 != oic.compare(oi, oi2));
-			assertTrue(0 != oic.compare(oi2, oi));
-
-			oi2 = new OverviewImageLink();
-			oi2.setLinkedOverviewImage(new OverviewImage());
-
-			assertTrue(0 != oic.compare(oi, oi2));
-			assertTrue(0 != oic.compare(oi2, oi));
-
-			oi2 = new OverviewImageLink();
-			oi2.setPolygon("AS");
-
-			assertTrue(0 != oic.compare(oi, oi2));
-			assertTrue(0 != oic.compare(oi, null));
-			assertTrue(0 != oic.compare(null, oi2));
-			assertTrue(0 != oic.compare(new OverviewImageLink(){
-
-				/**
-				 * 
-				 */
-				private static final long serialVersionUID = 1L;}, oi2));
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
+  @Before
+  public void setUp() throws Exception {
+  }
+
+  @After
+  public void tearDown() throws Exception {
+  }
+
+  @Test
+  public void testEqual() throws Exception {
+    try {
+      OverviewImageLinkComparator oic = new OverviewImageLinkComparator();
+
+      OverviewImageLink oi = new OverviewImageLink();
+      OverviewImageLink oi2 = new OverviewImageLink();
+
+      assertEquals(0, oic.compare(oi, oi2));
+      assertEquals(0, oic.compare(null, null));
+
+      oi2.setLinkedOverviewImage(new OverviewImage());
+      oi.setLinkedOverviewImage(new OverviewImage());
+      assertEquals(0, oic.compare(oi, oi2));
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testDifferent() throws Exception {
+    try {
+      OverviewImageLinkComparator oic = new OverviewImageLinkComparator();
+
+      OverviewImageLink oi = new OverviewImageLink();
+
+      OverviewImageLink oi2 = new OverviewImageLink();
+      oi2.setLinkedOverviewImage(new OverviewImage());
+
+      assertTrue(0 != oic.compare(oi, oi2));
+      assertTrue(0 != oic.compare(oi2, oi));
+
+      oi2 = new OverviewImageLink();
+      oi2.setLinkedOverviewImage(new OverviewImage());
+
+      assertTrue(0 != oic.compare(oi, oi2));
+      assertTrue(0 != oic.compare(oi2, oi));
+
+      oi2 = new OverviewImageLink();
+      oi2.setPolygon("AS");
+
+      assertTrue(0 != oic.compare(oi, oi2));
+      assertTrue(0 != oic.compare(oi, null));
+      assertTrue(0 != oic.compare(null, oi2));
+      assertTrue(0 != oic.compare(new OverviewImageLink() {
+
+        /**
+         * 
+         */
+        private static final long serialVersionUID = 1L;
+      }, oi2));
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testDifferentPolygon() throws Exception {
+    try {
+      OverviewImageLinkComparator comparator = new OverviewImageLinkComparator();
+
+      OverviewImageLink iml1 = new OverviewImageLink();
+      OverviewImageLink iml2 = new OverviewImageLink();
+      iml2.setPolygon("1,2");
+
+      assertTrue(0 != comparator.compare(iml1, iml2));
+      assertTrue(0 != comparator.compare(iml2, iml1));
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
 
 }
diff --git a/model/src/test/java/lcsb/mapviewer/model/map/OverviewLinkComparatorTest.java b/model/src/test/java/lcsb/mapviewer/model/map/OverviewLinkComparatorTest.java
index 8902796c1dffe30e1b636ad30a6525e35a2f6494..a328f37ae680ab6602c5ab0bdaed0f0bd2c88646 100644
--- a/model/src/test/java/lcsb/mapviewer/model/map/OverviewLinkComparatorTest.java
+++ b/model/src/test/java/lcsb/mapviewer/model/map/OverviewLinkComparatorTest.java
@@ -14,80 +14,80 @@ import lcsb.mapviewer.model.map.model.ModelFullIndexed;
 
 public class OverviewLinkComparatorTest {
 
-	@Before
-	public void setUp() throws Exception {
-	}
-
-	@After
-	public void tearDown() throws Exception {
-	}
-
-	@Test
-	public void testEqual() throws Exception {
-		try {
-			OverviewLinkComparator omlc = new OverviewLinkComparator();
-
-			OverviewModelLink oml = new OverviewModelLink();
-			OverviewModelLink oml2 = new OverviewModelLink();
-
-			assertEquals(0, omlc.compare(oml, oml2));
-			assertEquals(0, omlc.compare(null, null));
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testInvalid() throws Exception {
-		try {
-			class Tmp extends OverviewLink {
-				private static final long serialVersionUID = 1L;
-
-				@Override
-				public OverviewLink copy() {
-					return null;
-				}
-			}
-			;
-			OverviewLinkComparator omlc = new OverviewLinkComparator();
-
-			OverviewLink oml = new Tmp();
-			OverviewLink oml2 = new Tmp();
-
-			omlc.compare(oml, oml2);
-
-			fail("Exception expected");
-		} catch (NotImplementedException e) {
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testDifferent() throws Exception {
-		try {
-			OverviewLinkComparator omlc = new OverviewLinkComparator();
-
-			OverviewModelLink oml = new OverviewModelLink();
-			OverviewImageLink iml = new OverviewImageLink();
-
-			assertTrue(0 != omlc.compare(oml, iml));
-			assertTrue(0 != omlc.compare(oml, null));
-			assertTrue(0 != omlc.compare(null, iml));
-
-			oml = new OverviewModelLink();
-			OverviewModelLink oml2 = new OverviewModelLink();
-			oml2.setLinkedModel(new ModelFullIndexed(new ModelData()));
-
-			assertTrue(0 != omlc.compare(oml, oml2));
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
+  @Before
+  public void setUp() throws Exception {
+  }
+
+  @After
+  public void tearDown() throws Exception {
+  }
+
+  @Test
+  public void testEqual() throws Exception {
+    try {
+      OverviewLinkComparator omlc = new OverviewLinkComparator();
+
+      OverviewModelLink oml = new OverviewModelLink();
+      OverviewModelLink oml2 = new OverviewModelLink();
+
+      assertEquals(0, omlc.compare(oml, oml2));
+      assertEquals(0, omlc.compare(null, null));
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testInvalid() throws Exception {
+    try {
+      class Tmp extends OverviewLink {
+        private static final long serialVersionUID = 1L;
+
+        @Override
+        public OverviewLink copy() {
+          return null;
+        }
+      }
+      ;
+      OverviewLinkComparator omlc = new OverviewLinkComparator();
+
+      OverviewLink oml = new Tmp();
+      OverviewLink oml2 = new Tmp();
+
+      omlc.compare(oml, oml2);
+
+      fail("Exception expected");
+    } catch (NotImplementedException e) {
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testDifferent() throws Exception {
+    try {
+      OverviewLinkComparator omlc = new OverviewLinkComparator();
+
+      OverviewModelLink oml = new OverviewModelLink();
+      OverviewImageLink iml = new OverviewImageLink();
+
+      assertTrue(0 != omlc.compare(oml, iml));
+      assertTrue(0 != omlc.compare(oml, null));
+      assertTrue(0 != omlc.compare(null, iml));
+
+      oml = new OverviewModelLink();
+      OverviewModelLink oml2 = new OverviewModelLink();
+      oml2.setLinkedModel(new ModelFullIndexed(new ModelData()));
+
+      assertTrue(0 != omlc.compare(oml, oml2));
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
 
 }
diff --git a/model/src/test/java/lcsb/mapviewer/model/map/OverviewModelLinkComparatorTest.java b/model/src/test/java/lcsb/mapviewer/model/map/OverviewModelLinkComparatorTest.java
index 578e6a92ce78fe07f5288ce4425a41d6ecea7013..b060511d7077b9ce222e6c2f57f2693ce3325999 100644
--- a/model/src/test/java/lcsb/mapviewer/model/map/OverviewModelLinkComparatorTest.java
+++ b/model/src/test/java/lcsb/mapviewer/model/map/OverviewModelLinkComparatorTest.java
@@ -86,4 +86,22 @@ public class OverviewModelLinkComparatorTest {
 		}
 	}
 
+	  @Test
+	  public void testDifferentPolygon() throws Exception {
+	    try {
+	      OverviewModelLinkComparator comparator = new OverviewModelLinkComparator();
+
+	      OverviewModelLink iml1 = new OverviewModelLink();
+	      OverviewModelLink iml2 = new OverviewModelLink();
+	      iml2.setPolygon("1,2");
+
+	      assertTrue(0 != comparator.compare(iml1, iml2));
+	      assertTrue(0 != comparator.compare(iml2, iml1));
+
+	    } catch (Exception e) {
+	      e.printStackTrace();
+	      throw e;
+	    }
+	  }
+
 }
diff --git a/model/src/test/java/lcsb/mapviewer/model/map/compartment/CompartmentComparatorTest.java b/model/src/test/java/lcsb/mapviewer/model/map/compartment/CompartmentComparatorTest.java
index 3df3ef0c801f092b454fb9b6c0f2ccf5a1067403..535233b7c002d864b0cf48d37890651af07d4831 100644
--- a/model/src/test/java/lcsb/mapviewer/model/map/compartment/CompartmentComparatorTest.java
+++ b/model/src/test/java/lcsb/mapviewer/model/map/compartment/CompartmentComparatorTest.java
@@ -18,202 +18,205 @@ import lcsb.mapviewer.model.map.species.Species;
 
 public class CompartmentComparatorTest {
 
-	Logger								logger		 = Logger.getLogger(CompartmentComparatorTest.class);
-	
-	CompartmentComparator	comparator = new CompartmentComparator();
-
-	@Before
-	public void setUp() throws Exception {
-	}
-
-	@After
-	public void tearDown() throws Exception {
-	}
-
-	@Test
-	public void testEquals() {
-		try {
-			Compartment compartment1 = createCompartment();
-			Compartment compartment2 = createCompartment();
-
-			assertEquals(0, comparator.compare(compartment1, compartment2));
-
-			assertEquals(0, comparator.compare(null, null));
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testDifferent2() {
-		try {
-			Compartment compartment = createCompartment();
-
-			assertTrue(comparator.compare(compartment, new PathwayCompartment()) != 0);
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testInvalid() {
-		try {
-			Compartment compartment1 = createCompartment();
-			Compartment compartment2 = createCompartment();
-
-			GenericProtein protein = new GenericProtein("1");
-			compartment1.getElements().add(protein);
-			protein = new GenericProtein("1");
-			compartment1.getElements().add(protein);
-
-			compartment2.getElements().add(new GenericProtein("b"));
-			compartment2.getElements().add(new GenericProtein("a"));
-
-			comparator.compare(compartment1, compartment2);
-			fail("Exception expected");
-
-		} catch (InvalidArgumentException e) {
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testInvalid2() {
-		try {
-			Compartment compartment1 = createCompartment();
-			Compartment compartment2 = createCompartment();
+  Logger logger = Logger.getLogger(CompartmentComparatorTest.class);
+
+  CompartmentComparator comparator = new CompartmentComparator();
+
+  @Before
+  public void setUp() throws Exception {
+  }
+
+  @After
+  public void tearDown() throws Exception {
+  }
+
+  @Test
+  public void testEquals() {
+    try {
+      Compartment compartment1 = createCompartment();
+      Compartment compartment2 = createCompartment();
+
+      assertEquals(0, comparator.compare(compartment1, compartment2));
+
+      assertEquals(0, comparator.compare(null, null));
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testDifferent2() {
+    try {
+      Compartment compartment = createCompartment();
+
+      assertTrue(comparator.compare(compartment, new PathwayCompartment()) != 0);
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testInvalid() {
+    try {
+      Compartment compartment1 = createCompartment();
+      Compartment compartment2 = createCompartment();
+
+      GenericProtein protein = new GenericProtein("1");
+      compartment1.getElements().add(protein);
+      protein = new GenericProtein("1");
+      compartment1.getElements().add(protein);
+
+      compartment2.getElements().add(new GenericProtein("b"));
+      compartment2.getElements().add(new GenericProtein("a"));
+
+      comparator.compare(compartment1, compartment2);
+      fail("Exception expected");
+
+    } catch (InvalidArgumentException e) {
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
 
-			Species protein = new GenericProtein("1");
-			compartment1.getElements().add(protein);
-			protein = new GenericProtein("1");
-			compartment1.getElements().add(protein);
+  @Test
+  public void testInvalid2() {
+    try {
+      Compartment compartment1 = createCompartment();
+      Compartment compartment2 = createCompartment();
 
-			compartment2.getElements().add(new GenericProtein("A"));
-			compartment2.getElements().add(new GenericProtein("B"));
+      Species protein = new GenericProtein("1");
+      compartment1.getElements().add(protein);
+      protein = new GenericProtein("1");
+      compartment1.getElements().add(protein);
 
-			comparator.compare(compartment2, compartment1);
-			fail("Exception expected");
+      compartment2.getElements().add(new GenericProtein("A"));
+      compartment2.getElements().add(new GenericProtein("B"));
 
-		} catch (InvalidArgumentException e) {
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
+      comparator.compare(compartment2, compartment1);
+      fail("Exception expected");
 
-	private Compartment createCompartment() {
-		Compartment result = new Compartment();
+    } catch (InvalidArgumentException e) {
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
 
-		result.setElementId("asd");
-		result.setX(12.0);
-		result.setY(123.0);
-		result.setWidth(4);
-		result.setHeight(5);
-		result.setFontSize(9.0);
-		result.setColor(Color.BLUE);
-		result.setVisibilityLevel("14");
-		result.setThickness(998);
-		result.setOuterWidth(45);
-		result.setInnerWidth(65);
-		result.setNamePoint(new Point2D.Double(9, 2));
+  private Compartment createCompartment() {
+    Compartment result = new Compartment();
 
-		GenericProtein protein = new GenericProtein("S");
-		protein.setName("a");
-		result.addElement(protein);
+    result.setElementId("asd");
+    result.setX(12.0);
+    result.setY(123.0);
+    result.setWidth(4);
+    result.setHeight(5);
+    result.setFontSize(9.0);
+    result.setColor(Color.BLUE);
+    result.setVisibilityLevel("14");
+    result.setThickness(998);
+    result.setOuterWidth(45);
+    result.setInnerWidth(65);
+    result.setNamePoint(new Point2D.Double(9, 2));
 
-		return result;
-	}
+    GenericProtein protein = new GenericProtein("S");
+    protein.setName("a");
+    result.addElement(protein);
 
-	@Test
-	public void testDifferentElementList() {
-		Compartment compartment1 = createCompartment();
-		Compartment compartment2 = createCompartment();
+    return result;
+  }
 
-		compartment1.addElement(new GenericProtein("idd"));
-		
-		assertTrue(comparator.compare(compartment1, compartment2) != 0);
-		assertTrue(comparator.compare(compartment2, compartment1) != 0);
-	}
+  @Test
+  public void testDifferentElementList() {
+    Compartment compartment1 = createCompartment();
+    Compartment compartment2 = createCompartment();
 
-	@Test
-	public void testDifferent() {
-		try {
-			Compartment compartment1 = createCompartment();
-			Compartment compartment2 = createCompartment();
+    compartment1.addElement(new GenericProtein("idd"));
 
-			assertTrue(comparator.compare(compartment1, null) != 0);
-			assertTrue(comparator.compare(null, compartment1) != 0);
+    assertTrue(comparator.compare(compartment1, compartment2) != 0);
+    assertTrue(comparator.compare(compartment2, compartment1) != 0);
+  }
 
-			compartment1 = createCompartment();
-			compartment2 = createCompartment();
+  @Test
+  public void testDifferentElementId() {
+    Compartment compartment1 = createCompartment();
+    Compartment compartment2 = createCompartment();
 
-			compartment1.setElementId("tmp");
+    compartment1.setElementId("tmp");
 
-			assertTrue(comparator.compare(compartment1, compartment2) != 0);
-			assertTrue(comparator.compare(compartment2, compartment1) != 0);
+    assertTrue(comparator.compare(compartment1, compartment2) != 0);
+    assertTrue(comparator.compare(compartment2, compartment1) != 0);
+  }
 
-			compartment1 = createCompartment();
-			compartment2 = createCompartment();
+  @Test
+  public void testDifferent() {
+    try {
+      Compartment compartment1 = createCompartment();
+      Compartment compartment2 = createCompartment();
 
-			compartment1.setThickness(11111);
+      assertTrue(comparator.compare(compartment1, null) != 0);
+      assertTrue(comparator.compare(null, compartment1) != 0);
 
-			assertTrue(comparator.compare(compartment1, compartment2) != 0);
-			assertTrue(comparator.compare(compartment2, compartment1) != 0);
+      compartment1 = createCompartment();
+      compartment2 = createCompartment();
 
-			compartment1 = createCompartment();
-			compartment2 = createCompartment();
+      compartment1.setThickness(11111);
 
-			compartment1.setNamePoint(new Point2D.Double(9, 999));
+      assertTrue(comparator.compare(compartment1, compartment2) != 0);
+      assertTrue(comparator.compare(compartment2, compartment1) != 0);
 
-			assertTrue(comparator.compare(compartment1, compartment2) != 0);
-			assertTrue(comparator.compare(compartment2, compartment1) != 0);
+      compartment1 = createCompartment();
+      compartment2 = createCompartment();
 
-			compartment1 = createCompartment();
-			compartment2 = createCompartment();
+      compartment1.setNamePoint(new Point2D.Double(9, 999));
 
-			compartment1.getElements().iterator().next().setElementId("bnu");
+      assertTrue(comparator.compare(compartment1, compartment2) != 0);
+      assertTrue(comparator.compare(compartment2, compartment1) != 0);
 
-			assertTrue(comparator.compare(compartment1, compartment2) != 0);
-			assertTrue(comparator.compare(compartment2, compartment1) != 0);
+      compartment1 = createCompartment();
+      compartment2 = createCompartment();
 
-			compartment1 = createCompartment();
-			compartment2 = createCompartment();
+      compartment1.getElements().iterator().next().setElementId("bnu");
 
-			Species species = (Species) compartment1.getElements().iterator().next();
-			species.setName("new namne");
+      assertTrue(comparator.compare(compartment1, compartment2) != 0);
+      assertTrue(comparator.compare(compartment2, compartment1) != 0);
 
-			assertTrue(comparator.compare(compartment1, compartment2) != 0);
-			assertTrue(comparator.compare(compartment2, compartment1) != 0);
+      compartment1 = createCompartment();
+      compartment2 = createCompartment();
 
-			compartment1 = createCompartment();
-			compartment2 = createCompartment();
+      Species species = (Species) compartment1.getElements().iterator().next();
+      species.setName("new namne");
 
-			compartment1.setOuterWidth(2);
+      assertTrue(comparator.compare(compartment1, compartment2) != 0);
+      assertTrue(comparator.compare(compartment2, compartment1) != 0);
 
-			assertTrue(comparator.compare(compartment1, compartment2) != 0);
-			assertTrue(comparator.compare(compartment2, compartment1) != 0);
+      compartment1 = createCompartment();
+      compartment2 = createCompartment();
 
-			compartment1 = createCompartment();
-			compartment2 = createCompartment();
+      compartment1.setOuterWidth(2);
 
-			compartment1.setInnerWidth(2);
+      assertTrue(comparator.compare(compartment1, compartment2) != 0);
+      assertTrue(comparator.compare(compartment2, compartment1) != 0);
 
-			assertTrue(comparator.compare(compartment1, compartment2) != 0);
-			assertTrue(comparator.compare(compartment2, compartment1) != 0);
+      compartment1 = createCompartment();
+      compartment2 = createCompartment();
 
-			compartment1 = createCompartment();
-			compartment2 = createCompartment();
+      compartment1.setInnerWidth(2);
 
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
+      assertTrue(comparator.compare(compartment1, compartment2) != 0);
+      assertTrue(comparator.compare(compartment2, compartment1) != 0);
+
+      compartment1 = createCompartment();
+      compartment2 = createCompartment();
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
 
 }
diff --git a/model/src/test/java/lcsb/mapviewer/model/map/kinetics/AllKineticsTests.java b/model/src/test/java/lcsb/mapviewer/model/map/kinetics/AllKineticsTests.java
index d97dc565279aadcf3329ea4cc9361fc9c4d7d848..956076bdf28df445a890d95ddc35d956a77c8930 100644
--- a/model/src/test/java/lcsb/mapviewer/model/map/kinetics/AllKineticsTests.java
+++ b/model/src/test/java/lcsb/mapviewer/model/map/kinetics/AllKineticsTests.java
@@ -6,7 +6,7 @@ import org.junit.runners.Suite.SuiteClasses;
 
 @RunWith(Suite.class)
 @SuiteClasses({ SbmlFunctionTest.class, //
-    SbmlKinetics.class, //
+    SbmlKineticsTest.class, //
     SbmlParameterTest.class, //
     SbmlUnitTest.class, //
     SbmlUnitTypeFactorTest.class })
diff --git a/model/src/test/java/lcsb/mapviewer/model/map/reaction/AbstractNodeComparatorTest.java b/model/src/test/java/lcsb/mapviewer/model/map/reaction/AbstractNodeComparatorTest.java
index acd1b7899841235abc1d2fdda17551ca848ddcb6..d8e2ed5174f59b31b6a5a3b46a6fabbbc4ec78a5 100644
--- a/model/src/test/java/lcsb/mapviewer/model/map/reaction/AbstractNodeComparatorTest.java
+++ b/model/src/test/java/lcsb/mapviewer/model/map/reaction/AbstractNodeComparatorTest.java
@@ -2,14 +2,13 @@ package lcsb.mapviewer.model.map.reaction;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
 
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mockito;
 
-import lcsb.mapviewer.common.exception.InvalidClassException;
+import lcsb.mapviewer.common.exception.NotImplementedException;
 
 public class AbstractNodeComparatorTest {
 
@@ -23,20 +22,10 @@ public class AbstractNodeComparatorTest {
   public void tearDown() throws Exception {
   }
 
-  @Test
+  @Test(expected = NotImplementedException.class)
   public void testCompareException() {
-    try {
-
-      comparator.compare(Mockito.mock(AbstractNode.class, Mockito.CALLS_REAL_METHODS),
-          Mockito.mock(AbstractNode.class, Mockito.CALLS_REAL_METHODS));
-
-      fail("Exception should occur");
-    } catch (InvalidClassException e) {
-
-    } catch (Exception e) {
-      e.printStackTrace();
-      fail("Unkowne exception");
-    }
+    comparator.compare(Mockito.mock(AbstractNode.class, Mockito.CALLS_REAL_METHODS),
+        Mockito.mock(AbstractNode.class, Mockito.CALLS_REAL_METHODS));
   }
 
   @Test
@@ -46,7 +35,6 @@ public class AbstractNodeComparatorTest {
       assertEquals(0, comparator.compare(null, null));
     } catch (Exception e) {
       e.printStackTrace();
-      fail("Unkowne exception");
     }
   }
 
@@ -57,7 +45,7 @@ public class AbstractNodeComparatorTest {
       assertTrue(comparator.compare(null, new AndOperator()) != 0);
     } catch (Exception e) {
       e.printStackTrace();
-      fail("Unkowne exception");
+      throw e;
     }
   }
 
diff --git a/model/src/test/java/lcsb/mapviewer/model/map/reaction/NodeOperatorComparatorTest.java b/model/src/test/java/lcsb/mapviewer/model/map/reaction/NodeOperatorComparatorTest.java
index 080daf032159959393a5cc7fd42afee9c965f6c3..e7e4afecb4bd4d2ab97117163e30cf5de06167e7 100644
--- a/model/src/test/java/lcsb/mapviewer/model/map/reaction/NodeOperatorComparatorTest.java
+++ b/model/src/test/java/lcsb/mapviewer/model/map/reaction/NodeOperatorComparatorTest.java
@@ -16,138 +16,141 @@ import lcsb.mapviewer.model.map.species.Species;
 
 public class NodeOperatorComparatorTest {
 
-	NodeOperatorComparator comparator = new NodeOperatorComparator();
+  NodeOperatorComparator comparator = new NodeOperatorComparator();
 
-	@Before
-	public void setUp() throws Exception {
-	}
+  @Before
+  public void setUp() throws Exception {
+  }
 
-	@After
-	public void tearDown() throws Exception {
-	}
+  @After
+  public void tearDown() throws Exception {
+  }
 
-	@Test
-	public void testEquals() {
-		try {
-			assertEquals(0, comparator.compare(new AndOperator(), new AndOperator()));
+  @Test
+  public void testEquals() {
+    try {
+      assertEquals(0, comparator.compare(new AndOperator(), new AndOperator()));
 
-			NodeOperator operator1 = createNodeOperator();
-			NodeOperator operator2 = createNodeOperator();
+      NodeOperator operator1 = createNodeOperator();
+      NodeOperator operator2 = createNodeOperator();
 
-			assertEquals(0, comparator.compare(operator1, operator2));
+      assertEquals(0, comparator.compare(operator1, operator2));
 
-			assertEquals(0, comparator.compare(operator1, operator1));
+      assertEquals(0, comparator.compare(operator1, operator1));
 
-			assertEquals(0, comparator.compare(null, null));
+      assertEquals(0, comparator.compare(null, null));
 
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
 
-	@Test
-	public void testDifferent() {
-		try {
-			NodeOperator operator1 = createNodeOperator();
-			NodeOperator operator2 = createNodeOperator();
+  @Test
+  public void testDifferentElement() {
+    NodeOperator operator1 = createNodeOperator();
+    NodeOperator operator2 = createNodeOperator();
 
-			operator1.getLine().addPoint(new Point2D.Double(1, 1));
-			assertTrue(comparator.compare(operator1, operator2) != 0);
-			assertTrue(comparator.compare(operator2, operator1) != 0);
+    Reactant reactant = (Reactant) operator1.getInputs().get(0);
+    reactant.setElement(new GenericProtein("id666"));
+    assertTrue(comparator.compare(operator1, operator2) != 0);
+    assertTrue(comparator.compare(operator2, operator1) != 0);
+  }
 
-			operator1 = createNodeOperator();
-			operator2 = createNodeOperator();
+  @Test
+  public void testDifferent() {
+    try {
+      NodeOperator operator1 = createNodeOperator();
+      NodeOperator operator2 = createNodeOperator();
 
-			operator1.addInput(new Reactant());
-			assertTrue(comparator.compare(operator1, operator2) != 0);
-			assertTrue(comparator.compare(operator2, operator1) != 0);
+      operator1.getLine().addPoint(new Point2D.Double(1, 1));
+      assertTrue(comparator.compare(operator1, operator2) != 0);
+      assertTrue(comparator.compare(operator2, operator1) != 0);
 
-			operator1 = createNodeOperator();
-			operator2 = createNodeOperator();
+      operator1 = createNodeOperator();
+      operator2 = createNodeOperator();
 
-			operator1.addOutput(new Product());
-			assertTrue(comparator.compare(operator1, operator2) != 0);
-			assertTrue(comparator.compare(operator2, operator1) != 0);
+      operator1.addInput(new Reactant());
+      assertTrue(comparator.compare(operator1, operator2) != 0);
+      assertTrue(comparator.compare(operator2, operator1) != 0);
 
-			operator1 = createNodeOperator();
-			operator2 = createNodeOperator();
+      operator1 = createNodeOperator();
+      operator2 = createNodeOperator();
 
-			Reactant reactant = (Reactant) operator1.getInputs().get(0);
-			reactant.setElement(new GenericProtein("id666"));
-			assertTrue(comparator.compare(operator1, operator2) != 0);
-			assertTrue(comparator.compare(operator2, operator1) != 0);
+      operator1.addOutput(new Product());
+      assertTrue(comparator.compare(operator1, operator2) != 0);
+      assertTrue(comparator.compare(operator2, operator1) != 0);
 
-			operator1 = createNodeOperator();
-			operator2 = createNodeOperator();
+      operator1 = createNodeOperator();
+      operator2 = createNodeOperator();
 
-			Product product= (Product) operator1.getOutputs().get(0);
-			product.setElement(new GenericProtein("id666"));
-			assertTrue(comparator.compare(operator1, operator2) != 0);
-			assertTrue(comparator.compare(operator2, operator1) != 0);
+      Product product = (Product) operator1.getOutputs().get(0);
+      product.setElement(new GenericProtein("id666"));
+      assertTrue(comparator.compare(operator1, operator2) != 0);
+      assertTrue(comparator.compare(operator2, operator1) != 0);
 
-			operator1 = createNodeOperator();
-			operator2 = createNodeOperator();
+      operator1 = createNodeOperator();
+      operator2 = createNodeOperator();
 
-			reactant = (Reactant) operator1.getInputs().get(0);
-			reactant.getElement().setName("bla");
-			assertTrue(comparator.compare(operator1, operator2) != 0);
-			assertTrue(comparator.compare(operator2, operator1) != 0);
+      Reactant reactant = (Reactant) operator1.getInputs().get(0);
+      reactant.getElement().setName("bla");
+      assertTrue(comparator.compare(operator1, operator2) != 0);
+      assertTrue(comparator.compare(operator2, operator1) != 0);
 
-			assertTrue(comparator.compare(null, operator1) != 0);
-			assertTrue(comparator.compare(operator2, null) != 0);
+      assertTrue(comparator.compare(null, operator1) != 0);
+      assertTrue(comparator.compare(operator2, null) != 0);
 
-			assertTrue(comparator.compare(operator2, new OrOperator()) != 0);
+      assertTrue(comparator.compare(operator2, new OrOperator()) != 0);
 
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
 
-	private NodeOperator createNodeOperator() {
-		AndOperator result = new AndOperator();
+  private NodeOperator createNodeOperator() {
+    AndOperator result = new AndOperator();
 
-		Species protein0 = new GenericProtein("id0");
-		protein0.setName("protein a");
-		protein0.setX(12.0);
-		protein0.setY(1.0);
-		protein0.setWidth(2.0);
-		protein0.setHeight(3.0);
+    Species protein0 = new GenericProtein("id0");
+    protein0.setName("protein a");
+    protein0.setX(12.0);
+    protein0.setY(1.0);
+    protein0.setWidth(2.0);
+    protein0.setHeight(3.0);
 
-		Product product = new Product(protein0);
+    Product product = new Product(protein0);
 
-		result.addOutput(product);
+    result.addOutput(product);
 
-		Species protein1 = new GenericProtein("id1");
-		protein1.setName("protein b");
-		protein1.setX(120.0);
-		protein1.setY(10.0);
-		protein1.setWidth(20.0);
-		protein1.setHeight(30.0);
+    Species protein1 = new GenericProtein("id1");
+    protein1.setName("protein b");
+    protein1.setX(120.0);
+    protein1.setY(10.0);
+    protein1.setWidth(20.0);
+    protein1.setHeight(30.0);
 
-		Reactant reactant = new Reactant(protein1);
+    Reactant reactant = new Reactant(protein1);
 
-		result.addInput(reactant);
+    result.addInput(reactant);
 
-		Species protein2 = new Gene("id2");
-		protein2.setName("gene b");
-		protein2.setX(320.0);
-		protein2.setY(30.0);
-		protein2.setWidth(30.0);
-		protein2.setHeight(40.0);
+    Species protein2 = new Gene("id2");
+    protein2.setName("gene b");
+    protein2.setX(320.0);
+    protein2.setY(30.0);
+    protein2.setWidth(30.0);
+    protein2.setHeight(40.0);
 
-		Modifier modifier = new Modifier(protein2);
+    Modifier modifier = new Modifier(protein2);
 
-		result.addInput(modifier);
+    result.addInput(modifier);
 
-		PolylineData pd = new PolylineData();
-		pd.addPoint(new Point2D.Double(1, 2));
-		pd.addPoint(new Point2D.Double(1, 22));
-		pd.addPoint(new Point2D.Double(10, 22));
-		result.setLine(pd);
+    PolylineData pd = new PolylineData();
+    pd.addPoint(new Point2D.Double(1, 2));
+    pd.addPoint(new Point2D.Double(1, 22));
+    pd.addPoint(new Point2D.Double(10, 22));
+    result.setLine(pd);
 
-		return result;
-	}
+    return result;
+  }
 
 }
diff --git a/model/src/test/java/lcsb/mapviewer/model/map/reaction/ReactionComparatorTest.java b/model/src/test/java/lcsb/mapviewer/model/map/reaction/ReactionComparatorTest.java
index 5f1f3ee27934a0111f3a32147e665a079c21e756..06403a2233525dbf816523c3dba0efb16371ce35 100644
--- a/model/src/test/java/lcsb/mapviewer/model/map/reaction/ReactionComparatorTest.java
+++ b/model/src/test/java/lcsb/mapviewer/model/map/reaction/ReactionComparatorTest.java
@@ -13,6 +13,7 @@ import lcsb.mapviewer.model.graphics.PolylineData;
 import lcsb.mapviewer.model.map.MiriamData;
 import lcsb.mapviewer.model.map.MiriamRelationType;
 import lcsb.mapviewer.model.map.MiriamType;
+import lcsb.mapviewer.model.map.kinetics.SbmlKinetics;
 import lcsb.mapviewer.model.map.modifier.Catalysis;
 import lcsb.mapviewer.model.map.reaction.type.StateTransitionReaction;
 import lcsb.mapviewer.model.map.reaction.type.TransportReaction;
@@ -23,266 +24,275 @@ import lcsb.mapviewer.model.map.species.Unknown;
 
 public class ReactionComparatorTest {
 
-	ReactionComparator comparator = new ReactionComparator();
+  ReactionComparator comparator = new ReactionComparator();
 
-	@Before
-	public void setUp() throws Exception {
-	}
+  @Before
+  public void setUp() throws Exception {
+  }
 
-	@After
-	public void tearDown() throws Exception {
-	}
+  @After
+  public void tearDown() throws Exception {
+  }
 
-	@Test
-	public void testEquals() {
-		try {
-			Reaction reaction1 = createReaction();
-			Reaction reaction2 = createReaction();
-			assertEquals(0, comparator.compare(reaction1, reaction2));
-			assertEquals(0, comparator.compare(reaction2, reaction1));
-			assertEquals(0, comparator.compare(reaction1, reaction1));
-			assertEquals(0, comparator.compare(null, null));
+  @Test
+  public void testEquals() {
+    try {
+      Reaction reaction1 = createReaction();
+      Reaction reaction2 = createReaction();
+      assertEquals(0, comparator.compare(reaction1, reaction2));
+      assertEquals(0, comparator.compare(reaction2, reaction1));
+      assertEquals(0, comparator.compare(reaction1, reaction1));
+      assertEquals(0, comparator.compare(null, null));
 
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
 
-	@Test
-	public void testDifferent3() {
-		try {
-			Reaction reaction1 = createReaction();
-			Reaction reaction2 = createReaction();
-
-			reaction1.setNotes("a");
-			assertTrue(comparator.compare(reaction1, reaction2) != 0);
-			assertTrue(comparator.compare(reaction2, reaction1) != 0);
-
-			reaction1 = createReaction();
-			reaction2 = createReaction();
-
-			reaction1.setIdReaction("a");
-			assertTrue(comparator.compare(reaction1, reaction2) != 0);
-			assertTrue(comparator.compare(reaction2, reaction1) != 0);
-
-			reaction1 = createReaction();
-			reaction2 = createReaction();
-
-			reaction1.setSymbol("a");
-			assertTrue(comparator.compare(reaction1, reaction2) != 0);
-			assertTrue(comparator.compare(reaction2, reaction1) != 0);
+  @Test
+  public void testDifferent3() {
+    try {
+      Reaction reaction1 = createReaction();
+      Reaction reaction2 = createReaction();
+
+      reaction1.setNotes("a");
+      assertTrue(comparator.compare(reaction1, reaction2) != 0);
+      assertTrue(comparator.compare(reaction2, reaction1) != 0);
+
+      reaction1 = createReaction();
+      reaction2 = createReaction();
+
+      reaction1.setIdReaction("a");
+      assertTrue(comparator.compare(reaction1, reaction2) != 0);
+      assertTrue(comparator.compare(reaction2, reaction1) != 0);
+
+      reaction1 = createReaction();
+      reaction2 = createReaction();
+
+      reaction1.setSymbol("a");
+      assertTrue(comparator.compare(reaction1, reaction2) != 0);
+      assertTrue(comparator.compare(reaction2, reaction1) != 0);
 
-			reaction1 = createReaction();
-			reaction2 = createReaction();
-
-			reaction1.setFormula("a");
-			assertTrue(comparator.compare(reaction1, reaction2) != 0);
-			assertTrue(comparator.compare(reaction2, reaction1) != 0);
+      reaction1 = createReaction();
+      reaction2 = createReaction();
+
+      reaction1.setFormula("a");
+      assertTrue(comparator.compare(reaction1, reaction2) != 0);
+      assertTrue(comparator.compare(reaction2, reaction1) != 0);
 
-			reaction1 = createReaction();
-			reaction2 = createReaction();
-
-			reaction1.setSubsystem("a");
-			assertTrue(comparator.compare(reaction1, reaction2) != 0);
-			assertTrue(comparator.compare(reaction2, reaction1) != 0);
+      reaction1 = createReaction();
+      reaction2 = createReaction();
+
+      reaction1.setSubsystem("a");
+      assertTrue(comparator.compare(reaction1, reaction2) != 0);
+      assertTrue(comparator.compare(reaction2, reaction1) != 0);
 
-			reaction1 = createReaction();
-			reaction2 = createReaction();
-
-			reaction1.setGeneProteinReaction("a");
-			assertTrue(comparator.compare(reaction1, reaction2) != 0);
-			assertTrue(comparator.compare(reaction2, reaction1) != 0);
+      reaction1 = createReaction();
+      reaction2 = createReaction();
+
+      reaction1.setGeneProteinReaction("a");
+      assertTrue(comparator.compare(reaction1, reaction2) != 0);
+      assertTrue(comparator.compare(reaction2, reaction1) != 0);
 
-			reaction1 = createReaction();
-			reaction2 = createReaction();
+      reaction1 = createReaction();
+      reaction2 = createReaction();
 
-			reaction1.setMechanicalConfidenceScore(1);
-			assertTrue(comparator.compare(reaction1, reaction2) != 0);
-			assertTrue(comparator.compare(reaction2, reaction1) != 0);
+      reaction1.setMechanicalConfidenceScore(1);
+      assertTrue(comparator.compare(reaction1, reaction2) != 0);
+      assertTrue(comparator.compare(reaction2, reaction1) != 0);
 
-			reaction1 = createReaction();
-			reaction2 = createReaction();
+      reaction1 = createReaction();
+      reaction2 = createReaction();
 
-			reaction1.setLowerBound(1.2);
-			assertTrue(comparator.compare(reaction1, reaction2) != 0);
-			assertTrue(comparator.compare(reaction2, reaction1) != 0);
+      reaction1.setLowerBound(1.2);
+      assertTrue(comparator.compare(reaction1, reaction2) != 0);
+      assertTrue(comparator.compare(reaction2, reaction1) != 0);
 
-			reaction1 = createReaction();
-			reaction2 = createReaction();
+      reaction1 = createReaction();
+      reaction2 = createReaction();
 
-			reaction1.setUpperBound(4.3);
-			assertTrue(comparator.compare(reaction1, reaction2) != 0);
-			assertTrue(comparator.compare(reaction2, reaction1) != 0);
+      reaction1.setUpperBound(4.3);
+      assertTrue(comparator.compare(reaction1, reaction2) != 0);
+      assertTrue(comparator.compare(reaction2, reaction1) != 0);
 
-			reaction1 = createReaction();
-			reaction2 = createReaction();
+      reaction1 = createReaction();
+      reaction2 = createReaction();
 
-			reaction1.addSynonym("syn");
-			assertTrue(comparator.compare(reaction1, reaction2) != 0);
-			assertTrue(comparator.compare(reaction2, reaction1) != 0);
+      reaction1.addSynonym("syn");
+      assertTrue(comparator.compare(reaction1, reaction2) != 0);
+      assertTrue(comparator.compare(reaction2, reaction1) != 0);
 
-			reaction1 = createReaction();
-			reaction2 = createReaction();
+      reaction1 = createReaction();
+      reaction2 = createReaction();
 
-			reaction1.addNode(new AndOperator());
-			assertTrue(comparator.compare(reaction1, reaction2) != 0);
-			assertTrue(comparator.compare(reaction2, reaction1) != 0);
+      reaction1.addNode(new AndOperator());
+      assertTrue(comparator.compare(reaction1, reaction2) != 0);
+      assertTrue(comparator.compare(reaction2, reaction1) != 0);
 
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
 
-	@Test
-	public void testDifferent4() {
-		try {
-			Reaction reaction1 = createReaction();
-			Reaction reaction2 = createReaction();
+  @Test
+  public void testDifferent4() {
+    try {
+      Reaction reaction1 = createReaction();
+      Reaction reaction2 = createReaction();
 
-			reaction1.addNode(new AndOperator());
-			assertTrue(comparator.compare(reaction1, reaction2) != 0);
-			assertTrue(comparator.compare(reaction2, reaction1) != 0);
+      reaction1.addNode(new AndOperator());
+      assertTrue(comparator.compare(reaction1, reaction2) != 0);
+      assertTrue(comparator.compare(reaction2, reaction1) != 0);
 
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
 
-	@Test
-	public void testDifferent2() {
-		try {
-			Reaction reaction1 = createReaction();
-			assertTrue(comparator.compare(reaction1, null) != 0);
-			assertTrue(comparator.compare(null, reaction1) != 0);
+  @Test
+  public void testDifferent2() {
+    try {
+      Reaction reaction1 = createReaction();
+      assertTrue(comparator.compare(reaction1, null) != 0);
+      assertTrue(comparator.compare(null, reaction1) != 0);
 
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
 
-	@Test
-	public void testDifferent() {
-		try {
+  @Test
+  public void testDifferent() {
+    try {
 
-			assertTrue(comparator.compare(new TransportReaction(), new StateTransitionReaction()) != 0);
+      assertTrue(comparator.compare(new TransportReaction(), new StateTransitionReaction()) != 0);
 
-			Reaction reaction1 = createReaction();
-			Reaction reaction2 = createReaction();
+      Reaction reaction1 = createReaction();
+      Reaction reaction2 = createReaction();
 
-			reaction1.setReversible(true);
-			assertTrue(comparator.compare(reaction1, reaction2) != 0);
-			assertTrue(comparator.compare(reaction2, reaction1) != 0);
-
-			reaction1 = createReaction();
-			reaction2 = createReaction();
-
-			reaction1.addModifier(new Modifier());
-			assertTrue(comparator.compare(reaction1, reaction2) != 0);
-			assertTrue(comparator.compare(reaction2, reaction1) != 0);
-
-			reaction1 = createReaction();
-			reaction2 = createReaction();
-
-			reaction1.getModifiers().get(0).getElement().setElementId("dfshkj");
-			assertTrue(comparator.compare(reaction1, reaction2) != 0);
-			assertTrue(comparator.compare(reaction2, reaction1) != 0);
-
-			reaction1 = createReaction();
-			reaction2 = createReaction();
-
-			reaction1.addReactant(new Reactant());
-			assertTrue(comparator.compare(reaction1, reaction2) != 0);
-			assertTrue(comparator.compare(reaction2, reaction1) != 0);
-
-			reaction1 = createReaction();
-			reaction2 = createReaction();
-
-			reaction1.getReactants().get(0).getElement().setElementId("dfshkj");
-			assertTrue(comparator.compare(reaction1, reaction2) != 0);
-			assertTrue(comparator.compare(reaction2, reaction1) != 0);
-
-			reaction1 = createReaction();
-			reaction2 = createReaction();
-
-			reaction1.addProduct(new Product());
-			assertTrue(comparator.compare(reaction1, reaction2) != 0);
-			assertTrue(comparator.compare(reaction2, reaction1) != 0);
-
-			reaction1 = createReaction();
-			reaction2 = createReaction();
-
-			reaction1.getProducts().get(0).getElement().setElementId("dfshkj");
-			assertTrue(comparator.compare(reaction1, reaction2) != 0);
-			assertTrue(comparator.compare(reaction2, reaction1) != 0);
-
-			reaction1 = createReaction();
-			reaction2 = createReaction();
-
-			reaction1.getOperators().get(0).getLine().addPoint(new Point2D.Double(2, 2));
-			assertTrue(comparator.compare(reaction1, reaction2) != 0);
-			assertTrue(comparator.compare(reaction2, reaction1) != 0);
-
-			reaction1 = createReaction();
-			reaction2 = createReaction();
-
-			reaction1.getMiriamData().add(new MiriamData(MiriamRelationType.BQ_BIOL_ENCODES, MiriamType.UNKNOWN, "c"));
-			assertTrue(comparator.compare(reaction1, reaction2) != 0);
-			assertTrue(comparator.compare(reaction2, reaction1) != 0);
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	private Reaction createReaction() {
-		Reaction reaction = new Reaction();
-		Species protein = new GenericProtein("id1");
-		protein.setName("ASD");
-		Reactant reactant = new Reactant(protein);
-
-		Species protein2 = new GenericProtein("id2");
-		protein2.setName("ASD2");
-		Reactant reactant2 = new Reactant(protein2);
-
-		Species simpleMolecule = new SimpleMolecule("id3");
-		simpleMolecule.setName("mol");
-		Product product = new Product(simpleMolecule);
-
-		Species unknown = new Unknown("id4");
-		unknown.setName("unk");
-		Modifier modifier = new Catalysis(unknown);
-
-		AndOperator operator = new AndOperator();
-		operator.setLine(new PolylineData(new Point2D.Double(2, 2), new Point2D.Double(4, 4)));
-		operator.addInput(reactant);
-		operator.addInput(reactant2);
-
-		reaction.addModifier(modifier);
-		reaction.addReactant(reactant);
-		reaction.addReactant(reactant2);
-		reaction.addProduct(product);
-		reaction.addNode(operator);
-		return reaction;
-	}
-
-	@Test
-	public void testDifferentNewFields() throws Exception {
-		try {
-			Reaction reaction1 = createReaction();
-			Reaction reaction2 = createReaction();
-			reaction2.setAbbreviation("ABRR");
-
-			assertTrue(comparator.compare(reaction1, reaction2) != 0);
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
+      reaction1.setReversible(true);
+      assertTrue(comparator.compare(reaction1, reaction2) != 0);
+      assertTrue(comparator.compare(reaction2, reaction1) != 0);
+
+      reaction1 = createReaction();
+      reaction2 = createReaction();
 
+      reaction1.addModifier(new Modifier());
+      assertTrue(comparator.compare(reaction1, reaction2) != 0);
+      assertTrue(comparator.compare(reaction2, reaction1) != 0);
+
+      reaction1 = createReaction();
+      reaction2 = createReaction();
+
+      reaction1.getModifiers().get(0).getElement().setElementId("dfshkj");
+      assertTrue(comparator.compare(reaction1, reaction2) != 0);
+      assertTrue(comparator.compare(reaction2, reaction1) != 0);
+
+      reaction1 = createReaction();
+      reaction2 = createReaction();
+
+      reaction1.addReactant(new Reactant());
+      assertTrue(comparator.compare(reaction1, reaction2) != 0);
+      assertTrue(comparator.compare(reaction2, reaction1) != 0);
+
+      reaction1 = createReaction();
+      reaction2 = createReaction();
+
+      reaction1.getReactants().get(0).getElement().setElementId("dfshkj");
+      assertTrue(comparator.compare(reaction1, reaction2) != 0);
+      assertTrue(comparator.compare(reaction2, reaction1) != 0);
+
+      reaction1 = createReaction();
+      reaction2 = createReaction();
+
+      reaction1.addProduct(new Product());
+      assertTrue(comparator.compare(reaction1, reaction2) != 0);
+      assertTrue(comparator.compare(reaction2, reaction1) != 0);
+
+      reaction1 = createReaction();
+      reaction2 = createReaction();
+
+      reaction1.getProducts().get(0).getElement().setElementId("dfshkj");
+      assertTrue(comparator.compare(reaction1, reaction2) != 0);
+      assertTrue(comparator.compare(reaction2, reaction1) != 0);
+
+      reaction1 = createReaction();
+      reaction2 = createReaction();
+
+      reaction1.getOperators().get(0).getLine().addPoint(new Point2D.Double(2, 2));
+      assertTrue(comparator.compare(reaction1, reaction2) != 0);
+      assertTrue(comparator.compare(reaction2, reaction1) != 0);
+
+      reaction1 = createReaction();
+      reaction2 = createReaction();
+
+      reaction1.getMiriamData().add(new MiriamData(MiriamRelationType.BQ_BIOL_ENCODES, MiriamType.UNKNOWN, "c"));
+      assertTrue(comparator.compare(reaction1, reaction2) != 0);
+      assertTrue(comparator.compare(reaction2, reaction1) != 0);
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  private Reaction createReaction() {
+    Reaction reaction = new Reaction();
+    Species protein = new GenericProtein("id1");
+    protein.setName("ASD");
+    Reactant reactant = new Reactant(protein);
+
+    Species protein2 = new GenericProtein("id2");
+    protein2.setName("ASD2");
+    Reactant reactant2 = new Reactant(protein2);
+
+    Species simpleMolecule = new SimpleMolecule("id3");
+    simpleMolecule.setName("mol");
+    Product product = new Product(simpleMolecule);
+
+    Species unknown = new Unknown("id4");
+    unknown.setName("unk");
+    Modifier modifier = new Catalysis(unknown);
+
+    AndOperator operator = new AndOperator();
+    operator.setLine(new PolylineData(new Point2D.Double(2, 2), new Point2D.Double(4, 4)));
+    operator.addInput(reactant);
+    operator.addInput(reactant2);
+
+    reaction.addModifier(modifier);
+    reaction.addReactant(reactant);
+    reaction.addReactant(reactant2);
+    reaction.addProduct(product);
+    reaction.addNode(operator);
+    return reaction;
+  }
+
+  @Test
+  public void testDifferentNewFields() throws Exception {
+    try {
+      Reaction reaction1 = createReaction();
+      Reaction reaction2 = createReaction();
+      reaction2.setAbbreviation("ABRR");
+
+      assertTrue(comparator.compare(reaction1, reaction2) != 0);
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testDifferentKinetics() {
+    Reaction reaction1 = createReaction();
+    Reaction reaction2 = createReaction();
+
+    reaction1.setKinetics(new SbmlKinetics());
+    assertTrue(comparator.compare(reaction1, reaction2) != 0);
+    assertTrue(comparator.compare(reaction2, reaction1) != 0);
+  }
 }
diff --git a/model/src/test/java/lcsb/mapviewer/model/map/species/AntisenseRnaComparatorTest.java b/model/src/test/java/lcsb/mapviewer/model/map/species/AntisenseRnaComparatorTest.java
index 09242c650680a3c287d436785cbf077a5ae504bc..690e5c3e23d2e03934ca30e16ceeedd2feede7bd 100644
--- a/model/src/test/java/lcsb/mapviewer/model/map/species/AntisenseRnaComparatorTest.java
+++ b/model/src/test/java/lcsb/mapviewer/model/map/species/AntisenseRnaComparatorTest.java
@@ -15,90 +15,81 @@ import lcsb.mapviewer.model.map.species.field.AntisenseRnaRegionType;
 
 public class AntisenseRnaComparatorTest {
 
-	AntisenseRnaComparator comparator = new AntisenseRnaComparator();
-
-	@Before
-	public void setUp() throws Exception {
-	}
-
-	@After
-	public void tearDown() throws Exception {
-	}
-
-	@Test
-	public void testEquals() {
-		try {
-			AntisenseRna aRna1 = createAntisenseRna();
-			AntisenseRna aRna2 = createAntisenseRna();
-
-			assertEquals(0, comparator.compare(aRna1, aRna1));
-
-			assertEquals(0, comparator.compare(aRna1, aRna2));
-			assertEquals(0, comparator.compare(aRna2, aRna1));
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			fail("Unknowne exception occurred");
-		}
-	}
-
-	@Test
-	public void testDifferent() {
-		try {
-			AntisenseRna aRna1 = createAntisenseRna();
-			AntisenseRna aRna2 = createAntisenseRna();
-			aRna1.getRegions().get(0).setName("bla");
-			assertTrue(comparator.compare(aRna1, aRna2) != 0);
-			assertTrue(comparator.compare(aRna2, aRna1) != 0);
-
-			aRna1 = createAntisenseRna();
-			aRna2 = createAntisenseRna();
-			aRna1.getRegions().clear();
-			assertTrue(comparator.compare(aRna1, aRna2) != 0);
-			assertTrue(comparator.compare(aRna2, aRna1) != 0);
-
-			aRna1 = createAntisenseRna();
-			aRna2 = createAntisenseRna();
-			assertTrue(comparator.compare(null, aRna2) != 0);
-			assertTrue(comparator.compare(aRna2, null) != 0);
-			assertTrue(comparator.compare(null, null) == 0);
-
-			AntisenseRna unknown = createAntisenseRna();
-			unknown.setName("n");
-			assertTrue(comparator.compare(unknown, aRna2) != 0);
-
-			assertTrue(comparator.compare(unknown, Mockito.mock(AntisenseRna.class)) != 0);
-		} catch (Exception e) {
-			e.printStackTrace();
-			fail("Unknowne exception occurred");
-		}
-	}
-
-	public AntisenseRna createAntisenseRna() {
-		AntisenseRna result = new AntisenseRna();
-
-		AntisenseRnaRegion region1 = new AntisenseRnaRegion();
-		result.addRegion(region1);
-		region1.setIdAntisenseRnaRegion("a");
-		region1.setName("name");
-		region1.setPos("1");
-		region1.setSize("2");
-		region1.setType(AntisenseRnaRegionType.CODING_REGION);
-		return result;
-	}
-
-	@Test
-	public void testInvalid() {
-		try {
-			AntisenseRna element = Mockito.mock(AntisenseRna.class);
-			comparator.compare(element, element);
-
-			fail("Exception expected");
-		} catch (NotImplementedException e) {
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			fail("Unknowne exception occurred");
-		}
-	}
+  AntisenseRnaComparator comparator = new AntisenseRnaComparator();
+
+  @Before
+  public void setUp() throws Exception {
+  }
+
+  @After
+  public void tearDown() throws Exception {
+  }
+
+  @Test
+  public void testEquals() {
+    try {
+      AntisenseRna aRna1 = createAntisenseRna();
+      AntisenseRna aRna2 = createAntisenseRna();
+
+      assertEquals(0, comparator.compare(aRna1, aRna1));
+
+      assertEquals(0, comparator.compare(aRna1, aRna2));
+      assertEquals(0, comparator.compare(aRna2, aRna1));
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      fail("Unknowne exception occurred");
+    }
+  }
+
+  @Test
+  public void testDifferent() {
+    try {
+      AntisenseRna aRna1 = createAntisenseRna();
+      AntisenseRna aRna2 = createAntisenseRna();
+      aRna1.getRegions().get(0).setName("bla");
+      assertTrue(comparator.compare(aRna1, aRna2) != 0);
+      assertTrue(comparator.compare(aRna2, aRna1) != 0);
+
+      aRna1 = createAntisenseRna();
+      aRna2 = createAntisenseRna();
+      aRna1.getRegions().clear();
+      assertTrue(comparator.compare(aRna1, aRna2) != 0);
+      assertTrue(comparator.compare(aRna2, aRna1) != 0);
+
+      aRna1 = createAntisenseRna();
+      aRna2 = createAntisenseRna();
+      assertTrue(comparator.compare(null, aRna2) != 0);
+      assertTrue(comparator.compare(aRna2, null) != 0);
+      assertTrue(comparator.compare(null, null) == 0);
+
+      AntisenseRna unknown = createAntisenseRna();
+      unknown.setName("n");
+      assertTrue(comparator.compare(unknown, aRna2) != 0);
+
+      assertTrue(comparator.compare(unknown, Mockito.mock(AntisenseRna.class)) != 0);
+    } catch (Exception e) {
+      e.printStackTrace();
+      fail("Unknowne exception occurred");
+    }
+  }
+
+  public AntisenseRna createAntisenseRna() {
+    AntisenseRna result = new AntisenseRna();
+
+    AntisenseRnaRegion region1 = new AntisenseRnaRegion();
+    result.addRegion(region1);
+    region1.setIdAntisenseRnaRegion("a");
+    region1.setName("name");
+    region1.setPos("1");
+    region1.setSize("2");
+    region1.setType(AntisenseRnaRegionType.CODING_REGION);
+    return result;
+  }
+
+  @Test(expected = NotImplementedException.class)
+  public void testInvalid() {
+    AntisenseRna element = Mockito.mock(AntisenseRna.class);
+    comparator.compare(element, element);
+  }
 }
diff --git a/model/src/test/java/lcsb/mapviewer/model/map/species/ChemicalComparatorTest.java b/model/src/test/java/lcsb/mapviewer/model/map/species/ChemicalComparatorTest.java
index b024670527ba887aa5ecd161c17b01ae145ea05a..ccf0fe04d016481dc37f57c87082d721cc0e82db 100644
--- a/model/src/test/java/lcsb/mapviewer/model/map/species/ChemicalComparatorTest.java
+++ b/model/src/test/java/lcsb/mapviewer/model/map/species/ChemicalComparatorTest.java
@@ -13,72 +13,62 @@ import lcsb.mapviewer.common.exception.NotImplementedException;
 
 public class ChemicalComparatorTest {
 
-	ChemicalComparator comparator = new ChemicalComparator();
-
-	@Before
-	public void setUp() throws Exception {
-	}
-
-	@After
-	public void tearDown() throws Exception {
-	}
-
-	@Test
-	public void testEquals() {
-		try {
-			Chemical drug1 = createChemical();
-			Chemical drug2 = createChemical();
-
-			assertEquals(0, comparator.compare(drug1, drug1));
-
-			assertEquals(0, comparator.compare(drug1, drug2));
-			assertEquals(0, comparator.compare(drug2, drug1));
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			fail("Unknowne exception occurred");
-		}
-	}
-
-	@Test
-	public void testDifferent() {
-		try {
-			Chemical drug2 = createChemical();
-			assertTrue(comparator.compare(null, drug2) != 0);
-			assertTrue(comparator.compare(drug2, null) != 0);
-			assertTrue(comparator.compare(null, null) == 0);
-
-			Chemical drug = createChemical();
-			drug.setName("n");
-			assertTrue(comparator.compare(drug, drug2) != 0);
-
-			assertTrue(comparator.compare(drug, Mockito.mock(Chemical.class)) != 0);
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			fail("Unknowne exception occurred");
-		}
-	}
-
-	public Chemical createChemical() {
-		Chemical result = new Ion();
-		return result;
-	}
-
-	@Test
-	public void testInvalid() {
-		try {
-			Chemical object = Mockito.mock(Chemical.class);
-
-			comparator.compare(object, object);
-
-			fail("Exception expected");
-		} catch (NotImplementedException e) {
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			fail("Unknowne exception occurred");
-		}
-	}
+  ChemicalComparator comparator = new ChemicalComparator();
+
+  @Before
+  public void setUp() throws Exception {
+  }
+
+  @After
+  public void tearDown() throws Exception {
+  }
+
+  @Test
+  public void testEquals() {
+    try {
+      Chemical drug1 = createChemical();
+      Chemical drug2 = createChemical();
+
+      assertEquals(0, comparator.compare(drug1, drug1));
+
+      assertEquals(0, comparator.compare(drug1, drug2));
+      assertEquals(0, comparator.compare(drug2, drug1));
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      fail("Unknowne exception occurred");
+    }
+  }
+
+  @Test
+  public void testDifferent() {
+    try {
+      Chemical drug2 = createChemical();
+      assertTrue(comparator.compare(null, drug2) != 0);
+      assertTrue(comparator.compare(drug2, null) != 0);
+      assertTrue(comparator.compare(null, null) == 0);
+
+      Chemical drug = createChemical();
+      drug.setName("n");
+      assertTrue(comparator.compare(drug, drug2) != 0);
+
+      assertTrue(comparator.compare(drug, Mockito.mock(Chemical.class)) != 0);
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      fail("Unknowne exception occurred");
+    }
+  }
+
+  public Chemical createChemical() {
+    Chemical result = new Ion();
+    return result;
+  }
+
+  @Test(expected = NotImplementedException.class)
+  public void testInvalid() {
+    Chemical object = Mockito.mock(Chemical.class);
+    comparator.compare(object, object);
+  }
 
 }
diff --git a/model/src/test/java/lcsb/mapviewer/model/map/species/ComplexComparatorTest.java b/model/src/test/java/lcsb/mapviewer/model/map/species/ComplexComparatorTest.java
index 907dfeeef5ca93a46aa8d67aea5dd8934cdda857..227e98136781369806e1386fadb3d013768e6050 100644
--- a/model/src/test/java/lcsb/mapviewer/model/map/species/ComplexComparatorTest.java
+++ b/model/src/test/java/lcsb/mapviewer/model/map/species/ComplexComparatorTest.java
@@ -18,373 +18,366 @@ import lcsb.mapviewer.common.exception.NotImplementedException;
 
 public class ComplexComparatorTest {
 
-	Logger						logger		 = Logger.getLogger(ComplexComparatorTest.class);
-	ComplexComparator	comparator = new ComplexComparator();
+  Logger logger = Logger.getLogger(ComplexComparatorTest.class);
+  ComplexComparator comparator = new ComplexComparator();
 
-	@Before
-	public void setUp() throws Exception {
-	}
+  @Before
+  public void setUp() throws Exception {
+  }
 
-	@After
-	public void tearDown() throws Exception {
-	}
+  @After
+  public void tearDown() throws Exception {
+  }
 
-	@Test
-	public void testEquals() {
-		try {
-			Complex complex1 = createComplex2();
-			Complex complex2 = createComplex2();
+  @Test
+  public void testEquals() {
+    try {
+      Complex complex1 = createComplex2();
+      Complex complex2 = createComplex2();
 
-			assertEquals(0, comparator.compare(complex1, complex2));
+      assertEquals(0, comparator.compare(complex1, complex2));
 
-			assertEquals(0, comparator.compare(null, null));
+      assertEquals(0, comparator.compare(null, null));
 
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
 
-	private Complex createComplex2() {
-		Complex result = new Complex();
-		result.setName("complex");
+  private Complex createComplex2() {
+    Complex result = new Complex();
+    result.setName("complex");
 
-		result.setElementId("asd");
-		result.setX(12.0);
-		result.setY(123.0);
-		result.setWidth(4);
-		result.setHeight(5);
-		result.setFontSize(9.0);
-		result.setColor(Color.BLUE);
-		result.setVisibilityLevel("14");
+    result.setElementId("asd");
+    result.setX(12.0);
+    result.setY(123.0);
+    result.setWidth(4);
+    result.setHeight(5);
+    result.setFontSize(9.0);
+    result.setColor(Color.BLUE);
+    result.setVisibilityLevel("14");
 
-		Species protein = new GenericProtein("S");
-		protein.setName("a");
-		result.addSpecies(protein);
+    Species protein = new GenericProtein("S");
+    protein.setName("a");
+    result.addSpecies(protein);
 
-		return result;
-	}
+    return result;
+  }
 
-	@Test
-	public void testDifferent() {
-		try {
-			Complex complex1 = createComplex2();
-			Complex complex2 = createComplex2();
+  @Test
+  public void testDifferent() {
+    try {
+      Complex complex1 = createComplex2();
+      Complex complex2 = createComplex2();
 
-			assertTrue(comparator.compare(complex1, null) != 0);
-			assertTrue(comparator.compare(null, complex1) != 0);
+      assertTrue(comparator.compare(complex1, null) != 0);
+      assertTrue(comparator.compare(null, complex1) != 0);
 
-			complex1 = createComplex2();
-			complex2 = createComplex2();
+      complex1 = createComplex2();
+      complex2 = createComplex2();
 
-			complex1.setElementId("tmp");
+      complex1.setElementId("tmp");
 
-			assertTrue(comparator.compare(complex1, complex2) != 0);
-			assertTrue(comparator.compare(complex2, complex1) != 0);
+      assertTrue(comparator.compare(complex1, complex2) != 0);
+      assertTrue(comparator.compare(complex2, complex1) != 0);
 
-			complex1 = createComplex2();
-			complex2 = createComplex2();
+      complex1 = createComplex2();
+      complex2 = createComplex2();
 
-			complex1.addSpecies(new GenericProtein("id"));
+      complex1.addSpecies(new GenericProtein("id"));
 
-			assertTrue(comparator.compare(complex1, complex2) != 0);
-			assertTrue(comparator.compare(complex2, complex1) != 0);
+      assertTrue(comparator.compare(complex1, complex2) != 0);
+      assertTrue(comparator.compare(complex2, complex1) != 0);
 
-			complex1 = createComplex2();
-			complex2 = createComplex2();
+      complex1 = createComplex2();
+      complex2 = createComplex2();
 
-			complex1.getElements().iterator().next().setElementId("bnu");
+      complex1.getElements().iterator().next().setElementId("bnu");
 
-			assertTrue(comparator.compare(complex1, complex2) != 0);
-			assertTrue(comparator.compare(complex2, complex1) != 0);
+      assertTrue(comparator.compare(complex1, complex2) != 0);
+      assertTrue(comparator.compare(complex2, complex1) != 0);
 
-			complex1 = createComplex2();
-			complex2 = createComplex2();
+      complex1 = createComplex2();
+      complex2 = createComplex2();
 
-			Species species = (Species) complex1.getElements().iterator().next();
-			species.setName("new namne");
-
-			assertTrue(comparator.compare(complex1, complex2) != 0);
-			assertTrue(comparator.compare(complex2, complex1) != 0);
-
-			complex1 = createComplex2();
-			complex2 = createComplex2();
-
-			complex1.setName("new namne");
-
-			assertTrue(comparator.compare(complex1, complex2) != 0);
-			assertTrue(comparator.compare(complex2, complex1) != 0);
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testInvalid() {
-		try {
-			Complex complex1 = createComplex2();
-			Complex complex2 = createComplex2();
-
-			GenericProtein protein = new GenericProtein("1");
-			complex1.getElements().add(protein);
-			protein = new GenericProtein("1");
-			complex1.getElements().add(protein);
-
-			complex2.getElements().add(new GenericProtein("b"));
-			complex2.getElements().add(new GenericProtein("a"));
-
-			comparator.compare(complex1, complex2);
-			fail("Exception expected");
-
-		} catch (InvalidArgumentException e) {
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testInvalid3() {
-		try {
-			Complex invalidComplex = Mockito.mock(Complex.class);
-
-			comparator.compare(invalidComplex, invalidComplex);
-			fail("Exception expected");
-
-		} catch (NotImplementedException e) {
-		} catch (Exception e) {
-			e.printStackTrace();
-			fail("Unkowne exception");
-		}
-	}
-
-	@Test
-	public void testInvalid2() {
-		try {
-			Complex complex1 = createComplex2();
-			Complex complex2 = createComplex2();
-
-			Species protein = new GenericProtein("1");
-			complex1.getElements().add(protein);
-			protein = new GenericProtein("1");
-			complex1.getElements().add(protein);
-
-			complex2.getElements().add(new GenericProtein("A"));
-			complex2.getElements().add(new GenericProtein("B"));
-
-			comparator.compare(complex2, complex1);
-			fail("Exception expected");
-
-		} catch (InvalidArgumentException e) {
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testEquals2() {
-		try {
-			Complex complex1 = createComplex();
-			Complex complex2 = createComplex();
-
-			assertEquals(0, comparator.compare(complex1, complex1));
-
-			assertEquals(0, comparator.compare(complex1, complex2));
-			assertEquals(0, comparator.compare(complex2, complex1));
-
-			complex2.addSpecies(new GenericProtein("test"));
-			complex1.addSpecies(new GenericProtein("test"));
-			assertEquals(0, comparator.compare(complex1, complex2));
-			assertEquals(0, comparator.compare(complex2, complex1));
-		} catch (Exception e) {
-			e.printStackTrace();
-			fail("Unknowne exception occurred");
-		}
-	}
-
-	@Test
-	public void testInvalidComp2() throws Exception {
-		try {
-			Complex complex1 = createComplex();
-			Complex complex2 = createComplex();
-
-			Species mock = Mockito.mock(Species.class);
-			when(mock.getElementId()).thenReturn("id");
-			complex1.addSpecies(mock);
-			complex2.addSpecies(mock);
-			comparator.compare(complex1, complex2);
-			comparator.compare(complex2, complex1);
-			fail("Exception expected");
-		} catch (NotImplementedException e) {
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-
-	}
-
-	@Test
-	public void testInvalidComp3() throws Exception {
-		try {
-			Complex complex1 = createComplex();
-			Complex complex2 = createComplex();
-			GenericProtein c = new GenericProtein("test");
-			complex2.addSpecies(c);
-			complex1.addSpecies(new GenericProtein("test"));
-			Species mock = Mockito.mock(Species.class);
-			when(mock.getElementId()).thenReturn("id");
-			complex1.addSpecies(mock);
-			complex2.addSpecies(mock);
-			comparator.compare(complex2, complex1);
-			fail("Exception expected");
-		} catch (NotImplementedException e) {
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-
-	}
-
-	@Test
-	public void testDifferent5() throws Exception {
-		try {
-			Complex complex1 = createComplex();
-			Complex complex2 = createComplex();
-			complex1.setHomodimer(123);
-			assertTrue(comparator.compare(complex1, complex2) != 0);
-			assertTrue(comparator.compare(complex2, complex1) != 0);
-
-			complex1 = createComplex();
-			complex2 = createComplex();
-			complex1.getElements().iterator().next().setNotes("bla");
-			assertTrue(comparator.compare(complex1, complex2) != 0);
-			assertTrue(comparator.compare(complex2, complex1) != 0);
-
-			complex1 = createComplex();
-			complex2 = createComplex();
-			complex1.getElements().clear();
-			assertTrue(comparator.compare(complex1, complex2) != 0);
-			assertTrue(comparator.compare(complex2, complex1) != 0);
-
-			complex1 = createComplex();
-			complex2 = createComplex();
-			assertTrue(comparator.compare(null, complex2) != 0);
-			assertTrue(comparator.compare(complex2, null) != 0);
-			assertTrue(comparator.compare(null, null) == 0);
-
-			complex1 = createComplex();
-			complex2 = createComplex();
-			Complex child = (Complex) complex1.getElements().iterator().next();
-			child.getElements().iterator().next().setNotes("grand child notes");
-			assertTrue(comparator.compare(complex1, complex2) != 0);
-			assertTrue(comparator.compare(complex2, complex1) != 0);
-
-			complex1 = createComplex();
-			complex2 = createComplex();
-			Protein prot = new GenericProtein();
-			prot.setElementId("test");
-			complex1.addSpecies(prot);
-			assertTrue(comparator.compare(complex1, complex2) != 0);
-			assertTrue(comparator.compare(complex2, complex1) != 0);
-
-			complex1 = createComplex();
-			complex2 = createComplex();
-			complex1.setStructuralState("str");
-			assertTrue(comparator.compare(complex1, complex2) != 0);
-			assertTrue(comparator.compare(complex2, complex1) != 0);
-
-			assertTrue(comparator.compare(new Complex(), Mockito.mock(Complex.class)) != 0);
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testDifferent3() throws Exception {
-		try {
-			Complex complex1 = createComplex();
-			Complex complex2 = createComplex();
-			GenericProtein prot = new GenericProtein();
-			prot.setElementId("test");
-			complex1.addSpecies(prot);
-			prot = new GenericProtein();
-			prot.setElementId("test2");
-			complex2.addSpecies(prot);
-			assertTrue(comparator.compare(complex1, complex2) != 0);
-			assertTrue(comparator.compare(complex2, complex1) != 0);
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testDifferent4() throws Exception {
-		try {
-			Complex complex1 = createComplex();
-			Complex complex2 = createComplex();
-			GenericProtein c = new GenericProtein("test");
-			c.setName("a");
-			complex2.addSpecies(c);
-			complex2.addSpecies(new GenericProtein("test"));
-			c.setName("");
-
-			complex1.addSpecies(new GenericProtein("test"));
-			GenericProtein d = new GenericProtein("test2");
-			d.setName("a");
-			complex1.addSpecies(d);
-			assertTrue(comparator.compare(complex1, complex2) != 0);
-			assertTrue(comparator.compare(complex2, complex1) != 0);
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testDifferent2() throws Exception {
-		try {
-			Complex complex1 = createComplex();
-			Complex complex2 = createComplex();
-			GenericProtein comp = new GenericProtein("test");
-			comp.setFullName("X");
-			complex1.addSpecies(comp);
-			complex2.addSpecies(new GenericProtein("test"));
-			assertTrue(comparator.compare(complex1, complex2) != 0);
-			assertTrue(comparator.compare(complex2, complex1) != 0);
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	public Complex createComplex() {
-		Complex result = new Complex();
-
-		result.setHypothetical(true);
-		result.setHomodimer(3);
-
-		Complex child = new Complex();
-		result.addSpecies(child);
-		child.setCharge(12);
-		child.setName("buu");
-		child.setNotes("hey, hi, hello");
-
-		Complex grandChild = new Complex();
-		child.addSpecies(grandChild);
-		child.setCharge(123);
-		child.setName("buus");
-		child.setNotes("hey, hi, hello !!");
-
-		return result;
-	}
+      Species species = (Species) complex1.getElements().iterator().next();
+      species.setName("new namne");
+
+      assertTrue(comparator.compare(complex1, complex2) != 0);
+      assertTrue(comparator.compare(complex2, complex1) != 0);
+
+      complex1 = createComplex2();
+      complex2 = createComplex2();
+
+      complex1.setName("new namne");
+
+      assertTrue(comparator.compare(complex1, complex2) != 0);
+      assertTrue(comparator.compare(complex2, complex1) != 0);
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testInvalid() {
+    try {
+      Complex complex1 = createComplex2();
+      Complex complex2 = createComplex2();
+
+      GenericProtein protein = new GenericProtein("1");
+      complex1.getElements().add(protein);
+      protein = new GenericProtein("1");
+      complex1.getElements().add(protein);
+
+      complex2.getElements().add(new GenericProtein("b"));
+      complex2.getElements().add(new GenericProtein("a"));
+
+      comparator.compare(complex1, complex2);
+      fail("Exception expected");
+
+    } catch (InvalidArgumentException e) {
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test(expected = NotImplementedException.class)
+  public void testInvalid3() {
+    Complex invalidComplex = Mockito.mock(Complex.class);
+
+    comparator.compare(invalidComplex, invalidComplex);
+
+  }
+
+  @Test
+  public void testInvalid2() {
+    try {
+      Complex complex1 = createComplex2();
+      Complex complex2 = createComplex2();
+
+      Species protein = new GenericProtein("1");
+      complex1.getElements().add(protein);
+      protein = new GenericProtein("1");
+      complex1.getElements().add(protein);
+
+      complex2.getElements().add(new GenericProtein("A"));
+      complex2.getElements().add(new GenericProtein("B"));
+
+      comparator.compare(complex2, complex1);
+      fail("Exception expected");
+
+    } catch (InvalidArgumentException e) {
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testEquals2() {
+    try {
+      Complex complex1 = createComplex();
+      Complex complex2 = createComplex();
+
+      assertEquals(0, comparator.compare(complex1, complex1));
+
+      assertEquals(0, comparator.compare(complex1, complex2));
+      assertEquals(0, comparator.compare(complex2, complex1));
+
+      complex2.addSpecies(new GenericProtein("test"));
+      complex1.addSpecies(new GenericProtein("test"));
+      assertEquals(0, comparator.compare(complex1, complex2));
+      assertEquals(0, comparator.compare(complex2, complex1));
+    } catch (Exception e) {
+      e.printStackTrace();
+      fail("Unknowne exception occurred");
+    }
+  }
+
+  @Test
+  public void testInvalidComp2() throws Exception {
+    try {
+      Complex complex1 = createComplex();
+      Complex complex2 = createComplex();
+
+      Species mock = Mockito.mock(Species.class);
+      when(mock.getElementId()).thenReturn("id");
+      complex1.addSpecies(mock);
+      complex2.addSpecies(mock);
+      comparator.compare(complex1, complex2);
+      comparator.compare(complex2, complex1);
+      fail("Exception expected");
+    } catch (NotImplementedException e) {
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+
+  }
+
+  @Test
+  public void testInvalidComp3() throws Exception {
+    try {
+      Complex complex1 = createComplex();
+      Complex complex2 = createComplex();
+      GenericProtein c = new GenericProtein("test");
+      complex2.addSpecies(c);
+      complex1.addSpecies(new GenericProtein("test"));
+      Species mock = Mockito.mock(Species.class);
+      when(mock.getElementId()).thenReturn("id");
+      complex1.addSpecies(mock);
+      complex2.addSpecies(mock);
+      comparator.compare(complex2, complex1);
+      fail("Exception expected");
+    } catch (NotImplementedException e) {
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+
+  }
+
+  @Test
+  public void testDifferent5() throws Exception {
+    try {
+      Complex complex1 = createComplex();
+      Complex complex2 = createComplex();
+      complex1.setHomodimer(123);
+      assertTrue(comparator.compare(complex1, complex2) != 0);
+      assertTrue(comparator.compare(complex2, complex1) != 0);
+
+      complex1 = createComplex();
+      complex2 = createComplex();
+      complex1.getElements().iterator().next().setNotes("bla");
+      assertTrue(comparator.compare(complex1, complex2) != 0);
+      assertTrue(comparator.compare(complex2, complex1) != 0);
+
+      complex1 = createComplex();
+      complex2 = createComplex();
+      complex1.getElements().clear();
+      assertTrue(comparator.compare(complex1, complex2) != 0);
+      assertTrue(comparator.compare(complex2, complex1) != 0);
+
+      complex1 = createComplex();
+      complex2 = createComplex();
+      assertTrue(comparator.compare(null, complex2) != 0);
+      assertTrue(comparator.compare(complex2, null) != 0);
+      assertTrue(comparator.compare(null, null) == 0);
+
+      complex1 = createComplex();
+      complex2 = createComplex();
+      Complex child = (Complex) complex1.getElements().iterator().next();
+      child.getElements().iterator().next().setNotes("grand child notes");
+      assertTrue(comparator.compare(complex1, complex2) != 0);
+      assertTrue(comparator.compare(complex2, complex1) != 0);
+
+      complex1 = createComplex();
+      complex2 = createComplex();
+      Protein prot = new GenericProtein();
+      prot.setElementId("test");
+      complex1.addSpecies(prot);
+      assertTrue(comparator.compare(complex1, complex2) != 0);
+      assertTrue(comparator.compare(complex2, complex1) != 0);
+
+      complex1 = createComplex();
+      complex2 = createComplex();
+      complex1.setStructuralState("str");
+      assertTrue(comparator.compare(complex1, complex2) != 0);
+      assertTrue(comparator.compare(complex2, complex1) != 0);
+
+      assertTrue(comparator.compare(new Complex(), Mockito.mock(Complex.class)) != 0);
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testDifferent3() throws Exception {
+    try {
+      Complex complex1 = createComplex();
+      Complex complex2 = createComplex();
+      GenericProtein prot = new GenericProtein();
+      prot.setElementId("test");
+      complex1.addSpecies(prot);
+      prot = new GenericProtein();
+      prot.setElementId("test2");
+      complex2.addSpecies(prot);
+      assertTrue(comparator.compare(complex1, complex2) != 0);
+      assertTrue(comparator.compare(complex2, complex1) != 0);
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testDifferent4() throws Exception {
+    try {
+      Complex complex1 = createComplex();
+      Complex complex2 = createComplex();
+      GenericProtein c = new GenericProtein("test");
+      c.setName("a");
+      complex2.addSpecies(c);
+      complex2.addSpecies(new GenericProtein("test"));
+      c.setName("");
+
+      complex1.addSpecies(new GenericProtein("test"));
+      GenericProtein d = new GenericProtein("test2");
+      d.setName("a");
+      complex1.addSpecies(d);
+      assertTrue(comparator.compare(complex1, complex2) != 0);
+      assertTrue(comparator.compare(complex2, complex1) != 0);
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testDifferent2() throws Exception {
+    try {
+      Complex complex1 = createComplex();
+      Complex complex2 = createComplex();
+      GenericProtein comp = new GenericProtein("test");
+      comp.setFullName("X");
+      complex1.addSpecies(comp);
+      complex2.addSpecies(new GenericProtein("test"));
+      assertTrue(comparator.compare(complex1, complex2) != 0);
+      assertTrue(comparator.compare(complex2, complex1) != 0);
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  public Complex createComplex() {
+    Complex result = new Complex();
+
+    result.setHypothetical(true);
+    result.setHomodimer(3);
+
+    Complex child = new Complex();
+    result.addSpecies(child);
+    child.setCharge(12);
+    child.setName("buu");
+    child.setNotes("hey, hi, hello");
+
+    Complex grandChild = new Complex();
+    child.addSpecies(grandChild);
+    child.setCharge(123);
+    child.setName("buus");
+    child.setNotes("hey, hi, hello !!");
+
+    return result;
+  }
 
 }
diff --git a/model/src/test/java/lcsb/mapviewer/model/map/species/DegradedComparatorTest.java b/model/src/test/java/lcsb/mapviewer/model/map/species/DegradedComparatorTest.java
index 9256b2a65aeb279d2f5fb642df7266ec57c726fb..e21a9162f1fac2c131410b269af2ebf42241b0ae 100644
--- a/model/src/test/java/lcsb/mapviewer/model/map/species/DegradedComparatorTest.java
+++ b/model/src/test/java/lcsb/mapviewer/model/map/species/DegradedComparatorTest.java
@@ -13,80 +13,71 @@ import lcsb.mapviewer.common.exception.NotImplementedException;
 
 public class DegradedComparatorTest {
 
-	DegradedComparator comparator = new DegradedComparator();
-
-	@Before
-	public void setUp() throws Exception {
-	}
-
-	@After
-	public void tearDown() throws Exception {
-	}
-
-	@Test
-	public void testEquals() {
-		try {
-			Degraded degraded1 = createDegraded();
-			Degraded degraded2 = createDegraded();
-
-			assertEquals(0, comparator.compare(degraded1, degraded1));
-
-			assertEquals(0, comparator.compare(degraded1, degraded2));
-			assertEquals(0, comparator.compare(degraded2, degraded1));
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			fail("Unknowne exception occurred");
-		}
-	}
-
-	@Test
-	public void testDifferent() {
-		try {
-			Degraded degraded1 = createDegraded();
-			Degraded degraded2 = createDegraded();
-			degraded1 = createDegraded();
-			degraded2 = createDegraded();
-			degraded1.setCharge(54);
-			assertTrue(comparator.compare(degraded1, degraded2) != 0);
-			assertTrue(comparator.compare(degraded2, degraded1) != 0);
-
-			degraded1 = createDegraded();
-			degraded2 = createDegraded();
-			assertTrue(comparator.compare(null, degraded2) != 0);
-			assertTrue(comparator.compare(degraded2, null) != 0);
-			assertTrue(comparator.compare(null, null) == 0);
-
-			Degraded degraded = createDegraded();
-			degraded.setName("n");
-			assertTrue(comparator.compare(degraded, degraded1) != 0);
-
-			assertTrue(comparator.compare(degraded, Mockito.mock(Degraded.class)) != 0);
-		} catch (Exception e) {
-			e.printStackTrace();
-			fail("Unknowne exception occurred");
-		}
-	}
-
-	public Degraded createDegraded() {
-		Degraded result = new Degraded();
-		result.setCharge(12);
-		return result;
-	}
-
-	@Test
-	public void testInvalid() {
-		try {
-			Degraded object = Mockito.mock(Degraded.class);
-
-			comparator.compare(object, object);
-
-			fail("Exception expected");
-		} catch (NotImplementedException e) {
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			fail("Unknowne exception occurred");
-		}
-	}
+  DegradedComparator comparator = new DegradedComparator();
+
+  @Before
+  public void setUp() throws Exception {
+  }
+
+  @After
+  public void tearDown() throws Exception {
+  }
+
+  @Test
+  public void testEquals() {
+    try {
+      Degraded degraded1 = createDegraded();
+      Degraded degraded2 = createDegraded();
+
+      assertEquals(0, comparator.compare(degraded1, degraded1));
+
+      assertEquals(0, comparator.compare(degraded1, degraded2));
+      assertEquals(0, comparator.compare(degraded2, degraded1));
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      fail("Unknowne exception occurred");
+    }
+  }
+
+  @Test
+  public void testDifferent() {
+    try {
+      Degraded degraded1 = createDegraded();
+      Degraded degraded2 = createDegraded();
+      degraded1 = createDegraded();
+      degraded2 = createDegraded();
+      degraded1.setCharge(54);
+      assertTrue(comparator.compare(degraded1, degraded2) != 0);
+      assertTrue(comparator.compare(degraded2, degraded1) != 0);
+
+      degraded1 = createDegraded();
+      degraded2 = createDegraded();
+      assertTrue(comparator.compare(null, degraded2) != 0);
+      assertTrue(comparator.compare(degraded2, null) != 0);
+      assertTrue(comparator.compare(null, null) == 0);
+
+      Degraded degraded = createDegraded();
+      degraded.setName("n");
+      assertTrue(comparator.compare(degraded, degraded1) != 0);
+
+      assertTrue(comparator.compare(degraded, Mockito.mock(Degraded.class)) != 0);
+    } catch (Exception e) {
+      e.printStackTrace();
+      fail("Unknowne exception occurred");
+    }
+  }
+
+  public Degraded createDegraded() {
+    Degraded result = new Degraded();
+    result.setCharge(12);
+    return result;
+  }
+
+  @Test(expected = NotImplementedException.class)
+  public void testInvalid() {
+    Degraded object = Mockito.mock(Degraded.class);
+
+    comparator.compare(object, object);
+  }
 }
diff --git a/model/src/test/java/lcsb/mapviewer/model/map/species/DrugComparatorTest.java b/model/src/test/java/lcsb/mapviewer/model/map/species/DrugComparatorTest.java
index f0568d1dec016cf63130318485ce8f3cf07dd6b9..266e2dcb248710c454987c2c1c765c4ccb39d38e 100644
--- a/model/src/test/java/lcsb/mapviewer/model/map/species/DrugComparatorTest.java
+++ b/model/src/test/java/lcsb/mapviewer/model/map/species/DrugComparatorTest.java
@@ -13,72 +13,63 @@ import lcsb.mapviewer.common.exception.NotImplementedException;
 
 public class DrugComparatorTest {
 
-	DrugComparator comparator = new DrugComparator();
-
-	@Before
-	public void setUp() throws Exception {
-	}
-
-	@After
-	public void tearDown() throws Exception {
-	}
-
-	@Test
-	public void testEquals() {
-		try {
-			Drug drug1 = createDrug();
-			Drug drug2 = createDrug();
-
-			assertEquals(0, comparator.compare(drug1, drug1));
-
-			assertEquals(0, comparator.compare(drug1, drug2));
-			assertEquals(0, comparator.compare(drug2, drug1));
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			fail("Unknowne exception occurred");
-		}
-	}
-
-	@Test
-	public void testDifferent() {
-		try {
-			Drug drug2 = createDrug();
-			assertTrue(comparator.compare(null, drug2) != 0);
-			assertTrue(comparator.compare(drug2, null) != 0);
-			assertTrue(comparator.compare(null, null) == 0);
-
-			Drug drug = createDrug();
-			drug.setName("n");
-			assertTrue(comparator.compare(drug, drug2) != 0);
-
-			assertTrue(comparator.compare(drug, Mockito.mock(Drug.class)) != 0);
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			fail("Unknowne exception occurred");
-		}
-	}
-
-	public Drug createDrug() {
-		Drug result = new Drug();
-		return result;
-	}
-
-	@Test
-	public void testInvalid() {
-		try {
-			Drug object = Mockito.mock(Drug.class);
-
-			comparator.compare(object, object);
-
-			fail("Exception expected");
-		} catch (NotImplementedException e) {
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			fail("Unknowne exception occurred");
-		}
-	}
+  DrugComparator comparator = new DrugComparator();
+
+  @Before
+  public void setUp() throws Exception {
+  }
+
+  @After
+  public void tearDown() throws Exception {
+  }
+
+  @Test
+  public void testEquals() {
+    try {
+      Drug drug1 = createDrug();
+      Drug drug2 = createDrug();
+
+      assertEquals(0, comparator.compare(drug1, drug1));
+
+      assertEquals(0, comparator.compare(drug1, drug2));
+      assertEquals(0, comparator.compare(drug2, drug1));
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      fail("Unknowne exception occurred");
+    }
+  }
+
+  @Test
+  public void testDifferent() {
+    try {
+      Drug drug2 = createDrug();
+      assertTrue(comparator.compare(null, drug2) != 0);
+      assertTrue(comparator.compare(drug2, null) != 0);
+      assertTrue(comparator.compare(null, null) == 0);
+
+      Drug drug = createDrug();
+      drug.setName("n");
+      assertTrue(comparator.compare(drug, drug2) != 0);
+
+      assertTrue(comparator.compare(drug, Mockito.mock(Drug.class)) != 0);
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      fail("Unknowne exception occurred");
+    }
+  }
+
+  public Drug createDrug() {
+    Drug result = new Drug();
+    return result;
+  }
+
+  @Test(expected = NotImplementedException.class)
+  public void testInvalid() {
+    Drug object = Mockito.mock(Drug.class);
+
+    comparator.compare(object, object);
+  }
 
 }
diff --git a/web/.settings/org.eclipse.wst.common.component b/web/.settings/org.eclipse.wst.common.component
index 2c2e2c8b85f16344550cbaac6ff5482a76560f0d..969429923156e2c3a4fb1892eeda3a20a2d72eac 100644
--- a/web/.settings/org.eclipse.wst.common.component
+++ b/web/.settings/org.eclipse.wst.common.component
@@ -37,6 +37,9 @@
         <dependent-module archiveName="rest-api-1.0.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/rest-api/rest-api">
             <dependency-type>uses</dependency-type>
         </dependent-module>
+        <dependent-module archiveName="converter-sbml-1.0.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/converter-sbml/converter-sbml">
+            <dependency-type>uses</dependency-type>
+        </dependent-module>
         <dependent-module archiveName="frontend-js-1.0.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/frontend-js/frontend-js">
             <dependency-type>uses</dependency-type>
         </dependent-module>