diff --git a/GUI/GUI.iml b/GUI/GUI.iml
new file mode 100644
index 0000000000000000000000000000000000000000..0d65c1a1d59c3a0442954dbca08b2beecdca97ab
--- /dev/null
+++ b/GUI/GUI.iml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7">
+    <output url="file://$MODULE_DIR$/target/classes" />
+    <output-test url="file://$MODULE_DIR$/target/test-classes" />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
+      <excludeFolder url="file://$MODULE_DIR$/target" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="library" name="Maven: org.netbeans.api:org-netbeans-api-annotations-common:RELEASE82" level="project" />
+    <orderEntry type="module" module-name="MeshModel" />
+    <orderEntry type="library" name="Maven: java3d:j3d-core-utils:1.3.1" level="project" />
+    <orderEntry type="library" name="Maven: java3d:vecmath:1.3.1" level="project" />
+    <orderEntry type="library" name="Maven: java3d:j3d-core:1.3.1" level="project" />
+    <orderEntry type="library" name="Maven: com.github.mokiat:java-data-front:v2.0.0" level="project" />
+    <orderEntry type="library" name="Maven: javax.vecmath:vecmath:1.5.2" level="project" />
+    <orderEntry type="library" name="Maven: org.jogamp.jogl:jogl-all-mobile:2.0.2-rc12" level="project" />
+    <orderEntry type="library" name="Maven: org.jogamp.jogl:jogl-all:2.0-rc11" level="project" />
+  </component>
+</module>
\ No newline at end of file
diff --git a/MeshModel/MeshModel.iml b/MeshModel/MeshModel.iml
index df0b22bf0cb8c1d360fe1d05711bbbd2a40697e7..d7209f8e975db657bacc86e4b6f795a755009514 100644
--- a/MeshModel/MeshModel.iml
+++ b/MeshModel/MeshModel.iml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
-  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7">
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
     <output url="file://$MODULE_DIR$/target/classes" />
     <output-test url="file://$MODULE_DIR$/target/test-classes" />
     <content url="file://$MODULE_DIR$">
@@ -11,6 +11,17 @@
     </content>
     <orderEntry type="inheritedJdk" />
     <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter:5.6.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-params:5.6.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-engine:5.6.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.junit.platform:junit-platform-engine:1.6.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.testng:testng:7.1.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: com.beust:jcommander:1.72" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: com.google.inject:guice:no_aop:4.1.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: javax.inject:javax.inject:1" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: aopalliance:aopalliance:1.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: com.google.guava:guava:19.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.yaml:snakeyaml:1.21" level="project" />
     <orderEntry type="library" name="Maven: java3d:j3d-core-utils:1.3.1" level="project" />
     <orderEntry type="library" name="Maven: java3d:vecmath:1.3.1" level="project" />
     <orderEntry type="library" name="Maven: java3d:j3d-core:1.3.1" level="project" />
diff --git a/MeshModel/pom.xml b/MeshModel/pom.xml
index c06a0cd36a6b0e89f538f1b384e3cb1dc1da9376..4cc678b315ca4133457255bdd39191d3878ba3c0 100644
--- a/MeshModel/pom.xml
+++ b/MeshModel/pom.xml
@@ -108,6 +108,7 @@
             <artifactId>vecmath</artifactId>
             <version>1.5.2</version>
         </dependency>
+        <!-- https://mvnrepository.com/artifact/junit/junit -->
         <dependency>
             <groupId>org.junit.jupiter</groupId>
             <artifactId>junit-jupiter</artifactId>
diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/CornerTable.java b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/CornerTable.java
index 1f2d0f65b816e631350158b6b83ecbaf5f2dfaec..f7960da57ffca8b9cc5f6530b2bcf2afe3528fe7 100644
--- a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/CornerTable.java
+++ b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/CornerTable.java
@@ -2,6 +2,7 @@ package cz.fidentis.analyst.mesh.core;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.stream.Collectors;
 
 /**
  * Representation of mesh in memory using corner table
@@ -12,6 +13,25 @@ public class CornerTable {
 
     private List<CornerTableRow> rows = new ArrayList<>();
 
+    /**
+     * Constructor of CornerTable
+     */
+    public CornerTable() {
+
+    }
+
+    /**
+     * Copy constructor of CornerTable
+     *
+     * @param cornerTable copied CornerTable
+     */
+    public CornerTable(CornerTable cornerTable) {
+        for (CornerTableRow row :
+                cornerTable.rows) {
+            rows.add(new CornerTableRow(row));
+        }
+    }
+
     /**
      * returns index of face that contains corner.
      * returns -2 if index is less than 0 or more than number of rows in corner table
@@ -111,8 +131,8 @@ public class CornerTable {
         if (index < 0 || index > rows.size()) {
             return -2;
         }
-        int tipLeftCornerIndex=getIndexOfTipCornerOnLeft(index);
-        if (tipLeftCornerIndex==-1){
+        int tipLeftCornerIndex = getIndexOfTipCornerOnLeft(index);
+        if (tipLeftCornerIndex == -1) {
             return -1;
         }
 
@@ -156,4 +176,43 @@ public class CornerTable {
     public CornerTableRow getRow(int index) {
         return rows.get(index);
     }
+
+    /**
+     * returns corners of specific vertex
+     *
+     * @param vertexIndex index of vertex
+     * @return list of rows of corner table
+     */
+    public List<CornerTableRow> getCornersByVertexIndex(int vertexIndex) {
+        return rows.stream()
+                .filter(corner -> corner.getVertexIndex() == vertexIndex)
+                .collect(Collectors.toList());
+    }
+
+    /**
+     * returns list of indexes of faces that have a corner at specific vertex
+     *
+     * @param vertexIndex index of vertex
+     * @return list of indexes of faces
+     */
+    public List<Integer> getTriangleIndexesByVertexIndex(int vertexIndex) {
+        return rows.stream()
+                .filter(corner -> corner.getVertexIndex() == vertexIndex)
+                .map(corner -> getIndexOfFace(rows.indexOf(corner)))
+                .collect(Collectors.toList());
+    }
+
+    /**
+     * returns indexes of vertices of triangle
+     * @param triangleIndex index of triangle
+     * @return list of indexes
+     */
+    public List<Integer> getIndexesOfVerticesByTriangleIndex(int triangleIndex) {
+        List<Integer> indexes = new ArrayList<>();
+        for (int i = 0; i < 3; i++) {
+            CornerTableRow row = getRow(triangleIndex + i);
+            indexes.add(row.getVertexIndex());
+        }
+        return indexes;
+    }
 }
diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/CornerTableRow.java b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/CornerTableRow.java
index 07deb873ae87123981d7e42c62b31e92f6a6427d..99f9795892754686976bd4f29917a8d3f423c261 100644
--- a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/CornerTableRow.java
+++ b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/CornerTableRow.java
@@ -11,7 +11,8 @@ public class CornerTableRow {
 
     /**
      * Constructor of a row in corner
-     * @param vertexIndex index of associated vertex in MashFacet
+     *
+     * @param vertexIndex         index of associated vertex in MashFacet
      * @param oppositeCornerIndex index of the opposite corner, -1 if there is no opposite corner
      */
     public CornerTableRow(int vertexIndex, int oppositeCornerIndex) {
@@ -19,6 +20,16 @@ public class CornerTableRow {
         this.oppositeCornerIndex = oppositeCornerIndex;
     }
 
+    /**
+     * Copy constructor of a row in corner
+     *
+     * @param cornerTableRow copied row
+     */
+    public CornerTableRow(CornerTableRow cornerTableRow) {
+        this.vertexIndex = cornerTableRow.getVertexIndex();
+        this.oppositeCornerIndex = cornerTableRow.getOppositeCornerIndex();
+    }
+
     /**
      * returns vertex of corner
      *
@@ -37,6 +48,7 @@ public class CornerTableRow {
 
     /**
      * sets index of the opposite corner
+     *
      * @param index index of the opposite corner in corner table
      */
     public void setOppositeCornerIndex(int index) {
diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshFacet.java b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshFacet.java
index 438af33a71d319bd2fdfd9f751bec35bffc09875..a9c59105ee017853cc37270a86e9b41885f6a1e9 100644
--- a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshFacet.java
+++ b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshFacet.java
@@ -9,36 +9,69 @@ import java.util.List;
  * @author Matej Lukes
  */
 public class MeshFacet {
-    private List<MeshPoint> vertexes = new ArrayList<>();
-    private CornerTable cornerTable = new CornerTable();
+    private List<MeshPoint> vertices = new ArrayList<>();
+    private CornerTable cornerTable;
+
+    /**
+     * Constructor of MeshFacet
+     */
+    public MeshFacet() {
+        cornerTable = new CornerTable();
+    }
+
+    /**
+     * Copy constructor of MeshFacet
+     *
+     * @param facet copied MeshFacet
+     */
+    public MeshFacet(MeshFacet facet) {
+        for (MeshPoint vertex :
+                facet.vertices) {
+            vertices.add(new MeshPoint(vertex));
+        }
+        cornerTable = new CornerTable(facet.cornerTable);
+    }
 
     /**
      * returns vertex of specified index
+     *
      * @param index index of vertex
      * @return vertex
      */
     public MeshPoint getVertex(int index) {
-        return vertexes.get(index);
+        return vertices.get(index);
     }
 
     /**
      * adds vertex to MeshFacet
+     *
      * @param point new vertex
      */
-    public void addVertex(MeshPoint point){
-        vertexes.add(point);
+    public void addVertex(MeshPoint point) {
+        vertices.add(point);
+    }
+
+    /**
+     * returns number of vertices in MeshFacet
+     *
+     * @return number of vertices
+     */
+    public int getNumberOfVertices() {
+        return vertices.size();
     }
 
     /**
-     * returns number of vertexes in MeshFacet
-     * @return number of vertexes
+     * returns list of vertices in MeshFacet
+     *
+     * @return list if vertices
      */
-    public int getNumberOfVertexes() {
-        return vertexes.size();
+    public List<MeshPoint> getVertices() {
+        return vertices;
     }
 
     /**
      * returns Corner Table representing MeshFacet
+     *
      * @return corner table
      */
     public CornerTable getCornerTable() {
diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshModel.java b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshModel.java
index 7966434fa301c4163ff8840eb94cc3364dec64bb..1f22bb850298923e44df81fef96a40ffb33cfd71 100644
--- a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshModel.java
+++ b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshModel.java
@@ -11,8 +11,28 @@ import java.util.List;
 public class MeshModel {
     private List<MeshFacet> facets = new ArrayList<>();
 
+    /**
+     * Constructor of MeshModel
+     */
+    public MeshModel() {
+
+    }
+
+    /**
+     * Copy constructor of MeshModel
+     *
+     * @param meshModel copied MeshModel
+     */
+    public MeshModel(MeshModel meshModel) {
+        for (MeshFacet facet :
+                meshModel.facets) {
+            facets.add(new MeshFacet(facet));
+        }
+    }
+
     /**
      * returns list of MeshFacets
+     *
      * @return list of MeshFacets
      */
     public List<MeshFacet> getFacets() {
@@ -21,6 +41,7 @@ public class MeshModel {
 
     /**
      * adds new MeshFacet to the model
+     *
      * @param facet new MeshFacet
      */
     public void addFacet(MeshFacet facet) {
diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshPoint.java b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshPoint.java
index 4fdc8d9c212b45c4fdc3606da1dd1dddae138c01..b594f84d5a2c30f6f1304c95f67704edd515ea49 100644
--- a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshPoint.java
+++ b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshPoint.java
@@ -12,13 +12,14 @@ public class MeshPoint {
 
     /**
      * constructor of meshPoint
+     *
      * @param position position of MeshPoint
-     * @param normal normal of MeshPoint
+     * @param normal   normal of MeshPoint
      * @param texCoord coordinates in texture
      */
-    public MeshPoint(Vector3d position, Vector3d normal , Vector3d texCoord) {
-        if (position == null || normal == null || texCoord == null) {
-            throw new NullPointerException("position, normal and texCoord cannot be null");
+    public MeshPoint(Vector3d position, Vector3d normal, Vector3d texCoord) {
+        if (position == null) {
+            throw new NullPointerException("position cannot be null");
         }
 
         this.position = position;
@@ -26,6 +27,17 @@ public class MeshPoint {
         this.texCoord = texCoord;
     }
 
+    /**
+     * copy constructor of meshPoint
+     * @param meshPoint copied meshPoint
+     */
+    public MeshPoint(MeshPoint meshPoint) {
+        this.position = new Vector3d(meshPoint.position);
+        this.normal = new Vector3d(meshPoint.normal);
+        this.texCoord = new Vector3d(meshPoint.texCoord);
+
+    }
+
     /**
      * @return normal
      */
@@ -47,6 +59,96 @@ public class MeshPoint {
         return texCoord;
     }
 
+    /**
+     * returns new instance of MeshPoint with subtracted position
+     *
+     * @param subtrahend position to be subtracted
+     * @return subtracted MeshPoint
+     */
+    public MeshPoint subtractPosition(MeshPoint subtrahend) {
+        return subtractPosition(subtrahend.position);
+    }
+
+    /**
+     * returns new instance of MeshPoint with subtracted position
+     *
+     * @param subtrahend position to be subtracted
+     * @return subtracted MeshPoint
+     */
+    public MeshPoint subtractPosition(Vector3d subtrahend) {
+        Vector3d newPosition = new Vector3d(position);
+        newPosition.sub(subtrahend);
+        return new MeshPoint(new Vector3d(newPosition), normal, new Vector3d(texCoord));
+    }
+
+    /**
+     * returns new instance of MeshPoint with added position
+     *
+     * @param addend position to be added
+     * @return added MeshPoint
+     */
+    public MeshPoint addPosition(MeshPoint addend) {
+        return addPosition(addend.position);
+    }
+
+    /**
+     * returns new instance of MeshPoint with added position
+     *
+     * @param addend position to be added
+     * @return added MeshPoint
+     */
+    public MeshPoint addPosition(Vector3d addend) {
+        Vector3d newPosition = new Vector3d(position);
+        newPosition.add(addend);
+        return new MeshPoint(new Vector3d(newPosition), normal, new Vector3d(texCoord));
+    }
+
+    /**
+     * returns new instance of MeshPoint with subtracted normal
+     *
+     * @param subtrahend normal to be subtracted
+     * @return subtracted MeshPoint
+     */
+    public MeshPoint subtractNormal(MeshPoint subtrahend) {
+        return subtractNormal(subtrahend.normal);
+    }
+
+    /**
+     * returns new instance of MeshPoint with subtracted normal
+     *
+     * @param subtrahend normal to be subtracted
+     * @return subtracted MeshPoint
+     */
+    public MeshPoint subtractNormal(Vector3d subtrahend) {
+        Vector3d newNormal = new Vector3d(normal);
+        newNormal.sub(subtrahend);
+        newNormal.normalize();
+        return new MeshPoint(new Vector3d(position), newNormal, new Vector3d(texCoord));
+    }
+
+    /**
+     * returns new instance of MeshPoint with added normal
+     *
+     * @param addend normal to be added
+     * @return added MeshPoint
+     */
+    public MeshPoint addNormal(MeshPoint addend) {
+        return addNormal(addend.normal);
+    }
+
+    /**
+     * returns new instance of MeshPoint with added normal
+     *
+     * @param addend normal to be added
+     * @return added MeshPoint
+     */
+    public MeshPoint addNormal(Vector3d addend) {
+        Vector3d newNormal = new Vector3d(normal);
+        newNormal.add(addend);
+        newNormal.normalize();
+        return new MeshPoint(new Vector3d(position), newNormal, new Vector3d(texCoord));
+    }
+
     /**
      * @param obj compared object
      * @return true if positions, normals and texture coordinates are equal, false otherwise
@@ -65,6 +167,7 @@ public class MeshPoint {
 
     /**
      * returns hash of MeshPoint
+     *
      * @return hash
      */
     @Override
diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/io/MeshObjLoader.java b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/io/MeshObjLoader.java
index 14737ea1e08fcf6f4fac5b928f40638783021cd4..12ef65c44b81a258c918368b250925240a628e94 100644
--- a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/io/MeshObjLoader.java
+++ b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/io/MeshObjLoader.java
@@ -1,252 +1,251 @@
-package cz.fidentis.analyst.mesh.io;
-
-import com.mokiat.data.front.parser.IOBJParser;
-import com.mokiat.data.front.parser.OBJDataReference;
-import com.mokiat.data.front.parser.OBJFace;
-import com.mokiat.data.front.parser.OBJMesh;
-import com.mokiat.data.front.parser.OBJModel;
-import com.mokiat.data.front.parser.OBJNormal;
-import com.mokiat.data.front.parser.OBJObject;
-import com.mokiat.data.front.parser.OBJParser;
-import com.mokiat.data.front.parser.OBJTexCoord;
-import com.mokiat.data.front.parser.OBJVertex;
-import cz.fidentis.analyst.mesh.core.CornerTableRow;
-import cz.fidentis.analyst.mesh.core.MeshFacet;
-import cz.fidentis.analyst.mesh.core.MeshModel;
-import cz.fidentis.analyst.mesh.core.MeshPoint;
-
-import javax.vecmath.Vector3d;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import javax.vecmath.Vector3d;
-
-
-/**
- * Utility class for loading human face from OBJ data format.
- * Expects only one human face in one file stored as one object.
- * @author Marek Bařinka
- */
-public class MeshObjLoader {
-
-    /**
-     * Opens file and loads data into MeshModel
-     * @param file File containing face to load into a MeshModel
-     * @return Complete MeshModel
-     * @throws FileNotFoundException Requested file was not found
-     * @throws IOException There was problem with reading the file
-     */
-    public static MeshModel read(File file) throws FileNotFoundException, IOException {
-        try (InputStream is = new FileInputStream(file)) {
-            return read(is);
-        }
-    }
-
-    /**
-     * Loads data into MeshModel
-     * @param is Input data stream with model
-     * @return Complete MeshModel
-     * @throws IOException Data are corrupted
-     */
-    public static MeshModel read(InputStream is) throws IOException {
-        final IOBJParser parser = new OBJParser();
-        final OBJModel model = parser.parse(is);
-
-        if (model.getObjects().isEmpty()) {
-            throw new IOException("File doesn't contain any model");
-        }
-        OBJObject object = model.getObjects().get(0);
-        return parseObjectToModel(model, object);
-    }
-
-    /**
-     * Parse OBJObject into MeshModel
-     * @param model Model is needed in future. It's holding data pools
-     * @param object Object to parse. It corespond to our MeshModel
-     * @return Returns complete model
-     * @throws IOException Data are corrupted
-     */
-    private static MeshModel parseObjectToModel(OBJModel model, OBJObject object) throws IOException {
-        MeshModel meshModel = new MeshModel();
-        // Our facet = loader mesh, create and fill all facets
-        for (OBJMesh mesh : object.getMeshes()) {
-            MeshFacet meshFacet = parseMeshToFacet(model, mesh);
-            meshModel.addFacet(meshFacet);
-        }
-        return meshModel;
-    }
-
-    /**
-     * Parse OBJMesh into MeshFacet containig corner table data
-     * @param model Model is needed in future. It's holding data pools
-     * @param mesh Mesh to parse. It corespond to our MeshFacet
-     * @return Returns complete facet
-     * @throws IOException Data are corrupted
-     */
-    private static MeshFacet parseMeshToFacet(OBJModel model, OBJMesh mesh) throws IOException {
-        MeshFacet meshFacet = new MeshFacet();
-        Map<MeshPoint, Integer> vertices = new HashMap();
-        Map<Edge, Integer> edges = new HashMap();
-
-        for (OBJFace face : mesh.getFaces()) {
-            processFace(model, face, meshFacet, vertices, edges);
-        }
-
-        return meshFacet;
-    }
-
-    /**
-     * Process one face in source data into data and insert them into CornerTable
-     * @param model Model is needed in future. It's holding data pools
-     * @param face Face to process
-     * @param meshFacet MeshFacet containing data pools
-     * @param vertices Map containing information about processed vertices
-     *                  and their index in CornerTable
-     * @param edges Map containing edges and index of their opposite vertex
-     * @throws IOException Data are corrupted
-     */
-
-    private static void processFace(OBJModel model, OBJFace face, MeshFacet meshFacet,
-                    Map<MeshPoint, Integer> vertices, Map<Edge, Integer> edges) throws IOException {
-        List<MeshPoint> trianglePoints = parseFaceToTriangle(model, face);
-        List<Integer> vertexIndicies = new ArrayList();
-
-        // This cycle adds integer indices of new mesh points and add them to CornerTable
-        for (MeshPoint vertex : trianglePoints) {
-            Integer vertIndex = vertices.get(vertex);
-            if (vertIndex == null) {
-                int newIndex = meshFacet.getNumberOfVertexes();
-                vertices.put(vertex, newIndex);
-                meshFacet.addVertex(vertex);
-                vertIndex = newIndex;
-            }
-            vertexIndicies.add(vertIndex);
-            CornerTableRow cornerTableRow = new CornerTableRow(vertIndex, -1);
-            meshFacet.getCornerTable().addRow(cornerTableRow);
-        }
-
-        List<Edge> triangleEdges = new ArrayList();
-        triangleEdges.add(new Edge(trianglePoints.get(0).getPosition(),
-                    trianglePoints.get(1).getPosition(), vertexIndicies.get(2)));
-        triangleEdges.add(new Edge(trianglePoints.get(1).getPosition(),
-                    trianglePoints.get(2).getPosition(), vertexIndicies.get(0)));
-        triangleEdges.add(new Edge(trianglePoints.get(2).getPosition(),
-                    trianglePoints.get(0).getPosition(), vertexIndicies.get(1)));
-
-        for (Edge e : triangleEdges) {
-            // We are processing edge which we already found
-            // We can set corner.opposite on both corners
-            if (edges.containsKey(e)) {
-                int oppositeCornerIndex = edges.get(e);
-                meshFacet.getCornerTable().getRow(oppositeCornerIndex).setOppositeCornerIndex(e.getCornerIndex());
-                meshFacet.getCornerTable().getRow(e.getCornerIndex()).setOppositeCornerIndex(oppositeCornerIndex);
-                edges.remove(e);
-            } else {
-                edges.put(e, e.getCornerIndex());
-            }
-        }
-    }
-
-    /**
-     * Parse face from face data into list of MeshPoint
-     * @param model Model contains data pool
-     * @param face Face contains information about actually processed triangle
-     * @return List containing three MeshPoints parsed from face
-     * @throws IOException If face is non-triangular
-     */
-    private static List<MeshPoint> parseFaceToTriangle(OBJModel model, OBJFace face) throws IOException {
-        List<MeshPoint> result = new ArrayList();
-
-        List<OBJDataReference> references = face.getReferences();
-
-        for (OBJDataReference reference : references) {
-            final OBJVertex vertex = model.getVertex(reference);
-            Vector3d coords = new Vector3d(vertex.x, vertex.y, vertex.z);
-            Vector3d norm = null;
-            Vector3d texCoords = null;
-            if (reference.hasNormalIndex()) {
-                final OBJNormal normal = model.getNormal(reference);
-                norm = new Vector3d(normal.x, normal.y, normal.z);
-            }
-            if (reference.hasTexCoordIndex()) {
-                final OBJTexCoord texCoord = model.getTexCoord(reference);
-                texCoords = new Vector3d(texCoord.u, texCoord.v, texCoord.w);
-            }
-            result.add(new MeshPoint(coords, norm, texCoords));
-        }
-        if (result.size() != 3) {
-            throw new IOException("Mesh contains non-triangular face");
-        }
-        return result;
-    }
-
-    /**
-     * Helper class for finding opposite corners
-     * @author Marek Bařinka
-     */
-    private static class Edge {
-
-        private final Vector3d v1;
-        private final Vector3d v2;
-        private final int cornerIndex;
-
-        public Edge(Vector3d v1, Vector3d v2, int cornerIndex) {
-            this.v1 = v1;
-            this.v2 = v2;
-            this.cornerIndex = cornerIndex;
-        }
-
-        /**
-         * Returns new edge containing same vertices with opposite order
-         * and invalid cornerIndex value.
-         * @return Inverted edge in @method(equals) meaning
-         */
-        public Edge getInvertedEdge() {
-            return new Edge(this.v2, this.v1, -1);
-        }
-
-        public int getCornerIndex() {
-            return cornerIndex;
-        }
-
-        /**
-         * Hash code must be generated this way because of @method(equals)
-         * @return hash code of edge
-         */
-        @Override
-        public int hashCode() {
-            int hash = 3;
-            hash += Objects.hashCode(this.v1);
-            hash += Objects.hashCode(this.v2);
-            return hash;
-        }
-
-        /**
-         * Two edges are considered same if they have same vertices.
-         * @param obj Other edge to test
-         * @return true if edges are same with opposite direction
-         */
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (obj == null) {
-                return false;
-            }
-            if (!(obj instanceof Edge)) {
-                return false;
-            }
-            final Edge other = (Edge) obj;
-            return (other.v1.equals(this.v1) && other.v2.equals(this.v2)) || 
-                    (other.v1.equals(this.v2) && other.v2.equals(this.v1));
-        }
-    }
+package cz.fidentis.analyst.mesh.io;
+
+import com.mokiat.data.front.parser.IOBJParser;
+import com.mokiat.data.front.parser.OBJDataReference;
+import com.mokiat.data.front.parser.OBJFace;
+import com.mokiat.data.front.parser.OBJMesh;
+import com.mokiat.data.front.parser.OBJModel;
+import com.mokiat.data.front.parser.OBJNormal;
+import com.mokiat.data.front.parser.OBJObject;
+import com.mokiat.data.front.parser.OBJParser;
+import com.mokiat.data.front.parser.OBJTexCoord;
+import com.mokiat.data.front.parser.OBJVertex;
+import cz.fidentis.analyst.mesh.core.CornerTableRow;
+import cz.fidentis.analyst.mesh.core.MeshFacet;
+import cz.fidentis.analyst.mesh.core.MeshModel;
+import cz.fidentis.analyst.mesh.core.MeshPoint;
+
+import javax.vecmath.Vector3d;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+
+/**
+ * Utility class for loading human face from OBJ data format.
+ * Expects only one human face in one file stored as one object.
+ * @author Marek Bařinka
+ */
+public class MeshObjLoader {
+
+    /**
+     * Opens file and loads data into MeshModel
+     * @param file File containing face to load into a MeshModel
+     * @return Complete MeshModel
+     * @throws FileNotFoundException Requested file was not found
+     * @throws IOException There was problem with reading the file
+     */
+    public static MeshModel read(File file) throws FileNotFoundException, IOException {
+        try (InputStream is = new FileInputStream(file)) {
+            return read(is);
+        }
+    }
+
+    /**
+     * Loads data into MeshModel
+     * @param is Input data stream with model
+     * @return Complete MeshModel
+     * @throws IOException Data are corrupted
+     */
+    public static MeshModel read(InputStream is) throws IOException {
+        final IOBJParser parser = new OBJParser();
+        final OBJModel model = parser.parse(is);
+
+        if (model.getObjects().isEmpty()) {
+            throw new IOException("File doesn't contain any model");
+        }
+        OBJObject object = model.getObjects().get(0);
+        return parseObjectToModel(model, object);
+    }
+
+    /**
+     * Parse OBJObject into MeshModel
+     * @param model Model is needed in future. It's holding data pools
+     * @param object Object to parse. It corespond to our MeshModel
+     * @return Returns complete model
+     * @throws IOException Data are corrupted
+     */
+    private static MeshModel parseObjectToModel(OBJModel model, OBJObject object) throws IOException {
+        MeshModel meshModel = new MeshModel();
+        // Our facet = loader mesh, create and fill all facets
+        for (OBJMesh mesh : object.getMeshes()) {
+            MeshFacet meshFacet = parseMeshToFacet(model, mesh);
+            meshModel.addFacet(meshFacet);
+        }
+        return meshModel;
+    }
+
+    /**
+     * Parse OBJMesh into MeshFacet containig corner table data
+     * @param model Model is needed in future. It's holding data pools
+     * @param mesh Mesh to parse. It corespond to our MeshFacet
+     * @return Returns complete facet
+     * @throws IOException Data are corrupted
+     */
+    private static MeshFacet parseMeshToFacet(OBJModel model, OBJMesh mesh) throws IOException {
+        MeshFacet meshFacet = new MeshFacet();
+        Map<MeshPoint, Integer> vertices = new HashMap();
+        Map<Edge, Integer> edges = new HashMap();
+
+        for (OBJFace face : mesh.getFaces()) {
+            processFace(model, face, meshFacet, vertices, edges);
+        }
+
+        return meshFacet;
+    }
+
+    /**
+     * Process one face in source data into data and insert them into CornerTable
+     * @param model Model is needed in future. It's holding data pools
+     * @param face Face to process
+     * @param meshFacet MeshFacet containing data pools
+     * @param vertices Map containing information about processed vertices
+     *                  and their index in CornerTable
+     * @param edges Map containing edges and index of their opposite vertex
+     * @throws IOException Data are corrupted
+     */
+
+    private static void processFace(OBJModel model, OBJFace face, MeshFacet meshFacet,
+                    Map<MeshPoint, Integer> vertices, Map<Edge, Integer> edges) throws IOException {
+        List<MeshPoint> trianglePoints = parseFaceToTriangle(model, face);
+        List<Integer> vertexIndicies = new ArrayList();
+
+        // This cycle adds integer indices of new mesh points and add them to CornerTable
+        for (MeshPoint vertex : trianglePoints) {
+            Integer vertIndex = vertices.get(vertex);
+            if (vertIndex == null) {
+                int newIndex = meshFacet.getNumberOfVertices();
+                vertices.put(vertex, newIndex);
+                meshFacet.addVertex(vertex);
+                vertIndex = newIndex;
+            }
+            vertexIndicies.add(vertIndex);
+            CornerTableRow cornerTableRow = new CornerTableRow(vertIndex, -1);
+            meshFacet.getCornerTable().addRow(cornerTableRow);
+        }
+
+        List<Edge> triangleEdges = new ArrayList();
+        triangleEdges.add(new Edge(trianglePoints.get(0).getPosition(),
+                    trianglePoints.get(1).getPosition(), vertexIndicies.get(2)));
+        triangleEdges.add(new Edge(trianglePoints.get(1).getPosition(),
+                    trianglePoints.get(2).getPosition(), vertexIndicies.get(0)));
+        triangleEdges.add(new Edge(trianglePoints.get(2).getPosition(),
+                    trianglePoints.get(0).getPosition(), vertexIndicies.get(1)));
+
+        for (Edge e : triangleEdges) {
+            // We are processing edge which we already found
+            // We can set corner.opposite on both corners
+            if (edges.containsKey(e)) {
+                int oppositeCornerIndex = edges.get(e);
+                meshFacet.getCornerTable().getRow(oppositeCornerIndex).setOppositeCornerIndex(e.getCornerIndex());
+                meshFacet.getCornerTable().getRow(e.getCornerIndex()).setOppositeCornerIndex(oppositeCornerIndex);
+                edges.remove(e);
+            } else {
+                edges.put(e, e.getCornerIndex());
+            }
+        }
+    }
+
+    /**
+     * Parse face from face data into list of MeshPoint
+     * @param model Model contains data pool
+     * @param face Face contains information about actually processed triangle
+     * @return List containing three MeshPoints parsed from face
+     * @throws IOException If face is non-triangular
+     */
+    private static List<MeshPoint> parseFaceToTriangle(OBJModel model, OBJFace face) throws IOException {
+        List<MeshPoint> result = new ArrayList();
+
+        List<OBJDataReference> references = face.getReferences();
+
+        for (OBJDataReference reference : references) {
+            final OBJVertex vertex = model.getVertex(reference);
+            Vector3d coords = new Vector3d(vertex.x, vertex.y, vertex.z);
+            Vector3d norm = null;
+            Vector3d texCoords = null;
+            if (reference.hasNormalIndex()) {
+                final OBJNormal normal = model.getNormal(reference);
+                norm = new Vector3d(normal.x, normal.y, normal.z);
+            }
+            if (reference.hasTexCoordIndex()) {
+                final OBJTexCoord texCoord = model.getTexCoord(reference);
+                texCoords = new Vector3d(texCoord.u, texCoord.v, texCoord.w);
+            }
+            result.add(new MeshPoint(coords, norm, texCoords));
+        }
+        if (result.size() != 3) {
+            throw new IOException("Mesh contains non-triangular face");
+        }
+        return result;
+    }
+
+    /**
+     * Helper class for finding opposite corners
+     * @author Marek Bařinka
+     */
+    private static class Edge {
+
+        private final Vector3d v1;
+        private final Vector3d v2;
+        private final int cornerIndex;
+
+        Edge(Vector3d v1, Vector3d v2, int cornerIndex) {
+            this.v1 = v1;
+            this.v2 = v2;
+            this.cornerIndex = cornerIndex;
+        }
+
+        /**
+         * Returns new edge containing same vertices with opposite order
+         * and invalid cornerIndex value.
+         * @return Inverted edge in @method(equals) meaning
+         */
+        public Edge getInvertedEdge() {
+            return new Edge(this.v2, this.v1, -1);
+        }
+
+        public int getCornerIndex() {
+            return cornerIndex;
+        }
+
+        /**
+         * Hash code must be generated this way because of @method(equals)
+         * @return hash code of edge
+         */
+        @Override
+        public int hashCode() {
+            int hash = 3;
+            hash += Objects.hashCode(this.v1);
+            hash += Objects.hashCode(this.v2);
+            return hash;
+        }
+
+        /**
+         * Two edges are considered same if they have same vertices.
+         * @param obj Other edge to test
+         * @return true if edges are same with opposite direction
+         */
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj == null) {
+                return false;
+            }
+            if (!(obj instanceof Edge)) {
+                return false;
+            }
+            final Edge other = (Edge) obj;
+            return (other.v1.equals(this.v1) && other.v2.equals(this.v2)) || 
+                    (other.v1.equals(this.v2) && other.v2.equals(this.v1));
+        }
+    }
 }
\ No newline at end of file
diff --git a/application/src/test/java/cz/fidentis/analyst/mesh/core/CornerTableRowTest.java b/MeshModel/src/test/java/cz/fidentis/analyst/mesh/core/CornerTableRowTest.java
similarity index 62%
rename from application/src/test/java/cz/fidentis/analyst/mesh/core/CornerTableRowTest.java
rename to MeshModel/src/test/java/cz/fidentis/analyst/mesh/core/CornerTableRowTest.java
index f4acd64fb97857cf75b505152e577a8da04b3a5f..3beb127e06ab56af20c0fecfc81df7787245ad9b 100644
--- a/application/src/test/java/cz/fidentis/analyst/mesh/core/CornerTableRowTest.java
+++ b/MeshModel/src/test/java/cz/fidentis/analyst/mesh/core/CornerTableRowTest.java
@@ -1,22 +1,36 @@
 package cz.fidentis.analyst.mesh.core;
 
-import static org.junit.jupiter.api.Assertions.*;
+import org.testng.annotations.Test;
 
+import static org.testng.AssertJUnit.assertEquals;
+
+/**
+ * Unit test for cornerTableRow
+ */
 class CornerTableRowTest {
 
-    @org.junit.jupiter.api.Test
+    /**
+     * unit test for getVertex
+     */
+    @Test
     void getVertexIndex() {
         CornerTableRow row = new CornerTableRow(42, -1);
         assertEquals(42, row.getVertexIndex());
     }
 
-    @org.junit.jupiter.api.Test
+    /**
+     * Unit test for getOppositeCornerIndex
+     */
+    @Test
     void getOppositeCornerIndex() {
         CornerTableRow row = new CornerTableRow(0, 42);
         assertEquals(42, row.getOppositeCornerIndex());
     }
 
-    @org.junit.jupiter.api.Test
+    /**
+     * Unit test for setOppositeCornerIndex
+     */
+    @Test
     void setOppositeCornerIndex() {
         CornerTableRow row = new CornerTableRow(0, 42);
         assertEquals(42, row.getOppositeCornerIndex());
diff --git a/application/src/test/java/cz/fidentis/analyst/mesh/core/CornerTableTest.java b/MeshModel/src/test/java/cz/fidentis/analyst/mesh/core/CornerTableTest.java
similarity index 79%
rename from application/src/test/java/cz/fidentis/analyst/mesh/core/CornerTableTest.java
rename to MeshModel/src/test/java/cz/fidentis/analyst/mesh/core/CornerTableTest.java
index 20a43b9273c11e30fdc15c072b06661f1114e26e..bf6339673ff7d7770b634b13a3abbfd3c3479bbc 100644
--- a/application/src/test/java/cz/fidentis/analyst/mesh/core/CornerTableTest.java
+++ b/MeshModel/src/test/java/cz/fidentis/analyst/mesh/core/CornerTableTest.java
@@ -1,11 +1,18 @@
 package cz.fidentis.analyst.mesh.core;
 
-import org.junit.jupiter.api.Test;
 
-import static org.junit.jupiter.api.Assertions.*;
+import org.testng.annotations.Test;
 
+import static org.testng.AssertJUnit.assertEquals;
+
+/**
+ * Unit tests for CornerTable
+ */
 class CornerTableTest {
 
+    /**
+     * Unit test for getIndexOfFace
+     */
     @Test
     void getIndexOfFace() {
         CornerTable table = new CornerTable();
@@ -18,6 +25,9 @@ class CornerTableTest {
         }
     }
 
+    /**
+     * Unit test for getIndexOfFaceNegativeIndex with negative index
+     */
     @Test
     void getIndexOfFaceNegativeIndex() {
         CornerTable table = new CornerTable();
@@ -25,6 +35,9 @@ class CornerTableTest {
         assertEquals(-2, table.getIndexOfFace(-1));
     }
 
+    /**
+     * Unit test for getIndexOfFaceNegativeIndex with index out of range
+     */
     @Test
     void getIndexOfFaceIndexOutOfRange() {
         CornerTable table = new CornerTable();
@@ -32,6 +45,9 @@ class CornerTableTest {
         assertEquals(-2, table.getIndexOfFace(2));
     }
 
+    /**
+     * Unit test for getIndexOfOppositeCorner
+     */
     @Test
     void getIndexOfOppositeCorner() {
         CornerTable table = new CornerTable();
@@ -44,6 +60,9 @@ class CornerTableTest {
         }
     }
 
+    /**
+     * Unit test for getIndexOfOppositeCorner without opposite corner
+     */
     @Test
     void getIndexOfOppositeCornerNoOppositeCorner() {
         CornerTable table = new CornerTable();
@@ -51,6 +70,9 @@ class CornerTableTest {
         assertEquals(-1, table.getIndexOfOppositeCorner(0));
     }
 
+    /**
+     * Unit test for getIndexOfOppositeCorner with negative index of corner
+     */
     @Test
     void getIndexOfOppositeCornerNegativeIndex() {
         CornerTable table = new CornerTable();
@@ -58,6 +80,9 @@ class CornerTableTest {
         assertEquals(-2, table.getIndexOfOppositeCorner(-1));
     }
 
+    /**
+     * Unit test for getIndexOfOppositeCorner with index of corner out of range
+     */
     @Test
     void getIndexOfOppositeCornerOutOfRange() {
         CornerTable table = new CornerTable();
@@ -65,6 +90,9 @@ class CornerTableTest {
         assertEquals(-2, table.getIndexOfOppositeCorner(2));
     }
 
+    /**
+     * Unit test for getIndexOfNextCornerInFace
+     */
     @Test
     void getIndexOfNextCornerInFaceFirstTriangle() {
         CornerTable table = new CornerTable();
@@ -77,6 +105,9 @@ class CornerTableTest {
         assertEquals(0, table.getIndexOfNextCornerInFace(2));
     }
 
+    /**
+     * Unit test for getIndexOfNextCornerInFace
+     */
     @Test
     void getIndexOfNextCornerInFaceMiddleTriangle() {
         CornerTable table = new CornerTable();
@@ -89,6 +120,9 @@ class CornerTableTest {
         assertEquals(3, table.getIndexOfNextCornerInFace(5));
     }
 
+    /**
+     * Unit test for getIndexOfNextCornerInFace
+     */
     @Test
     void getIndexOfNextCornerInFaceLastTriangle() {
         CornerTable table = new CornerTable();
@@ -101,6 +135,9 @@ class CornerTableTest {
         assertEquals(6, table.getIndexOfNextCornerInFace(8));
     }
 
+    /**
+     * Unit test for getIndexOfNextCornerInFace with negative index of corner
+     */
     @Test
     void getIndexOfNextCornerInFaceNegativeIndex() {
         CornerTable table = new CornerTable();
@@ -108,6 +145,9 @@ class CornerTableTest {
         assertEquals(-2, table.getIndexOfNextCornerInFace(-1));
     }
 
+    /**
+     * Unit test for getIndexOfNextCornerInFace with index of corner out of range
+     */
     @Test
     void getIndexOfNextCornerInFaceOutOfRange() {
         CornerTable table = new CornerTable();
@@ -115,6 +155,9 @@ class CornerTableTest {
         assertEquals(-2, table.getIndexOfNextCornerInFace(2));
     }
 
+    /**
+     * Unit test for getIndexOfPreviousCornerInFace
+     */
     @Test
     void getIndexOfPreviousCornerInFaceFirstTriangle() {
         CornerTable table = new CornerTable();
@@ -127,6 +170,9 @@ class CornerTableTest {
         assertEquals(1, table.getIndexOfPreviousCornerInFace(2));
     }
 
+    /**
+     * Unit test for getIndexOfPreviousCornerInFace
+     */
     @Test
     void getIndexOfPreviousCornerInFaceMiddleTriangle() {
         CornerTable table = new CornerTable();
@@ -139,6 +185,9 @@ class CornerTableTest {
         assertEquals(4, table.getIndexOfPreviousCornerInFace(5));
     }
 
+    /**
+     * Unit test for getIndexOfPreviousCornerInFace
+     */
     @Test
     void getIndexOfPreviousCornerInFaceLastTriangle() {
         CornerTable table = new CornerTable();
@@ -151,6 +200,9 @@ class CornerTableTest {
         assertEquals(7, table.getIndexOfPreviousCornerInFace(8));
     }
 
+    /**
+     * Unit test for getIndexOfPreviousCornerInFace with negative index of corner
+     */
     @Test
     void getIndexOfPreviousCornerInFaceNegativeIndex() {
         CornerTable table = new CornerTable();
@@ -158,6 +210,9 @@ class CornerTableTest {
         assertEquals(-2, table.getIndexOfPreviousCornerInFace(-1));
     }
 
+    /**
+     * Unit test for getIndexOfPreviousCornerInFace with index of corner out of range
+     */
     @Test
     void getIndexOfPreviousCornerInFaceOutOfRange() {
         CornerTable table = new CornerTable();
@@ -165,6 +220,9 @@ class CornerTableTest {
         assertEquals(-2, table.getIndexOfPreviousCornerInFace(2));
     }
 
+    /**
+     * Unit test for getIndexOfTipCornerOnLeft
+     */
     @Test
     void getIndexOfTipCornerOnLeft() {
         CornerTable table = new CornerTable();
@@ -178,6 +236,9 @@ class CornerTableTest {
         assertEquals(5, table.getIndexOfTipCornerOnLeft(0));
     }
 
+    /**
+     * Unit test for getIndexOfTipCornerOnLeft with no left corner
+     */
     @Test
     void getIndexOfTipCornerOnLeftNoLeftCorner() {
         CornerTable table = new CornerTable();
@@ -191,6 +252,9 @@ class CornerTableTest {
         assertEquals(-1, table.getIndexOfTipCornerOnLeft(1));
     }
 
+    /**
+     * Unit test for getIndexOfTipCornerOnLeft with negative index of corner
+     */
     @Test
     void getIndexOfTipCornerOnLeftNegativeIndex() {
         CornerTable table = new CornerTable();
@@ -204,6 +268,9 @@ class CornerTableTest {
         assertEquals(-2, table.getIndexOfTipCornerOnLeft(-1));
     }
 
+    /**
+     * Unit test for getIndexOfTipCornerOnLeft with index of corner out of range
+     */
     @Test
     void getIndexOfTipCornerOnLeftOutOfRange() {
         CornerTable table = new CornerTable();
@@ -217,6 +284,9 @@ class CornerTableTest {
         assertEquals(-2, table.getIndexOfTipCornerOnLeft(6));
     }
 
+    /**
+     * Unit test for getIndexOfTipCornerOnRight
+     */
     @Test
     void getIndexOfTipCornerOnRight() {
         CornerTable table = new CornerTable();
@@ -230,6 +300,9 @@ class CornerTableTest {
         assertEquals(5, table.getIndexOfTipCornerOnRight(1));
     }
 
+    /**
+     * Unit test for getIndexOfTipCornerOnRight with no right corner
+     */
     @Test
     void getIndexOfTipCornerOnLeftNoRightCorner() {
         CornerTable table = new CornerTable();
@@ -243,6 +316,9 @@ class CornerTableTest {
         assertEquals(-1, table.getIndexOfTipCornerOnRight(0));
     }
 
+    /**
+     * Unit test for getIndexOfTipCornerOnRight with negative index of corner
+     */
     @Test
     void getIndexOfTipCornerOnRightNegativeIndex() {
         CornerTable table = new CornerTable();
@@ -256,6 +332,9 @@ class CornerTableTest {
         assertEquals(-2, table.getIndexOfTipCornerOnRight(-1));
     }
 
+    /**
+     * Unit test for getIndexOfTipCornerOnRight with index of corner out of range
+     */
     @Test
     void getIndexOfTipCornerOnRightOutOfRange() {
         CornerTable table = new CornerTable();
@@ -269,7 +348,9 @@ class CornerTableTest {
         assertEquals(-2, table.getIndexOfTipCornerOnLeft(6));
     }
 
-
+    /**
+     * Unit test for getNextAroundCorner
+     */
     @Test
     void getNextAroundCorner() {
         CornerTable table = new CornerTable();
@@ -283,6 +364,9 @@ class CornerTableTest {
         assertEquals(3, table.getNextAroundCorner(0));
     }
 
+    /**
+     * Unit test for getNextAroundCorner with no corner on around position
+     */
     @Test
     void getNextAroundCornerNoAroundCorner() {
         CornerTable table = new CornerTable();
@@ -296,6 +380,9 @@ class CornerTableTest {
         assertEquals(-1, table.getNextAroundCorner(1));
     }
 
+    /**
+     * Unit test for getNextAroundCorner with negative index of corner
+     */
     @Test
     void getNextAroundCornerNegativeIndex() {
         CornerTable table = new CornerTable();
@@ -309,6 +396,9 @@ class CornerTableTest {
         assertEquals(-2, table.getNextAroundCorner(-1));
     }
 
+    /**
+     * Unit test for getNextAroundCorner with index of corner out of range
+     */
     @Test
     void getNextAroundCornerOutOfRange() {
         CornerTable table = new CornerTable();
@@ -322,7 +412,9 @@ class CornerTableTest {
         assertEquals(-2, table.getNextAroundCorner(6));
     }
 
-
+    /**
+     * Unit test for addRow
+     */
     @Test
     void addRow() {
         CornerTable table = new CornerTable();
@@ -331,6 +423,9 @@ class CornerTableTest {
         assertEquals(1, table.getSize());
     }
 
+    /**
+     * Unit test for replaceRow
+     */
     @Test
     void replaceRow() {
         CornerTable table = new CornerTable();
@@ -348,6 +443,9 @@ class CornerTableTest {
         assertEquals(42, table.getRow(1).getOppositeCornerIndex());
     }
 
+    /**
+     * Unit test for getSize
+     */
     @Test
     void getSize() {
         CornerTable table = new CornerTable();
@@ -361,6 +459,9 @@ class CornerTableTest {
         assertEquals(9, table.getSize());
     }
 
+    /**
+     * Unit test for getRow
+     */
     @Test
     void getRow() {
         CornerTable table = new CornerTable();
diff --git a/application/FIDENTIS-Analyst-app.iml b/application/FIDENTIS-Analyst-app.iml
new file mode 100644
index 0000000000000000000000000000000000000000..29d467275709a7d720f2250b86584c2fd515ef97
--- /dev/null
+++ b/application/FIDENTIS-Analyst-app.iml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_9">
+    <output url="file://$MODULE_DIR$/target/classes" />
+    <output-test url="file://$MODULE_DIR$/target/test-classes" />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
+      <excludeFolder url="file://$MODULE_DIR$/target" />
+    </content>
+    <content url="file://$MODULE_DIR$/src/test/java" />
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$APPLICATION_HOME_DIR$/lib/groovy-all-2.4.17.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES />
+      </library>
+    </orderEntry>
+    <orderEntry type="library" name="Maven: org.netbeans.external:asm-all-5.0.1:RELEASE82" level="project" />
+    <orderEntry type="library" name="Maven: org.netbeans.external:net-java-html-boot-fx:RELEASE82" level="project" />
+    <orderEntry type="library" name="Maven: org.netbeans.external:net-java-html-boot-script:RELEASE82" level="project" />
+    <orderEntry type="library" name="Maven: org.netbeans.external:net-java-html-boot:RELEASE82" level="project" />
+    <orderEntry type="library" name="Maven: org.netbeans.external:net-java-html-geo:RELEASE82" level="project" />
+    <orderEntry type="library" name="Maven: org.netbeans.external:net-java-html-json:RELEASE82" level="project" />
+    <orderEntry type="library" name="Maven: org.netbeans.external:net-java-html-sound:RELEASE82" level="project" />
+    <orderEntry type="library" name="Maven: org.netbeans.external:net-java-html:RELEASE82" level="project" />
+    <orderEntry type="library" name="Maven: org.netbeans.external:org-netbeans-html-ko4j:RELEASE82" level="project" />
+    <orderEntry type="library" name="Maven: org.netbeans.external:org-netbeans-html-xhr4j:RELEASE82" level="project" />
+    <orderEntry type="module" module-name="FIDENTIS-Analyst-branding" />
+    <orderEntry type="library" name="Maven: org.netbeans.api:org-netbeans-api-annotations-common:RELEASE82" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.netbeans.api:org-netbeans-modules-nbjunit:RELEASE113" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.netbeans.modules:org-netbeans-insane:RELEASE113" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.netbeans.api:org-netbeans-libs-junit4:RELEASE113" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
+    <orderEntry type="module" module-name="MeshModel" />
+    <orderEntry type="library" name="Maven: java3d:j3d-core-utils:1.3.1" level="project" />
+    <orderEntry type="library" name="Maven: java3d:vecmath:1.3.1" level="project" />
+    <orderEntry type="library" name="Maven: java3d:j3d-core:1.3.1" level="project" />
+    <orderEntry type="library" name="Maven: com.github.mokiat:java-data-front:v2.0.0" level="project" />
+    <orderEntry type="library" name="Maven: javax.vecmath:vecmath:1.5.2" level="project" />
+    <orderEntry type="module" module-name="Renderer" />
+    <orderEntry type="library" name="Maven: cz.findetis:GUI:2.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-api:5.6.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.apiguardian:apiguardian-api:1.1.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.opentest4j:opentest4j:1.2.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.junit.platform:junit-platform-commons:1.6.0" level="project" />
+  </component>
+</module>
\ No newline at end of file
diff --git a/application/pom.xml b/application/pom.xml
index b698ed85ec1a87a255d6aba88527d725d7416d4b..7748a6cc640dd291354e1fbb2c4f04fcf75b7106 100644
--- a/application/pom.xml
+++ b/application/pom.xml
@@ -30,7 +30,7 @@
             <artifactId>FIDENTIS-Analyst-branding</artifactId>
             <version>${project.version}</version>
         </dependency>
-        <!-- NbModuleSuite functional in RELEASE70 or later: -->
+        <!-- https://mvnrepository.com/artifact/org.netbeans.api/org-netbeans-modules-nbjunit -->
         <dependency>
             <groupId>org.netbeans.api</groupId>
             <artifactId>org-netbeans-modules-nbjunit</artifactId>
@@ -86,6 +86,14 @@
                     </systemPropertyVariables>
                 </configuration>
             </plugin>
+            <!-- <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>9</source>
+                    <target>9</target>
+                </configuration>
+            </plugin> -->
         </plugins>
     </build>