diff --git a/model-command/src/main/java/lcsb/mapviewer/commands/CopyCommand.java b/model-command/src/main/java/lcsb/mapviewer/commands/CopyCommand.java
index 3917a84ce5cc673ab1c41937b2a3b91e8a19b746..9f6fad6b9175a2d68ac0993d383d7733c9d92188 100644
--- a/model-command/src/main/java/lcsb/mapviewer/commands/CopyCommand.java
+++ b/model-command/src/main/java/lcsb/mapviewer/commands/CopyCommand.java
@@ -1,6 +1,8 @@
 package lcsb.mapviewer.commands;
 
+import java.util.Collection;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
 
 import org.apache.log4j.Logger;
@@ -11,6 +13,11 @@ import lcsb.mapviewer.common.exception.InvalidStateException;
 import lcsb.mapviewer.model.graphics.PolylineData;
 import lcsb.mapviewer.model.map.compartment.Compartment;
 import lcsb.mapviewer.model.map.graph.DataMiningSet;
+import lcsb.mapviewer.model.map.kinetics.SbmlArgument;
+import lcsb.mapviewer.model.map.kinetics.SbmlFunction;
+import lcsb.mapviewer.model.map.kinetics.SbmlKinetics;
+import lcsb.mapviewer.model.map.kinetics.SbmlParameter;
+import lcsb.mapviewer.model.map.kinetics.SbmlUnit;
 import lcsb.mapviewer.model.map.layout.Layout;
 import lcsb.mapviewer.model.map.layout.graphics.Layer;
 import lcsb.mapviewer.model.map.model.ElementSubmodelConnection;
