diff --git a/MeshModel/pom.xml b/MeshModel/pom.xml
index 17bde7f5f34acefeef53960c99859ab70b7b39ae..ef16df962e16f7cb68cad78f94dddaf5296c9749 100644
--- a/MeshModel/pom.xml
+++ b/MeshModel/pom.xml
@@ -106,6 +106,11 @@
             <version>7.1.0</version>
             <scope>test</scope>
         </dependency>-->
+        <dependency>
+            <groupId>com.opencsv</groupId>
+            <artifactId>opencsv</artifactId>
+            <version>5.3</version>
+        </dependency>
     </dependencies>
     <properties>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/feature/FeaturePoint.java b/MeshModel/src/main/java/cz/fidentis/analyst/feature/FeaturePoint.java
new file mode 100644
index 0000000000000000000000000000000000000000..1b4a6a4c557a650cd041c7a2392afcdb24e56cac
--- /dev/null
+++ b/MeshModel/src/main/java/cz/fidentis/analyst/feature/FeaturePoint.java
@@ -0,0 +1,41 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package cz.fidentis.analyst.feature;
+
+/**
+ *
+ * @author kubok
+ */
+public class FeaturePoint {
+
+    private final double X;
+    private final double Y;
+    private final double Z;
+    private final FeaturePointType FEATURE_POINT_TYPE;
+
+    public FeaturePoint(double x, double y, double z, FeaturePointType featurePointType) {
+        this.X = x;
+        this.Y = y;
+        this.Z = z;
+        this.FEATURE_POINT_TYPE = featurePointType;
+    }
+
+    public double getX() {
+        return X;
+    }
+
+    public double getY() {
+        return Y;
+    }
+
+    public double getZ() {
+        return Z;
+    }
+
+    public FeaturePointType getFeaturePointType() {
+        return FEATURE_POINT_TYPE;
+    }
+}
diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/feature/FeaturePointType.java b/MeshModel/src/main/java/cz/fidentis/analyst/feature/FeaturePointType.java
new file mode 100644
index 0000000000000000000000000000000000000000..1c3b71a30c9e030056f02b90e700fc18d11c5fc2
--- /dev/null
+++ b/MeshModel/src/main/java/cz/fidentis/analyst/feature/FeaturePointType.java
@@ -0,0 +1,35 @@
+package cz.fidentis.analyst.feature;
+
+public class FeaturePointType {
+    private final int type;
+    private final String name;
+    private final String info;
+    private final String code;
+
+    public FeaturePointType(
+            int type,
+             String name,
+             String info,
+             String code) {
+        this.type = type;
+        this.name = name;
+        this.info = info;
+        this.code = code;
+    }
+
+    public int getType() {
+        return type;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getInfo() {
+        return info;
+    }
+
+    public String getCode() {
+        return code;
+    }
+}
diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/feature/exception/FeaturePointException.java b/MeshModel/src/main/java/cz/fidentis/analyst/feature/exception/FeaturePointException.java
new file mode 100644
index 0000000000000000000000000000000000000000..a7330475150a8b3e73349fada2f812ba1c717852
--- /dev/null
+++ b/MeshModel/src/main/java/cz/fidentis/analyst/feature/exception/FeaturePointException.java
@@ -0,0 +1,18 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package cz.fidentis.analyst.feature.exception;
+
+/**
+ *
+ * @author kubok
+ */
+public class FeaturePointException extends RuntimeException {
+    
+    public FeaturePointException(String message) {
+        super(message);
+    }
+    
+}
diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/feature/provider/FeaturePointTypeProvider.java b/MeshModel/src/main/java/cz/fidentis/analyst/feature/provider/FeaturePointTypeProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..4b15f1fbbef1c136b9bc226b60d39de7423b44d7
--- /dev/null
+++ b/MeshModel/src/main/java/cz/fidentis/analyst/feature/provider/FeaturePointTypeProvider.java
@@ -0,0 +1,58 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package cz.fidentis.analyst.feature.provider;
+
+import cz.fidentis.analyst.feature.FeaturePointType;
+import cz.fidentis.analyst.feature.services.FeaturePointTypesService;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ *
+ * @author kubok
+ */
+public class FeaturePointTypeProvider {
+
+    private final Map<Integer, FeaturePointType> featurePointTypesById;
+    private final Map<String, FeaturePointType> featurePointTypesByCode;
+    
+    // provide thread safe singleton
+    private static class InstanceHolder {
+
+        public static FeaturePointTypeProvider instance = new FeaturePointTypeProvider();
+    }
+
+    private FeaturePointTypeProvider() {
+        FeaturePointTypesService service = new FeaturePointTypesService();
+        featurePointTypesById = service.readResources().orElse(new HashMap<>());
+        featurePointTypesByCode = service.getFeaturepointTypesByCode(featurePointTypesById);
+    }
+
+    /**
+     * Access feature point types
+     * @return 
+     */
+    public static FeaturePointTypeProvider getInstance() {
+        return InstanceHolder.instance;
+    }
+
+    public Map<Integer, FeaturePointType> getFeaturePointTypesById() {
+        return featurePointTypesById;
+    }
+
+    public Map<String, FeaturePointType> getFeaturePointTypesByCode() {
+        return featurePointTypesByCode;
+    }
+
+    /**
+     * Get feature point by code
+     * @param code
+     * @return 
+     */
+    public FeaturePointType getFeaturePointTypeByCode(String code) {
+        return getFeaturePointTypesByCode().get(code);
+    }
+}
diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/feature/services/FeaturePointImportExportService.java b/MeshModel/src/main/java/cz/fidentis/analyst/feature/services/FeaturePointImportExportService.java
new file mode 100644
index 0000000000000000000000000000000000000000..8452e8c0966bb81024f955d3ed9206f2e397686d
--- /dev/null
+++ b/MeshModel/src/main/java/cz/fidentis/analyst/feature/services/FeaturePointImportExportService.java
@@ -0,0 +1,113 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package cz.fidentis.analyst.feature.services;
+
+import cz.fidentis.analyst.feature.FeaturePoint;
+import cz.fidentis.analyst.feature.exception.FeaturePointException;
+import cz.fidentis.analyst.feature.provider.FeaturePointTypeProvider;
+import cz.fidentis.analyst.feature.utils.FileResourcesUtils;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.stream.Stream;
+
+/**
+ *
+ * @author kubok
+ */
+public class FeaturePointImportExportService {
+
+    private static final String COLUMN_DELIMETER = ",";
+    private static final String CODE_PREFIX_DELIMETER = " ";
+
+    public Optional<List<FeaturePoint>> importFeaturePoints(String path, String fileName) {
+        FileResourcesUtils app = new FileResourcesUtils();
+        try (InputStreamReader streamReader
+                = new InputStreamReader(app.getFileAsStream(path, fileName), StandardCharsets.UTF_8);
+                BufferedReader reader = new BufferedReader(streamReader)) {
+
+            Stream<String> lines = reader.lines();
+            List<List<String>> linesList = new ArrayList<>();
+
+            lines
+                    .forEach(line -> {
+                        linesList.add(Arrays.asList(line.split(COLUMN_DELIMETER)));
+                    });
+
+            if (linesList.size() != 2
+                    || linesList.get(0).size() != linesList.get(1).size()) {
+                throw new FeaturePointException(String.format("Feature point import file '%s' has wrong format", fileName));
+            }
+
+            List<FeaturePoint> points = new ArrayList<>();
+            for (int i = 1; i < linesList.get(0).size(); i += 3) {
+                FeaturePoint point = new FeaturePoint(
+                        Double.parseDouble(linesList.get(1).get(i)),
+                        Double.parseDouble(linesList.get(1).get(i + 1)),
+                        Double.parseDouble(linesList.get(1).get(i + 2)),
+                        FeaturePointTypeProvider.getInstance().getFeaturePointTypeByCode(
+                                getCode(linesList.get(0).get(i)))
+                );
+                points.add(point);
+            }
+            return Optional.of(points);
+
+        } catch (IOException e) {
+            throw new FeaturePointException(String.format("Feature point cannot open file", fileName));
+        } catch (NumberFormatException e1) {
+            throw new FeaturePointException(e1.getMessage());
+        }
+    }
+
+    private String getCode(String str) {
+        return str.substring(0, str.indexOf(CODE_PREFIX_DELIMETER));
+    }
+
+    public void exportFeaturePoints(List<FeaturePoint> featurePointList, String objectName) throws FileNotFoundException, IOException {
+        File csvOutputFile = new File(String.format("%s_landmarks.csv", objectName));
+        // CSV is a normal text file, need a writer
+        try (BufferedWriter bw = new BufferedWriter(new FileWriter(csvOutputFile))) {
+            bw.write("Scan name");
+            featurePointList.forEach(featurePoint -> {
+                try {
+                    bw.write(String.format(",%s x", featurePoint.getFeaturePointType().getCode()));
+                    bw.write(String.format(",%s y", featurePoint.getFeaturePointType().getCode()));
+                    bw.write(String.format(",%s z", featurePoint.getFeaturePointType().getCode()));
+                } catch (IOException ex) {
+                    Logger.getLogger(FeaturePointImportExportService.class.getName()).log(Level.SEVERE, null, ex);
+                }
+            });
+            bw.newLine();
+            bw.write(String.format("%s", objectName));
+            featurePointList.forEach(featurePoint -> {
+                try {
+                    bw.write(",");
+                    bw.write(Double.toString(featurePoint.getX()));
+                    bw.write(",");
+                    bw.write(Double.toString(featurePoint.getY()));
+                    bw.write(",");
+                    bw.write(Double.toString(featurePoint.getZ()));
+                } catch (IOException ex) {
+                    Logger.getLogger(FeaturePointImportExportService.class.getName()).log(Level.SEVERE, null, ex);
+                }
+            });
+        }
+    }
+
+}
diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/feature/services/FeaturePointTypesService.java b/MeshModel/src/main/java/cz/fidentis/analyst/feature/services/FeaturePointTypesService.java
new file mode 100644
index 0000000000000000000000000000000000000000..87dd5beb5b949972b62637af94c6f05a193a9295
--- /dev/null
+++ b/MeshModel/src/main/java/cz/fidentis/analyst/feature/services/FeaturePointTypesService.java
@@ -0,0 +1,63 @@
+package cz.fidentis.analyst.feature.services;
+
+import cz.fidentis.analyst.feature.FeaturePointType;
+import cz.fidentis.analyst.feature.utils.FileResourcesUtils;
+
+import java.io.*;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Scanner;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+public class FeaturePointTypesService {
+
+    private static final String FILE_NAME = "fp_text_default.csv";
+    private static final String DELIMETER = ";";
+
+    /**
+     * Creates map of feature point types from fp_text_default.csv stored in resources
+     * @return Optional map of feature point types mapped by id
+     */
+    public Optional<Map<Integer, FeaturePointType>> readResources() {
+        try (InputStreamReader streamReader =
+                     new InputStreamReader(getInputStream(FILE_NAME), StandardCharsets.UTF_8);
+             BufferedReader reader = new BufferedReader(streamReader)) {
+
+            Stream<String> lines = reader.lines();
+            Map<Integer, FeaturePointType> featurePointTypes = lines
+                .skip(1)
+                .map(line -> {
+                    Scanner lineScanner = new Scanner(line);
+                    lineScanner.useDelimiter(DELIMETER);
+
+                    FeaturePointType featurePointType = new FeaturePointType(lineScanner.nextInt(), lineScanner.next(), lineScanner.next(), lineScanner.next());
+                    return featurePointType;
+                })
+                .collect(Collectors.toMap(FeaturePointType::getType,  Function.identity()));
+            return Optional.of(featurePointTypes);
+
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return Optional.empty();
+    }
+
+    /**
+     * Creates map of feature point types
+     * @return Optional map of feature point types mapped by code
+     */
+    public Map<String, FeaturePointType> getFeaturepointTypesByCode(Map<Integer, FeaturePointType> featurePointTypes) {
+        return featurePointTypes.values()
+                .stream()
+                .collect(Collectors.toMap(FeaturePointType::getCode,  Function.identity()));
+    }
+
+    private InputStream getInputStream(String fileName) {
+        FileResourcesUtils app = new FileResourcesUtils();
+        return app.getFileFromResourceAsStream(fileName);
+    }
+}
diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/feature/utils/FileResourcesUtils.java b/MeshModel/src/main/java/cz/fidentis/analyst/feature/utils/FileResourcesUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..119a17225d3103c0dcd014d8147219961a6bccc3
--- /dev/null
+++ b/MeshModel/src/main/java/cz/fidentis/analyst/feature/utils/FileResourcesUtils.java
@@ -0,0 +1,105 @@
+package cz.fidentis.analyst.feature.utils;
+
+import java.io.*;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.util.List;
+
+public class FileResourcesUtils {
+
+    public static void main(String[] args) throws IOException, URISyntaxException {
+
+        FileResourcesUtils app = new FileResourcesUtils();
+
+        //String fileName = "database.properties";
+        String fileName = "json/file1.json";
+
+        System.out.println("getResourceAsStream : " + fileName);
+        InputStream is = app.getFileFromResourceAsStream(fileName);
+        printInputStream(is);
+
+        System.out.println("\ngetResource : " + fileName);
+        File file = app.getFileFromResource(fileName);
+        printFile(file);
+
+    }
+
+    // get a file from the resources folder
+    // works everywhere, IDEA, unit test and JAR file.
+    public InputStream getFileFromResourceAsStream(String fileName) {
+
+        // The class loader that loaded the class
+        ClassLoader classLoader = getClass().getClassLoader();
+        InputStream inputStream = classLoader.getResourceAsStream(fileName);
+
+        // the stream holding the file content
+        if (inputStream == null) {
+            throw new IllegalArgumentException("file not found! " + fileName);
+        } else {
+            return inputStream;
+        }
+
+    }
+
+    /*
+        The resource URL is not working in the JAR
+        If we try to access a file that is inside a JAR,
+        It throws NoSuchFileException (linux), InvalidPathException (Windows)
+
+        Resource URL Sample: file:java-io.jar!/json/file1.json
+     */
+    private File getFileFromResource(String fileName) throws URISyntaxException {
+
+        ClassLoader classLoader = getClass().getClassLoader();
+        URL resource = classLoader.getResource(fileName);
+        if (resource == null) {
+            throw new IllegalArgumentException("file not found! " + fileName);
+        } else {
+
+            // failed if files have whitespaces or special characters
+            //return new File(resource.getFile());
+            return new File(resource.toURI());
+        }
+
+    }
+
+    // get a file from the resources folder
+    // works everywhere, IDEA, unit test and JAR file.
+    public InputStream getFileAsStream(String path, String fileName) throws FileNotFoundException {
+        return new FileInputStream(getFile(path, fileName));
+    }
+
+    private File getFile(String path, String fileName) {
+        return new File(path, fileName);
+    }
+
+    // print input stream
+    private static void printInputStream(InputStream is) {
+        try (InputStreamReader streamReader
+                = new InputStreamReader(is, StandardCharsets.UTF_8);
+                BufferedReader reader = new BufferedReader(streamReader)) {
+            String line;
+            while ((line = reader.readLine()) != null) {
+                System.out.println(line);
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+    }
+
+    // print a file
+    private static void printFile(File file) {
+        List<String> lines;
+        try {
+            lines = Files.readAllLines(file.toPath(), StandardCharsets.UTF_8);
+            lines.forEach(System.out::println);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+}
diff --git a/MeshModel/src/main/resources/fp_text_default.csv b/MeshModel/src/main/resources/fp_text_default.csv
new file mode 100644
index 0000000000000000000000000000000000000000..1b86ec7acadaed9e263ec2651280618ffb63ffb4
--- /dev/null
+++ b/MeshModel/src/main/resources/fp_text_default.csv
@@ -0,0 +1,62 @@
+Type;Name;Info;Acronym
+1;Exocanthion R;The point at the outer commissure of the eye where the outer margin of the upper eyelid meets the lower eyelid. If the precise spot cannot be found then the location is in the intersection of imaginary lines obtained by prolonging the eyelid margins. The point is bilateral.;EX_R
+2;Exocanthion L;The point at the outer commissure of the eye where the outer margin of the upper eyelid meets the lower eyelid. If the precise spot cannot be found then the location is in the intersection of imaginary lines obtained by prolonging the eyelid margins. The point is bilateral.;EX_L
+3;Endocanthion R;The point at the inner commissure of the eye where the inner margin of the upper eyelid meets the lower eyelid. It is the most medial point at the lacrimal caruncle. In case a skin fold is present (epicanthus, plica mongolica, plica marginalis fetis) and the point is not visible, by Kolar and Salter’s recommendations (1997) the landmark is defined as the point where the fold crosses the lower eyelid. In this case the points are not homologous. The point is bilateral.;EN_R
+4;Endocanthion L;The point at the inner commissure of the eye where the inner margin of the upper eyelid meets the lower eyelid. It is the most medial point at the lacrimal caruncle. In case a skin fold is present (epicanthus, plica mongolica, plica marginalis fetis) and the point is not visible, by Kolar and Salter’s recommendations (1997) the landmark is defined as the point where the fold crosses the lower eyelid. In this case the points are not homologous. The point is bilateral.;EN_L
+5;Palpebra superior R;The point which is located at the intersection of a line going through the eye center (parallel to the mid-sagittal plane) and the caudal (lower) margin of the upper eyelid. The eye center is defined as the half distance between exocanthion and endocanthion. Together with the palpebra inferior point the landmark determines the eye height. The point is bilateral.;PAS_R
+6;Palpebra superior L;The point which is located at the intersection of a line going through the eye center (parallel to the mid-sagittal plane) and the caudal (lower) margin of the upper eyelid. The eye center is defined as the half distance between exocanthion and endocanthion. Together with the palpebra inferior point the landmark determines the eye height. The point is bilateral.;PAS_L
+7;Palpebra inferior R;The point which is located at the intersection of a line going through the eye center (parallel to the mid-sagittal plane) and the upper margin of the lower eyelid. Together with the palpebra superior point the landmark determines the eye height. The point is bilateral.;PAI_R
+8;Palpebra inferior L;The point which is located at the intersection of a line going through the eye center (parallel to the mid-sagittal plane) and the upper margin of the lower eyelid. Together with the palpebra superior point the landmark determines the eye height. The point is bilateral.;PAI_L
+9;Glabella;The outermost midline point between the eyebrows.;G
+10;Subnasale;The lowest posterior midline point at the angle formed by the outline of nasal septum and upper lip.;SN
+11;Alare R;The most lateral anterior point of wing of the nose. The point is bilateral.;AL_R
+12;Alare L;The most lateral anterior point of wing of the nose. The point is bilateral.;AL_L
+13;Nasion;The point in the midline on the nasal root, the deepest point of the nasal root.;N
+14;Pronasale;The most anterior midline point of the nasal tip with the head positioned in the Frankfurt horizontal plane. If the nasal tip is bifid the point is located in the mid-sagittal plane between the elevations.;PRN
+15;Labrale superius;The midpoint of the upper vermilion line. From lateral view this point is mostly covered by other parts of the lips. In case of bow-shaped upper vermilion the point is located in the mid-distance between cheilion points. (by Farkas 1994, modified);LS
+16;Stomion;The point located at the intersection of the closed mouth fissure and the midline. If the mouth is open the point is localized at the lower margin of the upper lip.;STO
+17;Labrale inferius;The most anterior midline point at the lower margin of lower vermilion. (by Fetter 1967, modified);LI
+18;Cheilion R;The point located at the labial commissure. The point is bilateral.;CH_R
+19;Cheilion L;The point located at the labial commissure. The point is bilateral.;CH_L
+20;Crista philtri R;The point located at the place where the line, which is going through the highest margins of the upper vermilion, meets the lower margin of crista philtri. The point is bilateral.;CP_R
+21;Crista philtri L;The point located at the place where the line, which is going through the highest margins of the upper vermilion, meets the lower margin of crista philtri. The point is bilateral.;CP_L
+22;Sublabiale;The midpoint of the mentolabial sulcus (the ridge between the chin and the lower lip, not the vermilion). The point is located at the flexion point of the concavity.;SL
+23;Gnathion;The most anterior inferior point located in the midline at the lower margin of the mandible.;GN
+24;Gonion I R;The lateral inferior point located at the mandibular angle. The point is bilateral. (Digitized on texture-less 3D models);GOL_R
+25;Gonion I L;The lateral inferior point located at the mandibular angle. The point is bilateral. (Digitized on texture-less 3D models);GOL_L
+26;Zygion II R;The most lateral point of the face located on line running through the two eye centers. From lateral view the point is located at the extension to the posterior eyebrow margin (alternatively, at the eyebrow margin). The eye centers are defined as intersection of line connecting exo/endocanthion and of palpebra superior/inferior. The point is bilateral.;ZY_R
+27;Zygion II L;The most lateral point of the face located on line running through the two eye centers. From lateral view the point is located at the extension to the posterior eyebrow margin (alternatively, at the eyebrow margin). The eye centers are defined as intersection of line connecting exo/endocanthion and of palpebra superior/inferior. The point is bilateral.;ZY_L
+28;Pogonion;The most anterior midline point located at the chin with the head positioned in the Frankfurt horizontal plane.;PG
+29;Tragion R;The point located at the upper margin of tragus in the little notch where the cartilage is attached with the head positioned in the Frankfurt horizontal place. The point is bilateral.;T_R
+30;Tragion L;The point located at the upper margin of tragus in the little notch where the cartilage is attached with the head positioned in the Frankfurt horizontal place. The point is bilateral.;T_L
+31;Superaurale R;The most superior point located at the upper margin of the auricle with the head positioned in the Frankfurt horizontal plane. The point is bilateral.;SA_R
+32;Superaurale L;The most superior point located at the upper margin of the auricle with the head positioned in the Frankfurt horizontal plane. The point is bilateral.;SA_L
+33;Subaurale R;"The most inferior point located at the lower margin of the earlobe with the head positioned in the Frankfurt horizontal plane. If the ""attached earlobe"" appearance is present the point is identical to the Otobasion inferius point. The point is bilateral.";SBA_R
+34;Subaurale L;"The most inferior point located at the lower margin of the earlobe with the head positioned in the Frankfurt horizontal plane. If the ""attached earlobe"" appearance is present the point is identical to the Otobasion inferius point. The point is bilateral.";SBA_L
+35;Postaurale R;The most posterior point of the posterior margin of the auricle (when the head is positioned in the Frankfurt horizontal plane). The point is bilateral.;PA_R
+36;Postaurale L;The most posterior point of the posterior margin of the auricle (when the head is positioned in the Frankfurt horizontal plane). The point is bilateral.;PA_L
+37;Otobasion superius R;The point where the upper margin of the auricle attaches to the head. The point is bilateral.;OBS_R
+38;Otobasion superius L;The point where the upper margin of the auricle attaches to the head. The point is bilateral.;OBS_L
+39;Otobasion inferius R;The point where the earlobe attaches to the cheek skin (lower attachment). The point is bilateral.;OBI_R
+40;Otobasion inferius L;The point where the earlobe attaches to the cheek skin (lower attachment). The point is bilateral.;OBI_L
+41;Praeaurale R;The point at the intersection of the line between Otobasion superius and Otobasion inferius points, at the level of the Postaurale point. The point is bilateral.;PRA_R
+42;Praeaurale L;The point at the intersection of the line between Otobasion superius and Otobasion inferius points, at the level of the Postaurale point. The point is bilateral.;PRA_L
+43;Pupila R;No information;PUP_R
+44;Pupila L;No information;PUP_L
+45;Gnathion;No information;GNA
+46;Gonion II R;No information;GO2_R
+47;Gonion II L;No information;GO2_L
+48;Vertex;No information;V
+49;Ophryon;No information;O
+50;Radix nasi R;No information;RN_R
+51;Radix nasi L;No information;RN_L
+52;Euryon II R;No information;EU2_R
+53;Euryon II L;No information;EU2_L
+54;Ramus mandibulae R;No information;RM_R
+55;Ramus mandibulae L;No information;RM_L
+56;P_L;No information;P_L
+57;P_R;No information;P_R
+58;Supercilium Lateralis R;No information;SUL_R
+59;Supercilium Lateralis L;No information;SUL_L
+60;Supercilium Medialis R;No information;SUM_R
+61;Supercilium Medialis L;No information;SUM_L
diff --git a/MeshModel/src/test/java/cz/fidentis/analyst/feature/services/FeaturePointImportExportServiceTest.java b/MeshModel/src/test/java/cz/fidentis/analyst/feature/services/FeaturePointImportExportServiceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..5cc52b9af135739f8a61eba0aeda60c7af29bd46
--- /dev/null
+++ b/MeshModel/src/test/java/cz/fidentis/analyst/feature/services/FeaturePointImportExportServiceTest.java
@@ -0,0 +1,66 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package cz.fidentis.analyst.feature.services;
+
+import cz.fidentis.analyst.feature.FeaturePoint;
+import cz.fidentis.analyst.feature.provider.FeaturePointTypeProvider;
+import cz.fidentis.analyst.mesh.io.MeshObjLoader;
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+import java.util.Optional;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.DisplayName;
+
+/**
+ *
+ * @author Jakub Kolman
+ */
+public class FeaturePointImportExportServiceTest {
+    
+    
+    private static final Path testFileDirectory = Paths.get("src", "test", "resources", "cz", "fidentis", "analyst", "feature", "services");
+    private static final String TEST_CSV_FILE = "00007_01_landmarks.csv";
+     
+    @Test()
+    void fileExistsTest() throws IOException {
+        File testCsv = new File(testFileDirectory.toFile(), TEST_CSV_FILE);
+        assertTrue(testCsv.canRead());
+    }
+    
+    @DisplayName("Test loading a CSV file")
+    @Test
+    void importFeaturePointsTest() {
+        Optional<List<FeaturePoint>> featurePoints = loadFeaturePoints();
+        assertTrue(featurePoints.isPresent());
+        assertTrue(featurePoints.get().size() > 0);
+        assertTrue(featurePoints.get().get(0).getX() == -45.3298
+                && featurePoints.get().get(0).getY() == 37.1466
+                && featurePoints.get().get(0).getZ() == -40.5415
+                && featurePoints.get().get(0).getFeaturePointType().equals(
+                        FeaturePointTypeProvider.getInstance().getFeaturePointTypeByCode("EX_R"))
+        );
+    }
+    
+   @DisplayName("Test writing a CSV file")
+    @Test
+    void exportFeaturePointsTest() throws IOException {
+        FeaturePointImportExportService service = new FeaturePointImportExportService();
+        Optional<List<FeaturePoint>> featurePoints = loadFeaturePoints();
+        service.exportFeaturePoints(featurePoints.get(), "test_file");
+    }
+
+    private Optional<List<FeaturePoint>> loadFeaturePoints() {
+        FeaturePointImportExportService service = new FeaturePointImportExportService();
+        Optional<List<FeaturePoint>> featurePoints = service.importFeaturePoints(testFileDirectory.toString(), TEST_CSV_FILE);
+        return featurePoints;
+
+    }
+}
diff --git a/MeshModel/src/test/java/cz/fidentis/analyst/feature/services/FeaturePointTypeTypesServiceTest.java b/MeshModel/src/test/java/cz/fidentis/analyst/feature/services/FeaturePointTypeTypesServiceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..f0ff92a21ede396415679c54d4ff4cefdd9ce501
--- /dev/null
+++ b/MeshModel/src/test/java/cz/fidentis/analyst/feature/services/FeaturePointTypeTypesServiceTest.java
@@ -0,0 +1,29 @@
+package cz.fidentis.analyst.feature.services;
+
+import cz.fidentis.analyst.feature.FeaturePointType;
+import cz.fidentis.analyst.feature.services.FeaturePointTypesService;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class FeaturePointTypeTypesServiceTest {
+
+    @DisplayName("Test loading a CSV file")
+    @Test
+    void readResourcesTest() {
+
+        FeaturePointTypesService service = new FeaturePointTypesService();
+        Optional<Map<Integer, FeaturePointType>> featurePointTypes = service.readResources();
+        assertTrue(featurePointTypes.isPresent());
+        assertTrue(featurePointTypes.get().size() > 0);
+        assertTrue(featurePointTypes.get().get(1).getType() == 1
+                && featurePointTypes.get().get(1).getName().equals("Exocanthion R")
+                && featurePointTypes.get().get(1).getCode().equals("EX_R"));
+    }
+
+}
\ No newline at end of file
diff --git a/MeshModel/src/test/resources/cz/fidentis/analyst/feature/services/00007_01_landmarks.csv b/MeshModel/src/test/resources/cz/fidentis/analyst/feature/services/00007_01_landmarks.csv
new file mode 100644
index 0000000000000000000000000000000000000000..699435b708d3a63b53b34b888c108720dc311628
--- /dev/null
+++ b/MeshModel/src/test/resources/cz/fidentis/analyst/feature/services/00007_01_landmarks.csv
@@ -0,0 +1,2 @@
+Scan name,EX_R x,EX_R y,EX_R z,EX_L x,EX_L y,EX_L z,EN_R x,EN_R y,EN_R z,EN_L x,EN_L y,EN_L z,PAS_R x,PAS_R y,PAS_R z,PAS_L x,PAS_L y,PAS_L z,PAI_R x,PAI_R y,PAI_R z,PAI_L x,PAI_L y,PAI_L z,G x,G y,G z,SN x,SN y,SN z,AL_R x,AL_R y,AL_R z,AL_L x,AL_L y,AL_L z,N x,N y,N z,PRN x,PRN y,PRN z,LS x,LS y,LS z,STO x,STO y,STO z,LI x,LI y,LI z,CH_R x,CH_R y,CH_R z,CH_L x,CH_L y,CH_L z,CP_R x,CP_R y,CP_R z,CP_L x,CP_L y,CP_L z,SL x,SL y,SL z,GN x,GN y,GN z,GOL_R x,GOL_R y,GOL_R z,GOL_L x,GOL_L y,GOL_L z,ZY_R x,ZY_R y,ZY_R z,ZY_L x,ZY_L y,ZY_L z,PG x,PG y,PG z,T_R x,T_R y,T_R z,T_L x,T_L y,T_L z,SA_R x,SA_R y,SA_R z,SA_L x,SA_L y,SA_L z,SBA_R x,SBA_R y,SBA_R z,SBA_L x,SBA_L y,SBA_L z,PA_R x,PA_R y,PA_R z,PA_L x,PA_L y,PA_L z,OBS_R x,OBS_R y,OBS_R z,OBS_L x,OBS_L y,OBS_L z,OBI_R x,OBI_R y,OBI_R z,OBI_L x,OBI_L y,OBI_L z,PRA_R x,PRA_R y,PRA_R z,PRA_L x,PRA_L y,PRA_L z
+00007_01,-45.3298,37.1466,-40.5415,44.3033,36.255,-42.623,-18.5134,33.2336,-36.7921,16.188,32.6379,-37.2197,-34.3363,41.5306,-33.6564,33.8288,39.5634,-34.2531,-34.4132,31.9017,-35.2642,33.5827,30.789,-36.755,0.12959,51.8853,-14.4235,-0.0356107,-13.0827,-16.9983,-16.6623,-4.05884,-19.1798,15.5038,-4.97323,-21.1836,0.044336,39.4236,-19.1853,-0.0291473,0.258132,-0.140334,-0.0901103,-29.1039,-16.7076,0.055705,-35.7511,-21.7819,0.0285089,-44.8791,-21.1852,-28.1537,-35.8802,-32.2677,24.4702,-34.6564,-34.317,-5.68164,-26.7827,-16.8184,5.63171,-26.3173,-17.4413,0.0403775,-52.2879,-27.0041,0.0981629,-80.2827,-43.5233,-57.0806,-39.8906,-118.469,50.4482,-38.958,-118.26,-63.254,40.8951,-53.951,59.7107,38.7682,-58.1024,0.0468024,-61.4376,-25.9881,-78.3702,26.048,-120.74,70.6534,28.1125,-122.519,-91.2689,55.5377,-137.688,87.5631,56.4117,-137.202,-75.6368,-4.45582,-120.828,70.4776,-1.8171,-120.704,-93.2421,34.1812,-155.155,90.0449,35.8349,-155.402,-82.7099,46.6375,-123.483,76.087,46.7891,-123.211,-72.0651,-5.47207,-119.272,64.1992,-3.95897,-118.937,-83.3521,40.1314,-121.805,75.3747,40.0263,-121.781
\ No newline at end of file
diff --git a/MeshModel/test_file_landmarks.csv b/MeshModel/test_file_landmarks.csv
new file mode 100644
index 0000000000000000000000000000000000000000..e2d6288e77633889dd6f24afab8da4e892c0cc9b
--- /dev/null
+++ b/MeshModel/test_file_landmarks.csv
@@ -0,0 +1,2 @@
+Scan name,EX_R x,EX_R y,EX_R z,EX_L x,EX_L y,EX_L z,EN_R x,EN_R y,EN_R z,EN_L x,EN_L y,EN_L z,PAS_R x,PAS_R y,PAS_R z,PAS_L x,PAS_L y,PAS_L z,PAI_R x,PAI_R y,PAI_R z,PAI_L x,PAI_L y,PAI_L z,G x,G y,G z,SN x,SN y,SN z,AL_R x,AL_R y,AL_R z,AL_L x,AL_L y,AL_L z,N x,N y,N z,PRN x,PRN y,PRN z,LS x,LS y,LS z,STO x,STO y,STO z,LI x,LI y,LI z,CH_R x,CH_R y,CH_R z,CH_L x,CH_L y,CH_L z,CP_R x,CP_R y,CP_R z,CP_L x,CP_L y,CP_L z,SL x,SL y,SL z,GN x,GN y,GN z,GOL_R x,GOL_R y,GOL_R z,GOL_L x,GOL_L y,GOL_L z,ZY_R x,ZY_R y,ZY_R z,ZY_L x,ZY_L y,ZY_L z,PG x,PG y,PG z,T_R x,T_R y,T_R z,T_L x,T_L y,T_L z,SA_R x,SA_R y,SA_R z,SA_L x,SA_L y,SA_L z,SBA_R x,SBA_R y,SBA_R z,SBA_L x,SBA_L y,SBA_L z,PA_R x,PA_R y,PA_R z,PA_L x,PA_L y,PA_L z,OBS_R x,OBS_R y,OBS_R z,OBS_L x,OBS_L y,OBS_L z,OBI_R x,OBI_R y,OBI_R z,OBI_L x,OBI_L y,OBI_L z,PRA_R x,PRA_R y,PRA_R z,PRA_L x,PRA_L y,PRA_L z
+test_file,-45.3298,37.1466,-40.5415,44.3033,36.255,-42.623,-18.5134,33.2336,-36.7921,16.188,32.6379,-37.2197,-34.3363,41.5306,-33.6564,33.8288,39.5634,-34.2531,-34.4132,31.9017,-35.2642,33.5827,30.789,-36.755,0.12959,51.8853,-14.4235,-0.0356107,-13.0827,-16.9983,-16.6623,-4.05884,-19.1798,15.5038,-4.97323,-21.1836,0.044336,39.4236,-19.1853,-0.0291473,0.258132,-0.140334,-0.0901103,-29.1039,-16.7076,0.055705,-35.7511,-21.7819,0.0285089,-44.8791,-21.1852,-28.1537,-35.8802,-32.2677,24.4702,-34.6564,-34.317,-5.68164,-26.7827,-16.8184,5.63171,-26.3173,-17.4413,0.0403775,-52.2879,-27.0041,0.0981629,-80.2827,-43.5233,-57.0806,-39.8906,-118.469,50.4482,-38.958,-118.26,-63.254,40.8951,-53.951,59.7107,38.7682,-58.1024,0.0468024,-61.4376,-25.9881,-78.3702,26.048,-120.74,70.6534,28.1125,-122.519,-91.2689,55.5377,-137.688,87.5631,56.4117,-137.202,-75.6368,-4.45582,-120.828,70.4776,-1.8171,-120.704,-93.2421,34.1812,-155.155,90.0449,35.8349,-155.402,-82.7099,46.6375,-123.483,76.087,46.7891,-123.211,-72.0651,-5.47207,-119.272,64.1992,-3.95897,-118.937,-83.3521,40.1314,-121.805,75.3747,40.0263,-121.781
\ No newline at end of file