@@ -32,356 +39,390 @@ import lcsb.mapviewer.model.map.species.Species;
  */
 
 public class CopyCommand extends NewModelCommand {
-	/**
-	 * Defaul class logger.
-	 */
-	@SuppressWarnings("unused")
-	private static Logger logger = Logger.getLogger(CopyCommand.class);
-
-	/**
-	 * Default constructor.
-	 * 
-	 * @param model
-	 *          {@link #model}
-	 */
-	public CopyCommand(Model model) {
-		super(model);
-	}
-
-	/**
-	 * Executed the operation.
-	 * 
-	 * @return copy of the model
-	 */
-	public Model execute() {
-		Map<Model, Model> copies = new HashMap<>();
-
-		Model model = getModel();
-
-		if (model.getModelData().getParentModels().size() > 0) {
-			ModelSubmodelConnection parent = null;
-			for (SubmodelConnection connection : model.getModelData().getParentModels()) {
-				if (connection instanceof ModelSubmodelConnection) {
-					if (parent != null) {
-						throw new InvalidArgumentException("It looks like the model is a submodel, but has more than one parent...");
-					} else {
-						parent = (ModelSubmodelConnection) connection;
-					}
-				}
-			}
-			if (parent != null) {
-				CopyCommand copyParentCommand = new CopyCommand(parent.getParentModel().getModel());
-				Model copy = copyParentCommand.execute();
-				for (ModelSubmodelConnection submodel : copy.getSubmodelConnections()) {
-					if (submodel.getName().equals(parent.getName())) {
-						return submodel.getSubmodel().getModel();
-					}
-				}
-				throw new InvalidStateException("Problem with copying submodel of a model");
-			}
-		}
-
-		Model result = createNotNestedCopy(model);
-
-		copies.put(model, result);
-
-		for (ModelSubmodelConnection submodelConnection : model.getSubmodelConnections()) {
-			Model submodel = submodelConnection.getSubmodel().getModel();
-			Model submodelCopy = createNotNestedCopy(submodel);
-			copies.put(submodel, submodelCopy);
-		}
-		for (Model modelCopy : copies.values()) {
-			try {
-				assignModelCopies(modelCopy, copies);
-			} catch (InvalidModelException e) {
-				throw new InvalidArgumentException(e);
-			}
-		}
-		return result;
-
-	}
-
-	/**
-	 * Assign information about submodel to the copied links.
-	 * 
-	 * @param modelCopy
-	 *          copy of a model where substitution should be made
-	 * @param copies
-	 *          map with map copies
-	 * @throws InvalidModelException
-	 *           when there is inconsistency in data
-	 */
-	private void assignModelCopies(Model modelCopy, Map<Model, Model> copies) throws InvalidModelException {
-		for (ModelSubmodelConnection connection : modelCopy.getSubmodelConnections()) {
-			// copy connection reference
-			Model original = connection.getSubmodel().getModel();
-			Model copy = copies.get(original);
-			if (copy == null) {
-				throw new InvalidModelException("Original model contain reference to model that wasn't copied");
-			}
-			connection.setSubmodel(copy);
-
-			// copy connection parent reference
-			if (connection.getParentModel() != null) {
-				original = connection.getParentModel().getModel();
-				if (original != null) {
-					copy = copies.get(original);
-					if (copy == null) {
-						if (!copies.values().contains(original)) {
-							throw new InvalidModelException("Original model contain reference to model that wasn't copied");
-						}
-					} else {
-						connection.setParentModel(copy);
-					}
-				}
-			}
-		}
-		for (Element alias : modelCopy.getElements()) {
-			// if alias has connection to submodel
-			if (alias.getSubmodel() != null) {
-				ElementSubmodelConnection connection = alias.getSubmodel();
-				// copy information about submodel
-				Model original = connection.getSubmodel().getModel();
-				Model copy = copies.get(original);
-				if (copy == null) {
-					throw new InvalidModelException("Original model contain reference to model that wasn't copied");
-				}
-				connection.setSubmodel(copy);
-
-				// copy information about original alias
-				if (connection.getFromElement() != null) {
-					connection.setFromElement(modelCopy.getElementByElementId(connection.getFromElement().getElementId()));
-				}
-				// copy information about reference alias
-				if (connection.getToElement() != null) {
-					connection.setToElement(modelCopy.getElementByElementId(connection.getToElement().getElementId()));
-				}
-			}
-		}
-	}
-
-	/**
-	 * Creates copy of the model without modifing information about submodels
-	 * (information about original submodels will be left in the copy).
-	 * 
-	 * @param model
-	 *          original model to copy
-	 * @return copy of the model
-	 */
-	protected Model createNotNestedCopy(Model model) {
-		Model result = new ModelFullIndexed(null);
-
-		for (Element alias : model.getElements()) {
-			if (alias instanceof Compartment) {
-				Compartment copy = ((Compartment) alias).copy();
-				copy.getElements().clear();
-				copy.setCompartment(null);
-				result.addElement(copy);
-			}
-
-		}
-
-		for (Element alias : model.getElements()) {
-			if (alias instanceof Species) {
-				Species copy = ((Species) alias).copy();
-				copy.setCompartment(null);
-				result.addElement(copy);
-
-				Compartment parentCompartment = alias.getCompartment();
-
-				if (parentCompartment != null) {
-					parentCompartment = result.getElementByElementId(parentCompartment.getElementId());
-					copy.setCompartment(parentCompartment);
-				}
-
-			} else if (alias instanceof Compartment) {
-
-				Compartment parentCompartment = alias.getCompartment();
-
-				if (parentCompartment != null) {
-					Compartment copy = result.getElementByElementId(alias.getElementId());
-					parentCompartment = result.getElementByElementId(parentCompartment.getElementId());
-					copy.setCompartment(parentCompartment);
-				}
-			} else {
-				throw new InvalidClassException("Don't know what to do with: " + alias.getClass());
-			}
-		}
-
-		for (Layer layer : model.getLayers()) {
-			result.addLayer(layer.copy());
-		}
-
-		for (Reaction reaction : model.getReactions()) {
-			result.addReaction(createCopy(reaction));
-		}
-
-		assignSimpleDataToCopy(result, model);
-		for (Layout layout : model.getLayouts()) {
-			result.addLayout(layout.copy());
-		}
-		result.setProject(model.getProject());
-
-		for (Element alias : result.getElements()) {
-			updateAliasReferences(alias, result, model);
-		}
-		for (Reaction reaction : result.getReactions()) {
-			updateReactionReferences(reaction, result);
-		}
-		for (ModelSubmodelConnection connection : model.getSubmodelConnections()) {
-			result.addSubmodelConnection(connection.copy());
-		}
-		for (DataMiningSet dataMiningSet : model.getDataMiningSets()) {
-			result.addDataMiningSet(new DataMiningSet(dataMiningSet));
-		}
-		return result;
-	}
-
-	/**
-	 * Copies simple information about model to the copy.
-	 * 
-	 * @param copy
-	 *          to this model data will be copied
-	 * @param original
-	 *          original model
-	 */
-	private void assignSimpleDataToCopy(Model copy, Model original) {
-		copy.setName(original.getName());
-
-		copy.setCreationDate(original.getCreationDate());
-
-		copy.setWidth(original.getWidth());
-		copy.setHeight(original.getHeight());
-		copy.setNotes(original.getNotes());
-		copy.setIdModel(original.getIdModel());
-		copy.setZoomLevels(original.getZoomLevels());
-		copy.setTileSize(original.getTileSize());
-	}
-
-	/**
-	 * Creates copy of the reaction that doesn't contain any references to the
-	 * original (so we have to substitute all references with the new ones...).
-	 * 
-	 * @param reaction
-	 *          original reaction
-	 * @return copy of the reaction
-	 */
-	private Reaction createCopy(Reaction reaction) {
-		Reaction copy = reaction.copy();
-		reaction.getNodes().clear();
-		for (AbstractNode node : copy.getNodes()) {
-			reaction.addNode(node);
-		}
-		copy.getNodes().clear();
-
-		for (AbstractNode node : reaction.getNodes()) {
-			AbstractNode nodeCopy = node.copy();
-			nodeCopy.setLine(new PolylineData(nodeCopy.getLine()));
-			copy.addNode(nodeCopy);
-		}
-
-		for (int i = 0; i < copy.getOperators().size(); i++) {
-			NodeOperator nodeCopy = copy.getOperators().get(i);
-			NodeOperator nodeOriginal = reaction.getOperators().get(i);
-			for (int j = 0; j < nodeCopy.getInputs().size(); j++) {
-				AbstractNode input = nodeCopy.getInputs().get(j);
-				int index1 = reaction.getOperators().indexOf(input);
-				int index2 = reaction.getNodes().indexOf(input);
-				if (index1 >= 0) {
-					nodeCopy.getInputs().set(j, copy.getOperators().get(index1));
-					copy.getOperators().get(index1).setNodeOperatorForInput(nodeCopy);
-
-					reaction.getOperators().get(index1).setNodeOperatorForInput(nodeOriginal);
-				} else if (index2 >= 0) {
-					nodeCopy.getInputs().set(j, copy.getNodes().get(index2));
-					copy.getNodes().get(index2).setNodeOperatorForInput(nodeCopy);
-
-					reaction.getNodes().get(index2).setNodeOperatorForInput(nodeOriginal);
-				} else {
-					throw new InvalidStateException("WTF");
-				}
-			}
-
-			for (int j = 0; j < nodeCopy.getOutputs().size(); j++) {
-				AbstractNode output = nodeCopy.getOutputs().get(j);
-				int index1 = reaction.getOperators().indexOf(output);
-				int index2 = reaction.getNodes().indexOf(output);
-				if (index1 >= 0) {
-					nodeCopy.getOutputs().set(j, copy.getOperators().get(index1));
-					copy.getOperators().get(index1).setNodeOperatorForOutput(nodeCopy);
-
-					reaction.getOperators().get(index1).setNodeOperatorForOutput(nodeOriginal);
-				} else if (index2 >= 0) {
-					nodeCopy.getOutputs().set(j, copy.getNodes().get(index2));
-					copy.getNodes().get(index2).setNodeOperatorForOutput(nodeCopy);
-
-					reaction.getNodes().get(index2).setNodeOperatorForOutput(nodeOriginal);
-				} else {
-					throw new InvalidStateException("WTF");
-				}
-			}
-		}
-
-		return copy;
-	}
-
-	/**
-	 * Updates references to elements and aliases in reaction to the objects taken
-	 * from model.
-	 * 
-	 * @param reaction
-	 *          references in this reaction will be updated
-	 * @param model
-	 *          references from this model will be taken
-	 */
-	private void updateReactionReferences(Reaction reaction, Model model) {
-		reaction.setModel(model);
-		for (ReactionNode rNode : reaction.getReactionNodes()) {
-			rNode.setElement(model.getElementByElementId(rNode.getElement().getElementId()));
-		}
-
-	}
-
-	/**
-	 * Updates information (like elements, parent aliases) in the alias with the
-	 * data from new model.
-	 * 
-	 * @param alias
-	 *          object to be updated
-	 * @param model
-	 *          data from this model will be used for update
-	 * @param originalModel
-	 *          original model from which alias copy was created
-	 */
-	private void updateAliasReferences(Element alias, Model model, Model originalModel) {
-		if (alias instanceof Compartment) {
-			Compartment compartmentAlias = (Compartment) alias;
-			Compartment original = originalModel.getElementByElementId(alias.getElementId());
-			for (Element a : original.getElements()) {
-				compartmentAlias.addElement(model.getElementByElementId(a.getElementId()));
-			}
-		}
-
-		if (alias instanceof Complex) {
-			Complex ca = (Complex) alias;
-			for (int i = 0; i < ca.getElements().size(); i++) {
-				Species newAlias = (Species) model.getElementByElementId(ca.getElements().get(i).getElementId());
-				ca.getElements().set(i, newAlias);
-			}
-		}
-		if (alias instanceof Species) {
-			Species sa = (Species) alias;
-
-			if (sa.getComplex() != null) {
-				sa.setComplex((Complex) model.getElementByElementId(sa.getComplex().getElementId()));
-			}
-
-		}
-
-		alias.setModel(model);
-
-		if (alias.getCompartment() != null) {
-			alias.setCompartment(model.getElementByElementId(alias.getCompartment().getElementId()));
-		}
-	}
+  /**
+   * Defaul class logger.
+   */
+  @SuppressWarnings("unused")
+  private static Logger logger = Logger.getLogger(CopyCommand.class);
+
+  /**
+   * Default constructor.
+   * 
+   * @param model
+   *          {@link #model}
+   */
+  public CopyCommand(Model model) {
+    super(model);
+  }
+
+  /**
+   * Executed the operation.
+   * 
+   * @return copy of the model
+   */
+  public Model execute() {
+    Map<Model, Model> copies = new HashMap<>();
+
+    Model model = getModel();
+
+    if (model.getModelData().getParentModels().size() > 0) {
+      ModelSubmodelConnection parent = null;
+      for (SubmodelConnection connection : model.getModelData().getParentModels()) {
+        if (connection instanceof ModelSubmodelConnection) {
+          if (parent != null) {
+            throw new InvalidArgumentException(
+                "It looks like the model is a submodel, but has more than one parent...");
+          } else {
+            parent = (ModelSubmodelConnection) connection;
+          }
+        }
+      }
+      if (parent != null) {
+        CopyCommand copyParentCommand = new CopyCommand(parent.getParentModel().getModel());
+        Model copy = copyParentCommand.execute();
+        for (ModelSubmodelConnection submodel : copy.getSubmodelConnections()) {
+          if (submodel.getName().equals(parent.getName())) {
+            return submodel.getSubmodel().getModel();
+          }
+        }
+        throw new InvalidStateException("Problem with copying submodel of a model");
+      }
+    }
+
+    Model result = createNotNestedCopy(model);
+
+    copies.put(model, result);
+
+    for (ModelSubmodelConnection submodelConnection : model.getSubmodelConnections()) {
+      Model submodel = submodelConnection.getSubmodel().getModel();
+      Model submodelCopy = createNotNestedCopy(submodel);
+      copies.put(submodel, submodelCopy);
+    }
+    for (Model modelCopy : copies.values()) {
+      try {
+        assignModelCopies(modelCopy, copies);
+      } catch (InvalidModelException e) {
+        throw new InvalidArgumentException(e);
+      }
+    }
+    return result;
+
+  }
+
+  /**
+   * Assign information about submodel to the copied links.
+   * 
+   * @param modelCopy
+   *          copy of a model where substitution should be made
+   * @param copies
+   *          map with map copies
+   * @throws InvalidModelException
+   *           when there is inconsistency in data
+   */
+  private void assignModelCopies(Model modelCopy, Map<Model, Model> copies) throws InvalidModelException {
+    for (ModelSubmodelConnection connection : modelCopy.getSubmodelConnections()) {
+      // copy connection reference
+      Model original = connection.getSubmodel().getModel();
+      Model copy = copies.get(original);
+      if (copy == null) {
+        throw new InvalidModelException("Original model contain reference to model that wasn't copied");
+      }
+      connection.setSubmodel(copy);
+
+      // copy connection parent reference
+      if (connection.getParentModel() != null) {
+        original = connection.getParentModel().getModel();
+        if (original != null) {
+          copy = copies.get(original);
+          if (copy == null) {
+            if (!copies.values().contains(original)) {
+              throw new InvalidModelException("Original model contain reference to model that wasn't copied");
+            }
+          } else {
+            connection.setParentModel(copy);
+          }
+        }
+      }
+    }
+    for (Element alias : modelCopy.getElements()) {
+      // if alias has connection to submodel
+      if (alias.getSubmodel() != null) {
+        ElementSubmodelConnection connection = alias.getSubmodel();
+        // copy information about submodel
+        Model original = connection.getSubmodel().getModel();
+        Model copy = copies.get(original);
+        if (copy == null) {
+          throw new InvalidModelException("Original model contain reference to model that wasn't copied");
+        }
+        connection.setSubmodel(copy);
+
+        // copy information about original alias
+        if (connection.getFromElement() != null) {
+          connection.setFromElement(modelCopy.getElementByElementId(connection.getFromElement().getElementId()));
+        }
+        // copy information about reference alias
+        if (connection.getToElement() != null) {
+          connection.setToElement(modelCopy.getElementByElementId(connection.getToElement().getElementId()));
+        }
+      }
+    }
+  }
+
+  /**
+   * Creates copy of the model without modifying information about submodels
+   * (information about original submodels will be left in the copy).
+   * 
+   * @param model
+   *          original model to copy
+   * @return copy of the model
+   */
+  protected Model createNotNestedCopy(Model model) {
+    Model result = new ModelFullIndexed(null);
+
+    for (SbmlUnit unit : model.getUnits()) {
+      result.addUnit(unit.copy());
+    }
+
+    for (SbmlFunction function : model.getFunctions()) {
+      result.addFunction(function.copy());
+    }
+
+    for (SbmlParameter parameter : model.getParameters()) {
+      result.addParameter(parameter.copy());
+    }
+
+    for (Element alias : model.getElements()) {
+      if (alias instanceof Compartment) {
+        Compartment copy = ((Compartment) alias).copy();
+        copy.getElements().clear();
+        copy.setCompartment(null);
+        result.addElement(copy);
+      }
+
+    }
+
+    for (Element alias : model.getElements()) {
+      if (alias instanceof Species) {
+        Species copy = ((Species) alias).copy();
+        copy.setCompartment(null);
+        result.addElement(copy);
+
+        Compartment parentCompartment = alias.getCompartment();
+
+        if (parentCompartment != null) {
+          parentCompartment = result.getElementByElementId(parentCompartment.getElementId());
+          copy.setCompartment(parentCompartment);
+        }
+
+      } else if (alias instanceof Compartment) {
+
+        Compartment parentCompartment = alias.getCompartment();
+
+        if (parentCompartment != null) {
+          Compartment copy = result.getElementByElementId(alias.getElementId());
+          parentCompartment = result.getElementByElementId(parentCompartment.getElementId());
+          copy.setCompartment(parentCompartment);
+        }
+      } else {
+        throw new InvalidClassException("Don't know what to do with: " + alias.getClass());
+      }
+    }
+
+    for (Layer layer : model.getLayers()) {
+      result.addLayer(layer.copy());
+    }
+
+    for (Reaction reaction : model.getReactions()) {
+      result.addReaction(createCopy(reaction));
+    }
+
+    assignSimpleDataToCopy(result, model);
+    for (Layout layout : model.getLayouts()) {
+      result.addLayout(layout.copy());
+    }
+    result.setProject(model.getProject());
+
+    for (Element element : result.getElements()) {
+      updateElementReferences(element, result, model);
+    }
+    for (Reaction reaction : result.getReactions()) {
+      updateReactionReferences(reaction, result);
+    }
+    for (ModelSubmodelConnection connection : model.getSubmodelConnections()) {
+      result.addSubmodelConnection(connection.copy());
+    }
+    for (DataMiningSet dataMiningSet : model.getDataMiningSets()) {
+      result.addDataMiningSet(new DataMiningSet(dataMiningSet));
+    }
+    return result;
+  }
+
+  /**
+   * Copies simple information about model to the copy.
+   * 
+   * @param copy
+   *          to this model data will be copied
+   * @param original
+   *          original model
+   */
+  private void assignSimpleDataToCopy(Model copy, Model original) {
+    copy.setName(original.getName());
+
+    copy.setCreationDate(original.getCreationDate());
+
+    copy.setWidth(original.getWidth());
+    copy.setHeight(original.getHeight());
+    copy.setNotes(original.getNotes());
+    copy.setIdModel(original.getIdModel());
+    copy.setZoomLevels(original.getZoomLevels());
+    copy.setTileSize(original.getTileSize());
+  }
+
+  /**
+   * Creates copy of the reaction that doesn't contain any references to the
+   * original (so we have to substitute all references with the new ones...).
+   * 
+   * @param reaction
+   *          original reaction
+   * @return copy of the reaction
+   */
+  private Reaction createCopy(Reaction reaction) {
+    Reaction copy = reaction.copy();
+    reaction.getNodes().clear();
+    for (AbstractNode node : copy.getNodes()) {
+      reaction.addNode(node);
+    }
+    copy.getNodes().clear();
+
+    for (AbstractNode node : reaction.getNodes()) {
+      AbstractNode nodeCopy = node.copy();
+      nodeCopy.setLine(new PolylineData(nodeCopy.getLine()));
+      copy.addNode(nodeCopy);
+    }
+
+    for (int i = 0; i < copy.getOperators().size(); i++) {
+      NodeOperator nodeCopy = copy.getOperators().get(i);
+      NodeOperator nodeOriginal = reaction.getOperators().get(i);
+      for (int j = 0; j < nodeCopy.getInputs().size(); j++) {
+        AbstractNode input = nodeCopy.getInputs().get(j);
+        int index1 = reaction.getOperators().indexOf(input);
+        int index2 = reaction.getNodes().indexOf(input);
+        if (index1 >= 0) {
+          nodeCopy.getInputs().set(j, copy.getOperators().get(index1));
+          copy.getOperators().get(index1).setNodeOperatorForInput(nodeCopy);
+
+          reaction.getOperators().get(index1).setNodeOperatorForInput(nodeOriginal);
+        } else if (index2 >= 0) {
+          nodeCopy.getInputs().set(j, copy.getNodes().get(index2));
+          copy.getNodes().get(index2).setNodeOperatorForInput(nodeCopy);
+
+          reaction.getNodes().get(index2).setNodeOperatorForInput(nodeOriginal);
+        } else {
+          throw new InvalidStateException("WTF");
+        }
+      }
+
+      for (int j = 0; j < nodeCopy.getOutputs().size(); j++) {
+        AbstractNode output = nodeCopy.getOutputs().get(j);
+        int index1 = reaction.getOperators().indexOf(output);
+        int index2 = reaction.getNodes().indexOf(output);
+        if (index1 >= 0) {
+          nodeCopy.getOutputs().set(j, copy.getOperators().get(index1));
+          copy.getOperators().get(index1).setNodeOperatorForOutput(nodeCopy);
+
+          reaction.getOperators().get(index1).setNodeOperatorForOutput(nodeOriginal);
+        } else if (index2 >= 0) {
+          nodeCopy.getOutputs().set(j, copy.getNodes().get(index2));
+          copy.getNodes().get(index2).setNodeOperatorForOutput(nodeCopy);
+
+          reaction.getNodes().get(index2).setNodeOperatorForOutput(nodeOriginal);
+        } else {
+          throw new InvalidStateException("WTF");
+        }
+      }
+    }
+
+    return copy;
+  }
+
+  /**
+   * Updates references to elements and aliases in reaction to the objects taken
+   * from model.
+   * 
+   * @param reaction
+   *          references in this reaction will be updated
+   * @param model
+   *          references from this model will be taken
+   */
+  private void updateReactionReferences(Reaction reaction, Model model) {
+    reaction.setModel(model);
+    for (ReactionNode rNode : reaction.getReactionNodes()) {
+      rNode.setElement(model.getElementByElementId(rNode.getElement().getElementId()));
+    }
+    SbmlKinetics kinetics = reaction.getKinetics();
+    if (kinetics != null) {
+      Collection<SbmlArgument> arguments = new HashSet<>();
+      for (SbmlArgument argument : kinetics.getArguments()) {
+        if (argument instanceof Element) {
+          arguments.add(model.getElementByElementId(argument.getElementId()));
+        } else if (argument instanceof SbmlParameter) {
+          if (model.getParameterById(argument.getElementId()) != null) {
+            arguments.add(model.getParameterById(argument.getElementId()));
+          } else {
+            arguments.add(argument);
+          }
+        } else if (argument instanceof SbmlFunction) {
+          arguments.add(model.getFunctionById(argument.getElementId()));
+        } else {
+          throw new InvalidStateException("Don't know what to do with class: " + argument.getClass());
+        }
+      }
+      kinetics.removeArguments(kinetics.getArguments());
+      kinetics.addArguments(arguments);
+    }
+
+  }
+
+  /**
+   * Updates information (like elements, parent aliases) in the alias with the
+   * data from new model.
+   * 
+   * @param element
+   *          object to be updated
+   * @param model
+   *          data from this model will be used for update
+   * @param originalModel
+   *          original model from which alias copy was created
+   */
+  private void updateElementReferences(Element element, Model model, Model originalModel) {
+    if (element instanceof Compartment) {
+      Compartment compartment = (Compartment) element;
+      Compartment original = originalModel.getElementByElementId(element.getElementId());
+      for (Element child : original.getElements()) {
+        compartment.addElement(model.getElementByElementId(child.getElementId()));
+      }
+    }
+
+    if (element instanceof Complex) {
+      Complex complex = (Complex) element;
+      for (int i = 0; i < complex.getElements().size(); i++) {
+        Species newElement = model.getElementByElementId(complex.getElements().get(i).getElementId());
+        complex.getElements().set(i, newElement);
+      }
+    }
+    if (element instanceof Species) {
+      Species species = (Species) element;
+
+      if (species.getComplex() != null) {
+        species.setComplex((Complex) model.getElementByElementId(species.getComplex().getElementId()));
+      }
+
+    }
+
+    element.setModel(model);
+
+    if (element.getCompartment() != null) {
+      element.setCompartment(model.getElementByElementId(element.getCompartment().getElementId()));
+    }
+  }
 }
diff --git a/model-command/src/test/java/lcsb/mapviewer/commands/CopyCommandTest.java b/model-command/src/test/java/lcsb/mapviewer/commands/CopyCommandTest.java
index 9421f1661d7e59624d1463fedc2e3765dc8285f6..d942482d7b7e014eb922b4eac6e3fadd33b518be 100644
--- a/model-command/src/test/java/lcsb/mapviewer/commands/CopyCommandTest.java
+++ b/model-command/src/test/java/lcsb/mapviewer/commands/CopyCommandTest.java
@@ -21,6 +21,8 @@ import lcsb.mapviewer.converter.model.celldesigner.CellDesignerXmlParser;
 import lcsb.mapviewer.model.graphics.PolylineData;
 import lcsb.mapviewer.model.map.compartment.Compartment;
 import lcsb.mapviewer.model.map.compartment.SquareCompartment;
+import lcsb.mapviewer.model.map.kinetics.SbmlFunction;
+import lcsb.mapviewer.model.map.kinetics.SbmlParameter;
 import lcsb.mapviewer.model.map.layout.graphics.Layer;
 import lcsb.mapviewer.model.map.model.ElementSubmodelConnection;
 import lcsb.mapviewer.model.map.model.Model;
@@ -38,317 +40,350 @@ import lcsb.mapviewer.model.map.species.GenericProtein;
 
 public class CopyCommandTest extends CommandTestFunctions {
 
-	@Before
-	public void setUp() throws Exception {
-	}
-
-	@After
-	public void tearDown() throws Exception {
-	}
-
-	@Test
-	public void testCopyModel() {
-		try {
-			Model model = getModelForFile("testFiles/sample.xml", false);
-			Model copy = new CopyCommand(model).execute();
-
-			ModelComparator comparator = new ModelComparator();
-
-			assertEquals(0, comparator.compare(model, copy));
-		} catch (Exception e) {
-			e.printStackTrace();
-			fail("exception occurred");
-		}
-	}
-
-	@Test
-	public void testCopyCustomModel() {
-		try {
-			Model model = new ModelFullIndexed(null);
-
-			GenericProtein protein = new GenericProtein("A");
-			protein.setNotes(null);
-
-			model.addElement(protein);
-
-			Model copy = new CopyCommand(model).execute();
-
-			ModelComparator comparator = new ModelComparator();
-
-			assertEquals(0, comparator.compare(model, copy));
-		} catch (Exception e) {
-			e.printStackTrace();
-			fail("exception occurred");
-		}
-	}
-
-	@Test
-	public void testCopyCustomModel2() {
-		try {
-			Model model = new ModelFullIndexed(null);
-
-			Complex complexAlias = new Complex("id2");
-			GenericProtein protein = new GenericProtein("A");
-			protein.setNotes(null);
-			complexAlias.addSpecies(protein);
-			model.addElement(protein);
-			model.addElement(complexAlias);
-
-			GenericProtein alias = new GenericProtein("B");
-			alias.setNotes(null);
-
-			complexAlias.addSpecies(alias);
-			model.addElement(alias);
-
-			Model copy = new CopyCommand(model).execute();
-
-			ModelComparator comparator = new ModelComparator();
-
-			assertEquals(0, comparator.compare(model, copy));
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testCopyModel3() throws Exception {
-		try {
-			Model model = getModelForFile("testFiles/complex_with_state.xml", true);
-
-			Model copy = new CopyCommand(model).execute();
-
-			CellDesignerXmlParser parser = new CellDesignerXmlParser();
-			String xml = parser.toXml(copy);
-
-			InputStream stream = new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8));
-			Model copy2 = parser.createModel(new ConverterParams().inputStream(stream).sizeAutoAdjust(false));
-			ModelComparator comparator = new ModelComparator();
-
-			// check if after conversion to xml everything works
-			assertEquals(0, comparator.compare(copy, copy2));
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testCopyModel4() throws Exception {
-		try {
-			Model model = getModelForFile("testFiles/problematic_description.xml", true);
-
-			Model copy = new CopyCommand(model).execute();
-
-			CellDesignerXmlParser parser = new CellDesignerXmlParser();
-			String xml = parser.toXml(copy);
-
-			InputStream stream = new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8));
-			Model copy2 = parser.createModel(new ConverterParams().inputStream(stream).sizeAutoAdjust(false));
-			ModelComparator comparator = new ModelComparator();
-
-			// check if after conversion to xml everything works
-			assertEquals(0, comparator.compare(copy, copy2));
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testCopyModelWithArtifitialAliases() throws Exception {
-		try {
-			Model model = getModelForFile("testFiles/artifitial_compartments.xml", false);
-			new CreateHierarchyCommand(model, 2, 2).execute();
-
-			Model copy = new CopyCommand(model).execute();
-
-			CellDesignerXmlParser parser = new CellDesignerXmlParser();
-			String xml = parser.toXml(copy);
-
-			InputStream stream = new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8));
-			Model copy2 = parser.createModel(new ConverterParams().inputStream(stream).sizeAutoAdjust(false));
-			ModelComparator comparator = new ModelComparator();
-
-			new CreateHierarchyCommand(copy2, 2, 2).execute();
-
-			// check if after conversion to xml everything works
-			assertEquals(0, comparator.compare(copy, copy2));
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testCopyModelWithSubmodels() throws Exception {
-		try {
-			Model model = getModel();
-			Model model2 = getModel();
-			model2.setNotes("ASDSA");
-			model.addSubmodelConnection(new ModelSubmodelConnection(model2, SubmodelType.DOWNSTREAM_TARGETS));
-			Model copy = new CopyCommand(model).execute();
-
-			ModelComparator comparator = new ModelComparator();
-
-			assertEquals(0, comparator.compare(model, copy));
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testCopySubmodel() throws Exception {
-		try {
-			Model model = getModel();
-			Model model2 = getModel();
-			model2.setNotes("ASDSA");
-			model.addSubmodelConnection(new ModelSubmodelConnection(model2, SubmodelType.DOWNSTREAM_TARGETS, "name a"));
-
-			Model model3 = getModel();
-			model3.setNotes("ASDSA");
-			model.addSubmodelConnection(new ModelSubmodelConnection(model3, SubmodelType.DOWNSTREAM_TARGETS, "name b"));
-			Element alias = model2.getElementByElementId("a_id");
-			alias.setSubmodel(new ElementSubmodelConnection(model3, SubmodelType.DOWNSTREAM_TARGETS, "name c"));
-			Model copy = new CopyCommand(model2).execute();
-
-			ModelComparator comparator = new ModelComparator();
-
-			assertEquals(0, comparator.compare(model2, copy));
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testCopyModelWithSubmodels2() throws Exception {
-		try {
-			Model model = getModel();
-			Model model2 = getModel();
-			model2.setNotes("ASDSA2");
-
-			model.addSubmodelConnection(new ModelSubmodelConnection(model2, SubmodelType.DOWNSTREAM_TARGETS));
-			model.getElementByElementId("a_id").setSubmodel(new ElementSubmodelConnection(model2, SubmodelType.DOWNSTREAM_TARGETS));
-			Model copy = new CopyCommand(model).execute();
-
-			ModelComparator comparator = new ModelComparator();
-
-			assertEquals(0, comparator.compare(model, copy));
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testCopyModelWithName() throws Exception {
-		try {
-			Model model = getModel();
-			model.setName("ASDSA2");
-
-			Model copy = new CopyCommand(model).execute();
-
-			ModelComparator comparator = new ModelComparator();
-
-			assertEquals(0, comparator.compare(model, copy));
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testCopyModelWithSubmodelsThrowException() throws Exception {
-		try {
-			Model model = getModel();
-			Model model2 = getModel();
-			model2.setNotes("ASDSA2");
-
-			model.getElementByElementId("a_id").setSubmodel(new ElementSubmodelConnection(model2, SubmodelType.DOWNSTREAM_TARGETS));
-			try {
-				new CopyCommand(model).execute();
-				fail("Exception expected");
-			} catch (InvalidArgumentException e) {
-			}
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	private Model getModel() {
-		Model model = new ModelFullIndexed(null);
-		model.setNotes("Some description");
-
-		GenericProtein alias = new GenericProtein("a_id");
-		alias.setName("ad");
-		model.addElement(alias);
-
-		Layer layer = new Layer();
-		layer.setName("layer name");
-		model.addLayer(layer);
-
-		model.addReaction(new Reaction());
-		return model;
-	}
-
-	@Test
-	public void testCopyModelReaction() throws Exception {
-		try {
-			Model model = new ModelFullIndexed(null);
-
-			Compartment c1 = new SquareCompartment("c1");
-			Compartment c2 = new SquareCompartment("c2");
-			c1.setVisibilityLevel("2");
-			c2.setVisibilityLevel("3");
-
-			model.addElement(c1);
-			model.addElement(c2);
-
-			GenericProtein s1 = new GenericProtein("s1");
-			s1.setCompartment(c1);
-			model.addElement(s1);
-
-			GenericProtein s2 = new GenericProtein("s2");
-			s2.setCompartment(c2);
-			model.addElement(s2);
-
-			StateTransitionReaction reaction = new StateTransitionReaction();
-			Reactant reactant = new Reactant(s1);
-			reactant.setLine(new PolylineData(new Point2D.Double(0, 0), new Point2D.Double(10, 10)));
-			reaction.addReactant(reactant);
-			Product product = new Product(s2);
-			product.setLine(new PolylineData(new Point2D.Double(10, 0), new Point2D.Double(120, 10)));
-			reaction.addProduct(product);
-			reaction.setVisibilityLevel("4");
-
-			model.addReaction(reaction);
-
-			assertTrue(s1.equals(reaction.getReactants().get(0).getElement()));
-			assertTrue(s2.equals(reaction.getProducts().get(0).getElement()));
-
-			Model model2 = new CopyCommand(model).execute();
-			Reaction reaction2 = model2.getReactions().iterator().next();
-
-			assertTrue(s1.equals(reaction.getReactants().get(0).getElement()));
-			assertTrue(s2.equals(reaction.getProducts().get(0).getElement()));
-
-			assertFalse(s1.equals(reaction2.getReactants().get(0).getElement()));
-			assertFalse(s2.equals(reaction2.getProducts().get(0).getElement()));
-
-			assertNotNull(reaction2.getReactants().get(0).getElement().getCompartment());
-			assertNotNull(reaction2.getProducts().get(0).getElement().getCompartment());
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
+  @Before
+  public void setUp() throws Exception {
+  }
+
+  @After
+  public void tearDown() throws Exception {
+  }
+
+  @Test
+  public void testCopyModel() {
+    try {
+      Model model = getModelForFile("testFiles/sample.xml", false);
+      Model copy = new CopyCommand(model).execute();
+
+      ModelComparator comparator = new ModelComparator();
+
+      assertEquals(0, comparator.compare(model, copy));
+    } catch (Exception e) {
+      e.printStackTrace();
+      fail("exception occurred");
+    }
+  }
+
+  @Test
+  public void testCopyModelWithKinetics() throws Exception {
+    try {
+      Model model = getModelForFile("testFiles/kinetics_with_compartment.xml", false);
+      Model copy = new CopyCommand(model).execute();
+
+      ModelComparator comparator = new ModelComparator();
+
+      assertEquals(0, comparator.compare(model, copy));
+      for (Reaction reaction : copy.getReactions()) {
+        if (reaction.getKinetics() != null) {
+          for (Element element : reaction.getKinetics().getElements()) {
+            assertTrue("Element in the copy doesn't belong to copy", copy.getElements().contains(element));
+          }
+          for (SbmlFunction function : reaction.getKinetics().getFunctions()) {
+            assertTrue("Function in the copy doesn't belong to copy", copy.getFunctions().contains(function));
+          }
+          for (SbmlParameter parameter : reaction.getKinetics().getParameters()) {
+            if (parameter.getParameterId().equals("k2")) {
+              assertTrue("Global parameter in the function copy doesn't belong to copy",
+                  copy.getParameters().contains(parameter));
+            }
+          }
+        }
+      }
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testCopyCustomModel() {
+    try {
+      Model model = new ModelFullIndexed(null);
+
+      GenericProtein protein = new GenericProtein("A");
+      protein.setNotes(null);
+
+      model.addElement(protein);
+
+      Model copy = new CopyCommand(model).execute();
+
+      ModelComparator comparator = new ModelComparator();
+
+      assertEquals(0, comparator.compare(model, copy));
+    } catch (Exception e) {
+      e.printStackTrace();
+      fail("exception occurred");
+    }
+  }
+
+  @Test
+  public void testCopyCustomModel2() {
+    try {
+      Model model = new ModelFullIndexed(null);
+
+      Complex complexAlias = new Complex("id2");
+      GenericProtein protein = new GenericProtein("A");
+      protein.setNotes(null);
+      complexAlias.addSpecies(protein);
+      model.addElement(protein);
+      model.addElement(complexAlias);
+
+      GenericProtein alias = new GenericProtein("B");
+      alias.setNotes(null);
+
+      complexAlias.addSpecies(alias);
+      model.addElement(alias);
+
+      Model copy = new CopyCommand(model).execute();
+
+      ModelComparator comparator = new ModelComparator();
+
+      assertEquals(0, comparator.compare(model, copy));
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testCopyModel3() throws Exception {
+    try {
+      Model model = getModelForFile("testFiles/complex_with_state.xml", true);
+
+      Model copy = new CopyCommand(model).execute();
+
+      CellDesignerXmlParser parser = new CellDesignerXmlParser();
+      String xml = parser.toXml(copy);
+
+      InputStream stream = new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8));
+      Model copy2 = parser.createModel(new ConverterParams().inputStream(stream).sizeAutoAdjust(false));
+      ModelComparator comparator = new ModelComparator();
+
+      // check if after conversion to xml everything works
+      assertEquals(0, comparator.compare(copy, copy2));
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testCopyModel4() throws Exception {
+    try {
+      Model model = getModelForFile("testFiles/problematic_description.xml", true);
+
+      Model copy = new CopyCommand(model).execute();
+
+      CellDesignerXmlParser parser = new CellDesignerXmlParser();
+      String xml = parser.toXml(copy);
+
+      InputStream stream = new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8));
+      Model copy2 = parser.createModel(new ConverterParams().inputStream(stream).sizeAutoAdjust(false));
+      ModelComparator comparator = new ModelComparator();
+
+      // check if after conversion to xml everything works
+      assertEquals(0, comparator.compare(copy, copy2));
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testCopyModelWithArtifitialAliases() throws Exception {
+    try {
+      Model model = getModelForFile("testFiles/artifitial_compartments.xml", false);
+      new CreateHierarchyCommand(model, 2, 2).execute();
+
+      Model copy = new CopyCommand(model).execute();
+
+      CellDesignerXmlParser parser = new CellDesignerXmlParser();
+      String xml = parser.toXml(copy);
+
+      InputStream stream = new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8));
+      Model copy2 = parser.createModel(new ConverterParams().inputStream(stream).sizeAutoAdjust(false));
+      ModelComparator comparator = new ModelComparator();
+
+      new CreateHierarchyCommand(copy2, 2, 2).execute();
+
+      // check if after conversion to xml everything works
+      assertEquals(0, comparator.compare(copy, copy2));
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testCopyModelWithSubmodels() throws Exception {
+    try {
+      Model model = getModel();
+      Model model2 = getModel();
+      model2.setNotes("ASDSA");
+      model.addSubmodelConnection(new ModelSubmodelConnection(model2, SubmodelType.DOWNSTREAM_TARGETS));
+      Model copy = new CopyCommand(model).execute();
+
+      ModelComparator comparator = new ModelComparator();
+
+      assertEquals(0, comparator.compare(model, copy));
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testCopySubmodel() throws Exception {
+    try {
+      Model model = getModel();
+      Model model2 = getModel();
+      model2.setNotes("ASDSA");
+      model.addSubmodelConnection(new ModelSubmodelConnection(model2, SubmodelType.DOWNSTREAM_TARGETS, "name a"));
+
+      Model model3 = getModel();
+      model3.setNotes("ASDSA");
+      model.addSubmodelConnection(new ModelSubmodelConnection(model3, SubmodelType.DOWNSTREAM_TARGETS, "name b"));
+      Element alias = model2.getElementByElementId("a_id");
+      alias.setSubmodel(new ElementSubmodelConnection(model3, SubmodelType.DOWNSTREAM_TARGETS, "name c"));
+      Model copy = new CopyCommand(model2).execute();
+
+      ModelComparator comparator = new ModelComparator();
+
+      assertEquals(0, comparator.compare(model2, copy));
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testCopyModelWithSubmodels2() throws Exception {
+    try {
+      Model model = getModel();
+      Model model2 = getModel();
+      model2.setNotes("ASDSA2");
+
+      model.addSubmodelConnection(new ModelSubmodelConnection(model2, SubmodelType.DOWNSTREAM_TARGETS));
+      model.getElementByElementId("a_id")
+          .setSubmodel(new ElementSubmodelConnection(model2, SubmodelType.DOWNSTREAM_TARGETS));
+      Model copy = new CopyCommand(model).execute();
+
+      ModelComparator comparator = new ModelComparator();
+
+      assertEquals(0, comparator.compare(model, copy));
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testCopyModelWithName() throws Exception {
+    try {
+      Model model = getModel();
+      model.setName("ASDSA2");
+
+      Model copy = new CopyCommand(model).execute();
+
+      ModelComparator comparator = new ModelComparator();
+
+      assertEquals(0, comparator.compare(model, copy));
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testCopyModelWithSubmodelsThrowException() throws Exception {
+    try {
+      Model model = getModel();
+      Model model2 = getModel();
+      model2.setNotes("ASDSA2");
+
+      model.getElementByElementId("a_id")
+          .setSubmodel(new ElementSubmodelConnection(model2, SubmodelType.DOWNSTREAM_TARGETS));
+      try {
+        new CopyCommand(model).execute();
+        fail("Exception expected");
+      } catch (InvalidArgumentException e) {
+      }
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  private Model getModel() {
+    Model model = new ModelFullIndexed(null);
+    model.setNotes("Some description");
+
+    GenericProtein alias = new GenericProtein("a_id");
+    alias.setName("ad");
+    model.addElement(alias);
+
+    Layer layer = new Layer();
+    layer.setName("layer name");
+    model.addLayer(layer);
+
+    model.addReaction(new Reaction());
+    return model;
+  }
+
+  @Test
+  public void testCopyModelReaction() throws Exception {
+    try {
+      Model model = new ModelFullIndexed(null);
+
+      Compartment c1 = new SquareCompartment("c1");
+      Compartment c2 = new SquareCompartment("c2");
+      c1.setVisibilityLevel("2");
+      c2.setVisibilityLevel("3");
+
+      model.addElement(c1);
+      model.addElement(c2);
+
+      GenericProtein s1 = new GenericProtein("s1");
+      s1.setCompartment(c1);
+      model.addElement(s1);
+
+      GenericProtein s2 = new GenericProtein("s2");
+      s2.setCompartment(c2);
+      model.addElement(s2);
+
+      StateTransitionReaction reaction = new StateTransitionReaction();
+      Reactant reactant = new Reactant(s1);
+      reactant.setLine(new PolylineData(new Point2D.Double(0, 0), new Point2D.Double(10, 10)));
+      reaction.addReactant(reactant);
+      Product product = new Product(s2);
+      product.setLine(new PolylineData(new Point2D.Double(10, 0), new Point2D.Double(120, 10)));
+      reaction.addProduct(product);
+      reaction.setVisibilityLevel("4");
+
+      model.addReaction(reaction);
+
+      assertTrue(s1.equals(reaction.getReactants().get(0).getElement()));
+      assertTrue(s2.equals(reaction.getProducts().get(0).getElement()));
+
+      Model model2 = new CopyCommand(model).execute();
+      Reaction reaction2 = model2.getReactions().iterator().next();
+
+      assertTrue(s1.equals(reaction.getReactants().get(0).getElement()));
+      assertTrue(s2.equals(reaction.getProducts().get(0).getElement()));
+
+      assertFalse(s1.equals(reaction2.getReactants().get(0).getElement()));
+      assertFalse(s2.equals(reaction2.getProducts().get(0).getElement()));
+
+      assertNotNull(reaction2.getReactants().get(0).getElement().getCompartment());
+      assertNotNull(reaction2.getProducts().get(0).getElement().getCompartment());
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
 
 }
diff --git a/model-command/testFiles/kinetics_with_compartment.xml b/model-command/testFiles/kinetics_with_compartment.xml
new file mode 100644
index 0000000000000000000000000000000000000000..209c35ca73ee4b52c9312283f5c62b0c30c9bbf6
--- /dev/null
+++ b/model-command/testFiles/kinetics_with_compartment.xml
@@ -0,0 +1,217 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<sbml xmlns="http://www.sbml.org/sbml/level2/version4" xmlns:celldesigner="http://www.sbml.org/2001/ns/celldesigner" level="2" version="4">
+<model metaid="untitled" id="untitled">
+<annotation>
+<celldesigner:extension>
+<celldesigner:modelVersion>4.0</celldesigner:modelVersion>
+<celldesigner:modelDisplay sizeX="600" sizeY="400"/>
+<celldesigner:listOfCompartmentAliases>
+<celldesigner:compartmentAlias id="ca1" compartment="c1">
+<celldesigner:class>SQUARE</celldesigner:class>
+<celldesigner:bounds x="46.0" y="105.0" w="413.0" h="201.0"/>
+<celldesigner:namePoint x="244.0" y="270.5"/>
+<celldesigner:doubleLine thickness="12.0" outerWidth="2.0" innerWidth="1.0"/>
+<celldesigner:paint color="ffcccc00" scheme="Color"/>
+<celldesigner:info state="empty" angle="-1.5707963267948966"/>
+</celldesigner:compartmentAlias>
+</celldesigner:listOfCompartmentAliases>
+<celldesigner:listOfComplexSpeciesAliases/>
+<celldesigner:listOfSpeciesAliases>
+<celldesigner:speciesAlias id="sa1" species="s1" compartmentAlias="ca1">
+<celldesigner:activity>inactive</celldesigner:activity>
+<celldesigner:bounds x="67.0" y="151.0" w="80.0" h="40.0"/>
+<celldesigner:font size="12"/>
+<celldesigner:view state="usual"/>
+<celldesigner:usualView>
+<celldesigner:innerPosition x="21.0" y="46.0"/>
+<celldesigner:boxSize width="80.0" height="40.0"/>
+<celldesigner:singleLine width="1.0"/>
+<celldesigner:paint color="ffccffcc" scheme="Color"/>
+</celldesigner:usualView>
+<celldesigner:briefView>
+<celldesigner:innerPosition x="0.0" y="0.0"/>
+<celldesigner:boxSize width="80.0" height="60.0"/>
+<celldesigner:singleLine width="1.0"/>
+<celldesigner:paint color="3fff0000" scheme="Color"/>
+</celldesigner:briefView>
+<celldesigner:info state="empty" angle="-1.5707963267948966"/>
+</celldesigner:speciesAlias>
+<celldesigner:speciesAlias id="sa2" species="s2" compartmentAlias="ca1">
+<celldesigner:activity>inactive</celldesigner:activity>
+<celldesigner:bounds x="296.0" y="174.0" w="80.0" h="40.0"/>
+<celldesigner:font size="12"/>
+<celldesigner:view state="usual"/>
+<celldesigner:usualView>
+<celldesigner:innerPosition x="250.0" y="69.0"/>
+<celldesigner:boxSize width="80.0" height="40.0"/>
+<celldesigner:singleLine width="1.0"/>
+<celldesigner:paint color="ffccffcc" scheme="Color"/>
+</celldesigner:usualView>
+<celldesigner:briefView>
+<celldesigner:innerPosition x="0.0" y="0.0"/>
+<celldesigner:boxSize width="80.0" height="60.0"/>
+<celldesigner:singleLine width="1.0"/>
+<celldesigner:paint color="3fff0000" scheme="Color"/>
+</celldesigner:briefView>
+<celldesigner:info state="empty" angle="-1.5707963267948966"/>
+</celldesigner:speciesAlias>
+</celldesigner:listOfSpeciesAliases>
+<celldesigner:listOfGroups/>
+<celldesigner:listOfProteins>
+<celldesigner:protein id="pr1" name="s1" type="GENERIC"/>
+<celldesigner:protein id="pr2" name="s2" type="GENERIC"/>
+</celldesigner:listOfProteins>
+<celldesigner:listOfGenes/>
+<celldesigner:listOfRNAs/>
+<celldesigner:listOfAntisenseRNAs/>
+<celldesigner:listOfLayers/>
+<celldesigner:listOfBlockDiagrams/>
+</celldesigner:extension>
+</annotation>
+<listOfParameters>
+<parameter metaid="k2" id="k2" name="global param" value="0" units="substance"/>
+</listOfParameters>
+<listOfFunctionDefinitions>
+<functionDefinition metaid="fun" id="fun" name="Function name">
+<math xmlns="http://www.w3.org/1998/Math/MathML">
+<lambda>
+<bvar>
+<ci> x </ci>
+</bvar>
+<bvar>
+<ci> y </ci>
+</bvar>
+<apply>
+<plus/>
+<ci> x </ci>
+<ci> y </ci>
+</apply>
+</lambda>
+</math>
+</functionDefinition>
+</listOfFunctionDefinitions>
+<listOfUnitDefinitions>
+<unitDefinition metaid="substance" id="substance" name="substance">
+<listOfUnits>
+<unit metaid="CDMT00004" kind="mole"/>
+</listOfUnits>
+</unitDefinition>
+<unitDefinition metaid="volume" id="volume" name="volume">
+<listOfUnits>
+<unit metaid="CDMT00005" kind="litre"/>
+</listOfUnits>
+</unitDefinition>
+<unitDefinition metaid="area" id="area" name="area">
+<listOfUnits>
+<unit metaid="CDMT00006" kind="metre" exponent="2"/>
+</listOfUnits>
+</unitDefinition>
+<unitDefinition metaid="length" id="length" name="length">
+<listOfUnits>
+<unit metaid="CDMT00007" kind="metre"/>
+</listOfUnits>
+</unitDefinition>
+<unitDefinition metaid="time" id="time" name="time">
+<listOfUnits>
+<unit metaid="CDMT00008" kind="second"/>
+</listOfUnits>
+</unitDefinition>
+</listOfUnitDefinitions>
+<listOfCompartments>
+<compartment metaid="default" id="default" size="1" units="volume"/>
+<compartment metaid="c1" id="c1" name="c1" size="1" units="volume" outside="default">
+<annotation>
+<celldesigner:extension>
+<celldesigner:name>c1</celldesigner:name>
+</celldesigner:extension>
+</annotation>
+</compartment>
+</listOfCompartments>
+<listOfSpecies>
+<species metaid="s1" id="s1" name="s1" compartment="c1" initialAmount="0">
+<annotation>
+<celldesigner:extension>
+<celldesigner:positionToCompartment>inside</celldesigner:positionToCompartment>
+<celldesigner:speciesIdentity>
+<celldesigner:class>PROTEIN</celldesigner:class>
+<celldesigner:proteinReference>pr1</celldesigner:proteinReference>
+</celldesigner:speciesIdentity>
+</celldesigner:extension>
+</annotation>
+</species>
+<species metaid="s2" id="s2" name="s2" compartment="c1" initialAmount="0">
+<annotation>
+<celldesigner:extension>
+<celldesigner:positionToCompartment>inside</celldesigner:positionToCompartment>
+<celldesigner:speciesIdentity>
+<celldesigner:class>PROTEIN</celldesigner:class>
+<celldesigner:proteinReference>pr2</celldesigner:proteinReference>
+</celldesigner:speciesIdentity>
+</celldesigner:extension>
+</annotation>
+</species>
+</listOfSpecies>
+<listOfReactions>
+<reaction metaid="re1" id="re1" reversible="false" fast="false">
+<annotation>
+<celldesigner:extension>
+<celldesigner:reactionType>STATE_TRANSITION</celldesigner:reactionType>
+<celldesigner:baseReactants>
+<celldesigner:baseReactant species="s1" alias="sa1"/>
+</celldesigner:baseReactants>
+<celldesigner:baseProducts>
+<celldesigner:baseProduct species="s2" alias="sa2"/>
+</celldesigner:baseProducts>
+<celldesigner:connectScheme connectPolicy="direct" rectangleIndex="0">
+<celldesigner:listOfLineDirection>
+<celldesigner:lineDirection index="0" value="unknown"/>
+</celldesigner:listOfLineDirection>
+</celldesigner:connectScheme>
+<celldesigner:line width="1.0" color="ff000000"/>
+</celldesigner:extension>
+</annotation>
+<listOfReactants>
+<speciesReference metaid="CDMT00001" species="s1">
+<annotation>
+<celldesigner:extension>
+<celldesigner:alias>sa1</celldesigner:alias>
+</celldesigner:extension>
+</annotation>
+</speciesReference>
+</listOfReactants>
+<listOfProducts>
+<speciesReference metaid="CDMT00002" species="s2">
+<annotation>
+<celldesigner:extension>
+<celldesigner:alias>sa2</celldesigner:alias>
+</celldesigner:extension>
+</annotation>
+</speciesReference>
+</listOfProducts>
+<kineticLaw metaid="CDMT00003">
+<math xmlns="http://www.w3.org/1998/Math/MathML">
+<apply>
+<divide/>
+<apply>
+<times/>
+<ci> c1 </ci>
+<apply>
+<plus/>
+<ci> s1 </ci>
+<ci> s2 </ci>
+<ci> fun </ci>
+<ci> k2 </ci>
+<ci> k1 </ci>
+</apply>
+</apply>
+<cn type="integer"> 2 </cn>
+</apply>
+</math>
+<listOfParameters>
+<parameter metaid="k1" id="k1" name="local param" value="0" units="substance"/>
+</listOfParameters>
+</kineticLaw>
+</reaction>
+</listOfReactions>
+</model>
+</sbml>
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/kinetics/SbmlKinetics.java b/model/src/main/java/lcsb/mapviewer/model/map/kinetics/SbmlKinetics.java
index aa0a577447c7f3f667d16f957c19e0f09da0e124..8b7b1058ff6e3ce6893aaaceb3e59198457e7696 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/kinetics/SbmlKinetics.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/kinetics/SbmlKinetics.java
@@ -16,8 +16,6 @@ import javax.persistence.Id;
 import javax.persistence.JoinColumn;
 import javax.persistence.JoinTable;
 import javax.persistence.ManyToMany;
-import javax.persistence.ManyToOne;
-import javax.persistence.OneToOne;
 import javax.persistence.Table;
 import javax.xml.bind.annotation.XmlRootElement;
 
@@ -25,7 +23,6 @@ import org.apache.log4j.Logger;
 import org.hibernate.annotations.Cascade;
 import org.hibernate.annotations.CascadeType;
 
-import lcsb.mapviewer.model.map.reaction.Reaction;
 import lcsb.mapviewer.model.map.species.Element;
 
 /**
@@ -134,8 +131,8 @@ public class SbmlKinetics implements Serializable {
 
   }
 
-  public void addArguments(Set<SbmlArgument> elementsUsedInKinetics) {
-    for (SbmlArgument argument : elementsUsedInKinetics) {
+  public void addArguments(Collection<SbmlArgument> arguments) {
+    for (SbmlArgument argument : arguments) {
       addArgument(argument);
     }
 
@@ -180,4 +177,29 @@ public class SbmlKinetics implements Serializable {
   public void removeElement(Element elementToRemove) {
     elements.remove(elementToRemove);
   }
+
+  public void removeArguments(Collection<SbmlArgument> arguments) {
+    for (SbmlArgument sbmlArgument : arguments) {
+      removeArgument(sbmlArgument);
+    }
+  }
+
+  private void removeArgument(SbmlArgument argument) {
+    if (argument instanceof SbmlParameter) {
+      removeParameter((SbmlParameter) argument);
+    } else if (argument instanceof SbmlFunction) {
+      removeFunction((SbmlFunction) argument);
+    } else {
+      removeElement((Element) argument);
+    }
+  }
+
+  private void removeFunction(SbmlFunction function) {
+    functions.remove(function);
+  }
+
+  private void removeParameter(SbmlParameter parameter) {
+    parameters.remove(parameter);
+
+  }
 }
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/kinetics/SbmlUnit.java b/model/src/main/java/lcsb/mapviewer/model/map/kinetics/SbmlUnit.java
index 3a0b60ad84756d1d3bac0ddca634192482a825b3..f1a1339c6a08ca74058334d81c3d5be9f5199349 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/kinetics/SbmlUnit.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/kinetics/SbmlUnit.java
@@ -76,6 +76,14 @@ public class SbmlUnit implements Serializable {
     this.unitId = unitId;
   }
 
+  public SbmlUnit(SbmlUnit sbmlUnit) {
+    this(sbmlUnit.getUnitId());
+    this.setName(sbmlUnit.getName());
+    for (SbmlUnitTypeFactor factor : sbmlUnit.getUnitTypeFactors()) {
+      this.addUnitTypeFactor(factor.copy());
+    }
+  }
+
   public String getUnitId() {
     return unitId;
   }
@@ -109,4 +117,8 @@ public class SbmlUnit implements Serializable {
     this.model = model;
   }
 
+  public SbmlUnit copy() {
+    return new SbmlUnit(this);
+  }
+
 }
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/kinetics/SbmlUnitComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/kinetics/SbmlUnitComparator.java
index 0f4b585b9f78546434943fcc14032cdb3b553fd2..c76949b4914634ca8eb62cc53255061ad55dcf71 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/kinetics/SbmlUnitComparator.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/kinetics/SbmlUnitComparator.java
@@ -1,10 +1,13 @@
 package lcsb.mapviewer.model.map.kinetics;
 
+import org.apache.log4j.Logger;
+
 import lcsb.mapviewer.common.Comparator;
 import lcsb.mapviewer.common.comparator.SetComparator;
 import lcsb.mapviewer.common.comparator.StringComparator;
 
 public class SbmlUnitComparator extends Comparator<SbmlUnit> {
+  Logger logger =Logger.getLogger(SbmlUnitComparator.class);
 
   public SbmlUnitComparator() {
     super(SbmlUnit.class);
@@ -16,22 +19,18 @@ public class SbmlUnitComparator extends Comparator<SbmlUnit> {
     SetComparator<SbmlUnitTypeFactor> unitTypeFactorComparator = new SetComparator<>(
         new SbmlUnitTypeFactorComparator());
     if (stringComparator.compare(arg0.getUnitId(), arg1.getUnitId()) != 0) {
+      logger.debug("unitId different");
       return stringComparator.compare(arg0.getUnitId(), arg1.getUnitId());
     }
     if (stringComparator.compare(arg0.getName(), arg1.getName()) != 0) {
+      logger.debug("name different");
       return stringComparator.compare(arg0.getName(), arg1.getName());
     }
 
     if (unitTypeFactorComparator.compare(arg0.getUnitTypeFactors(), arg1.getUnitTypeFactors()) != 0) {
+      logger.debug("unit type factor different");
       return unitTypeFactorComparator.compare(arg0.getUnitTypeFactors(), arg1.getUnitTypeFactors());
     }
-    //
-    // if (stringListComparator.compare(arg0.getArguments(), arg1.getArguments()) !=
-    // 0) {
-    // return stringListComparator.compare(arg0.getArguments(),
-    // arg1.getArguments());
-    // }
-
     return 0;
   }
 
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/kinetics/SbmlUnitTypeFactor.java b/model/src/main/java/lcsb/mapviewer/model/map/kinetics/SbmlUnitTypeFactor.java
index 1e4c15b550157b86fcdd11d3b29e6de03b17bc54..b718204ce9d1133caf73ad27591138cf98b91525 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/kinetics/SbmlUnitTypeFactor.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/kinetics/SbmlUnitTypeFactor.java
@@ -16,8 +16,6 @@ import javax.xml.bind.annotation.XmlRootElement;
 
 import org.apache.log4j.Logger;
 
-import lcsb.mapviewer.model.map.model.ModelData;
-
 /**
  * Representation of a single SBML unit factor. For example unit for velocity is
  * m/s. It means that we have two unit types here:
@@ -78,6 +76,10 @@ public class SbmlUnitTypeFactor implements Serializable {
     this.multiplier = multiplier;
   }
 
+  public SbmlUnitTypeFactor(SbmlUnitTypeFactor original) {
+    this(original.getUnitType(), original.getExponent(), original.getScale(), original.getMultiplier());
+  }
+
   public SbmlUnitType getUnitType() {
     return unitType;
   }
@@ -118,4 +120,8 @@ public class SbmlUnitTypeFactor implements Serializable {
     this.unit = unit;
   }
 
+  public SbmlUnitTypeFactor copy() {
+    return new SbmlUnitTypeFactor(this);
+  }
+
 }
diff --git a/model/src/test/java/lcsb/mapviewer/model/map/kinetics/SbmlUnitTest.java b/model/src/test/java/lcsb/mapviewer/model/map/kinetics/SbmlUnitTest.java
index 3e1d4e4f8785f4ac012ae54f058805b6cde06777..05018314821db4dc3d189b56e0f3a5d4d2e2ec18 100644
--- a/model/src/test/java/lcsb/mapviewer/model/map/kinetics/SbmlUnitTest.java
+++ b/model/src/test/java/lcsb/mapviewer/model/map/kinetics/SbmlUnitTest.java
@@ -5,6 +5,7 @@ import static org.junit.Assert.assertEquals;
 import org.junit.Test;
 
 public class SbmlUnitTest {
+  SbmlUnitComparator comparator = new SbmlUnitComparator();
 
   @Test
   public void testConstructor() {
@@ -15,12 +16,22 @@ public class SbmlUnitTest {
 
   @Test
   public void testSetName() {
-    String name= "id";
+    String name = "id";
     SbmlUnit unit = new SbmlUnit("");
     unit.setName(name);
     assertEquals(unit.getName(), name);
   }
 
+  @Test
+  public void testCopy() {
+    SbmlUnit unit = new SbmlUnit("");
+    unit.setName("nam");
+    unit.addUnitTypeFactor(new SbmlUnitTypeFactor(SbmlUnitType.METRE, 2, 0, 1.0));
+
+    SbmlUnit copy = unit.copy();
+    assertEquals(0, comparator.compare(unit, copy));
+  }
+
   @Test
   public void testAddUnitTypeFactor() {
     SbmlUnitTypeFactor factor = new SbmlUnitTypeFactor(SbmlUnitType.METRE, 2, 0, 1.0);