diff --git a/Comparison/src/main/java/cz/fidentis/analyst/face/HumanFace.java b/Comparison/src/main/java/cz/fidentis/analyst/face/HumanFace.java
index 28836f6c061c1b752392e37eb24b827d367dcf35..2776b098580aa772dc42fc9beb51ca87c1df0d9a 100644
--- a/Comparison/src/main/java/cz/fidentis/analyst/face/HumanFace.java
+++ b/Comparison/src/main/java/cz/fidentis/analyst/face/HumanFace.java
@@ -22,6 +22,7 @@ import java.io.InputStream;
  * Then the are informed about changes in the human automatically via methods 
  * prescribed by the interface.
  * </p>
+ * <p>
  * Events fired by the class:
  * <ul>
  * <li>{@link cz.fidentis.analyst.mesh.events.MeshEvent} or its sub-type if 
diff --git a/Comparison/src/main/java/cz/fidentis/analyst/symmetry/SymmetryEstimator.java b/Comparison/src/main/java/cz/fidentis/analyst/symmetry/SymmetryEstimator.java
index f245e8690c03d508ee8f94e7907604939f2678f3..c2a3520f98e4110a4bbff851cc9c87ac9d2de471 100644
--- a/Comparison/src/main/java/cz/fidentis/analyst/symmetry/SymmetryEstimator.java
+++ b/Comparison/src/main/java/cz/fidentis/analyst/symmetry/SymmetryEstimator.java
@@ -89,7 +89,7 @@ public class SymmetryEstimator {
      */
     public BoundingBox getBoundingBox() {
         if (boundingBox == null) {
-            BoundingBoxVisitor visitor = new BoundingBoxVisitor();
+            BoundingBoxVisitor visitor = new BoundingBoxVisitor(true);
             facet.accept(visitor);
             boundingBox = visitor.getBoundingBox();
         }
diff --git a/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/BoundingBoxVisitor.java b/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/BoundingBoxVisitor.java
index 25451855fce826da972a9c045dba61af895d2fd0..6a121d1f4b9647266009fd51eb34ab3f17089f52 100644
--- a/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/BoundingBoxVisitor.java
+++ b/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/BoundingBoxVisitor.java
@@ -5,15 +5,28 @@ import cz.fidentis.analyst.mesh.core.MeshFacet;
 
 /**
  * Visitor that computes a 3D bounding box (cube).
+ * <p>
+ * This visitor is thread-safe. A single instance of the visitor can be used 
+ * to inspect multiple mesh models or facets simultaneously.
+ * </p>
  * 
  * @author Radek Oslejsek
  */
-public class BoundingBoxVisitor implements MeshVisitor {
+public class BoundingBoxVisitor extends MeshVisitor {
 
     private BoundingBox bbox;
     
+    /**
+     *
+     * @param concurrently If {@code true} and this visitor is thread-safe, then
+     * the visitor is applied concurrently on multiple mesf facets.
+     */
+    public BoundingBoxVisitor(boolean concurrently) {
+        super(concurrently);
+    }
+    
     @Override
-    public void visitMeshFacet(MeshFacet facet) {
+    protected synchronized void visitMeshFacet(MeshFacet facet) {
         if (bbox == null) {
             bbox = new BoundingBox(facet.getVertices());
         } else {
@@ -23,6 +36,7 @@ public class BoundingBoxVisitor implements MeshVisitor {
     
     /**
      * Returns computed bounding box.
+     * 
      * @return Bounding box or null
      */
     public BoundingBox getBoundingBox() {
diff --git a/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/HausdorffDistMeshTriVisitor.java b/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/HausdorffDistMeshTriVisitor.java
index e9befdb693da449252b4b2c931b483ec35660129..947ce338324aec6777e3f26340994eb10ecc97ca 100644
--- a/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/HausdorffDistMeshTriVisitor.java
+++ b/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/HausdorffDistMeshTriVisitor.java
@@ -24,10 +24,12 @@ public class HausdorffDistMeshTriVisitor extends HausdorffDistMeshVisitor {
      * @param relativeDistance If true, then the visitor calculates the relative distances with respect 
      * to the normal vectors of source facets (normal vectors have to present), 
      * i.e., we can get negative distances.
+     * @param concurrently If {@code true} and this visitor is thread-safe, then
+     * the visitor is applied concurrently on multiple mesf facets.
      * @throws IllegalArgumentException if some parametr is wrong
      */
-    public HausdorffDistMeshTriVisitor(Set<MeshFacet> mainFacets, boolean relativeDistance) {
-        super(mainFacets, relativeDistance);
+    public HausdorffDistMeshTriVisitor(Set<MeshFacet> mainFacets, boolean relativeDistance, boolean concurrently) {
+        super(mainFacets, relativeDistance, concurrently);
     }
     
     /**
@@ -35,14 +37,16 @@ public class HausdorffDistMeshTriVisitor extends HausdorffDistMeshVisitor {
      * @param relativeDistance If true, then the visitor calculates the relative distances with respect 
      * to the normal vectors of source facets (normal vectors have to present), 
      * i.e., we can get negative distances.
+     * @param concurrently If {@code true} and this visitor is thread-safe, then
+     * the visitor is applied concurrently on multiple mesf facets.
      * @throws IllegalArgumentException if some parametr is wrong
      */
-    public HausdorffDistMeshTriVisitor(MeshFacet mainFacet, boolean relativeDistance) {
-        super(mainFacet, relativeDistance);
+    public HausdorffDistMeshTriVisitor(MeshFacet mainFacet, boolean relativeDistance, boolean concurrently) {
+        super(mainFacet, relativeDistance, concurrently);
     }
     
     @Override
-    public void visitMeshFacet(MeshFacet comparedFacet) {
+    protected void visitMeshFacet(MeshFacet comparedFacet) {
         for (Map.Entry<MeshFacet, List<Double>> entry: getDistMap().entrySet()) {
             List<MeshPoint> vertices = entry.getKey().getVertices();
             List<Double> distList = entry.getValue();
@@ -50,7 +54,7 @@ public class HausdorffDistMeshTriVisitor extends HausdorffDistMeshVisitor {
             boolean firstComparison = distList.isEmpty();
             
             for (int i = 0; i < vertices.size(); i++) {
-                Point2MeshTriVisitor visitor = new Point2MeshTriVisitor(vertices.get(i), isRelativeDistance());
+                Point2MeshTriVisitor visitor = new Point2MeshTriVisitor(vertices.get(i), isRelativeDistance(), concurrently());
                 comparedFacet.accept(visitor);
                 double dist = visitor.getDistance();
                 updateDistances(distList, firstComparison, dist, i);
diff --git a/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/HausdorffDistMeshVisitor.java b/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/HausdorffDistMeshVisitor.java
index ef40c2d20891770baf00deaf4011692b44f158ea..3d66dcde5a99987d9aa890a3a87c41ae7c79e240 100644
--- a/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/HausdorffDistMeshVisitor.java
+++ b/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/HausdorffDistMeshVisitor.java
@@ -19,7 +19,7 @@ import java.util.Set;
  * @author Matej Lukes
  * @author Radek Oslejsek
  */
-public class HausdorffDistMeshVisitor implements MeshVisitor {
+public class HausdorffDistMeshVisitor extends MeshVisitor {
     
     private boolean relativeDistance;
     private Map<MeshFacet, List<Double>> distances = new HashMap<>();
@@ -29,9 +29,12 @@ public class HausdorffDistMeshVisitor implements MeshVisitor {
      * @param relativeDistance If true, then the visitor calculates the relative distances with respect 
      * to the normal vectors of source facets (normal vectors have to present), 
      * i.e., we can get negative distances.
+     * @param concurrently If {@code true} and this visitor is thread-safe, then
+     * the visitor is applied concurrently on multiple mesf facets.
      * @throws IllegalArgumentException if some parametr is wrong
      */
-    public HausdorffDistMeshVisitor(Set<MeshFacet> mainFacets, boolean relativeDistance) {
+    public HausdorffDistMeshVisitor(Set<MeshFacet> mainFacets, boolean relativeDistance, boolean concurrently) {
+        super(concurrently);
         if (mainFacets == null) {
             throw new IllegalArgumentException("mainFacets");
         }
@@ -46,17 +49,19 @@ public class HausdorffDistMeshVisitor implements MeshVisitor {
      * @param relativeDistance If true, then the visitor calculates the relative distances with respect 
      * to the normal vectors of source facets (normal vectors have to present), 
      * i.e., we can get negative distances.
+     * @param concurrently If {@code true} and this visitor is thread-safe, then
+     * the visitor is applied concurrently on multiple mesf facets.
      * @throws IllegalArgumentException if some parametr is wrong
      */
-    public HausdorffDistMeshVisitor(MeshFacet mainFacet, boolean relativeDistance) {
-        this(new HashSet<>(Collections.singleton(mainFacet)), relativeDistance);
+    public HausdorffDistMeshVisitor(MeshFacet mainFacet, boolean relativeDistance, boolean concurrently) {
+        this(new HashSet<>(Collections.singleton(mainFacet)), relativeDistance, concurrently);
         if (mainFacet == null) {
             throw new IllegalArgumentException("mainFacet");
         }
     }
     
     @Override
-    public void visitMeshFacet(MeshFacet comparedFacet) {
+    protected void visitMeshFacet(MeshFacet comparedFacet) {
         for (Map.Entry<MeshFacet, List<Double>> entry: distances.entrySet()) {
             List<MeshPoint> vertices = entry.getKey().getVertices();
             List<Double> distList = entry.getValue();
@@ -64,7 +69,7 @@ public class HausdorffDistMeshVisitor implements MeshVisitor {
             boolean firstComparison = distList.isEmpty();
             
             for (int i = 0; i < vertices.size(); i++) {
-                Point2MeshVisitor visitor = new Point2MeshVisitor(vertices.get(i), relativeDistance);
+                Point2MeshVisitor visitor = new Point2MeshVisitor(vertices.get(i), relativeDistance, concurrently());
                 comparedFacet.accept(visitor);
                 double dist = visitor.getDistance();
                 updateDistances(distList, firstComparison, dist, i);
diff --git a/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/KdTreeBuildVisitor.java b/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/KdTreeBuildVisitor.java
index 7538144f0bce7c8060f77dd6afb2d77e862ceae0..0c8d0af662d574d3582e552bb1a70fea59e9f572 100644
--- a/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/KdTreeBuildVisitor.java
+++ b/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/KdTreeBuildVisitor.java
@@ -14,11 +14,21 @@ import java.util.List;
  * @author Maria Kocurekova
  */
 
-public class KdTreeBuildVisitor implements MeshVisitor {
+public class KdTreeBuildVisitor extends MeshVisitor {
+    
     private List<MeshFacet> facets = new LinkedList<>();
+    
+    /**
+     *
+     * @param concurrently If {@code true} and this visitor is thread-safe, then
+     * the visitor is applied concurrently on multiple mesf facets.
+     */
+    public KdTreeBuildVisitor(boolean concurrently) {
+        super(concurrently);
+    }
 
     @Override
-    public void visitMeshFacet(MeshFacet facet) {
+    protected void visitMeshFacet(MeshFacet facet) {
         this.facets.add(facet);
     }
 
diff --git a/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/Point2MeshTriVisitor.java b/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/Point2MeshTriVisitor.java
index 050f68cb8462ca89e5d3e57a3f25af5ae10af784..2c7482801a65b42cdd4238c1c83fda7ae77d19a7 100644
--- a/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/Point2MeshTriVisitor.java
+++ b/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/Point2MeshTriVisitor.java
@@ -13,16 +13,22 @@ import javax.vecmath.Vector3d;
  * In contrast to the {@code Point2MeshVisitor} visitor, 
  * which computes pont-to-point distance, this implementation measures 
  * the distance to the triangles. 
- * 
+ * <p>
  * Because there can be multiple triangles with the same minimal distance, the visitor
  * returns a list of mesh facets and a list of indices corresponding 
  * to the facets.  
- *
+ * </p>
+ * <p>
  * Returned lists have the same size. 
  * {@code n = getIndices().get(i)} returns the index of the closest triangle on the i-th facet.
  * Then iterate into the n-th triangle of facet {@code getClosestFacets().get(i)} to get 
  * the triangle instance.
- * 
+ * </p>
+* <p>
+ * This visitor is thread-safe. A single instance of the visitor can be used 
+ * to inspect multiple mesh models or facets simultaneously.
+ * </p>
+  * 
  * @author Matej Lukes
  * @author Radek Oslejsek
  */
@@ -35,22 +41,26 @@ public class Point2MeshTriVisitor extends Point2MeshVisitor {
      * @param relativeDistance If true, the visitor calculates the distances with respect 
      * to the normals of the source point (the normal has to be present), 
      * i.e., we can get negative distance.
+     * @param concurrently If {@code true} and this visitor is thread-safe, then
+     * the visitor is applied concurrently on multiple mesf facets.
      * @throws IllegalArgumentException if some parametr is wrong
      */
-    public Point2MeshTriVisitor(MeshPoint point, boolean relativeDistance) {
-        super(point, relativeDistance);
+    public Point2MeshTriVisitor(MeshPoint point, boolean relativeDistance, boolean concurrently) {
+        super(point, relativeDistance, concurrently);
     }
     
     /**
      * @param point 3D point of which distance is computed. Must not be {@code null}
+     * @param concurrently If {@code true} and this visitor is thread-safe, then
+     * the visitor is applied concurrently on multiple mesf facets.
      * @throws IllegalArgumentException if some parametr is wrong
      */
-    public Point2MeshTriVisitor(Vector3d point) {
-        this (new MeshPointImpl(point, null, null), true);
+    public Point2MeshTriVisitor(Vector3d point, boolean concurrently) {
+        this (new MeshPointImpl(point, null, null), true, concurrently);
     }
     
     @Override
-    public void visitMeshFacet(MeshFacet facet) {
+    protected void visitMeshFacet(MeshFacet facet) {
         Vector3d my = getMyPoint().getPosition();
         int i = 0;
         for (MeshTriangle tri: facet) {
diff --git a/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/Point2MeshVisitor.java b/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/Point2MeshVisitor.java
index 5208e7e202a4a2033728ff4b91d4b3f15681d8b7..b93d34beceaf8fd4ba6bbfc47a2fe009fd084c81 100644
--- a/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/Point2MeshVisitor.java
+++ b/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/Point2MeshVisitor.java
@@ -14,15 +14,20 @@ import javax.vecmath.Vector3d;
  * Because there can be multiple points with the same minimal distance, the visitor
  * returns a list of mesh facets and a list of indices corresponding 
  * to the facets. 
- * 
-* Returned lists have the same size. 
+ * <p>
+ * Returned lists have the same size. 
  * {@code n = getIndices().get(i)} returns the index of the closest point on the i-th facet.
  * Then call {@code getClosestFacets().get(i).getVertex(n))} to get the closest point.
- * 
+ * </p>
+* <p>
+ * This visitor is thread-safe. A single instance of the visitor can be used 
+ * to inspect multiple mesh models or facets simultaneously.
+ * </p>
+  * 
  * @author Matej Lukes
  * @author Radek Oslejsek
  */
-public class Point2MeshVisitor implements MeshVisitor {
+public class Point2MeshVisitor extends MeshVisitor {
     
     private boolean relativeDist;
     private MeshPoint myPoint;
@@ -36,9 +41,12 @@ public class Point2MeshVisitor implements MeshVisitor {
      * @param relativeDistance If true, the visitor calculates the distances with respect 
      * to the normals of the source point (the normal has to be present), 
      * i.e., we can get negative distance.
+     * @param concurrently If {@code true} and this visitor is thread-safe, then
+     * the visitor is applied concurrently on multiple mesf facets.
      * @throws IllegalArgumentException if some parametr is wrong
      */
-    public Point2MeshVisitor(MeshPoint point, boolean relativeDistance) {
+    public Point2MeshVisitor(MeshPoint point, boolean relativeDistance, boolean concurrently) {
+        super(concurrently);
         if (point == null) {
             throw new IllegalArgumentException("point");
         }
@@ -51,14 +59,16 @@ public class Point2MeshVisitor implements MeshVisitor {
     
     /**
      * @param point 3D point of which distance is computed. Must not be {@code null}
+     * @param concurrently If {@code true} and this visitor is thread-safe, then
+     * the visitor is applied concurrently on multiple mesf facets.
      * @throws IllegalArgumentException if some parametr is wrong
      */
-    public Point2MeshVisitor(Vector3d point) {
-        this (new MeshPointImpl(point, null, null), true);
+    public Point2MeshVisitor(Vector3d point, boolean concurrently) {
+        this (new MeshPointImpl(point, null, null), true, concurrently);
     }
 
     @Override
-    public void visitMeshFacet(MeshFacet facet) {
+    protected void visitMeshFacet(MeshFacet facet) {
         List<MeshPoint> vertices = facet.getVertices();
         for (int i = 0; i < vertices.size(); i++) {
             checkAndUpdateDistance(vertices.get(i).getPosition(), facet, i);
@@ -112,19 +122,21 @@ public class Point2MeshVisitor implements MeshVisitor {
         sign = relativeDist ? (int) Math.signum(aux.dot(myPoint.getNormal())): 1;
         double dist = aux.length();
             
-        if (dist > distance) {
-            return;
-        }
+        synchronized (this) {
+            if (dist > distance) {
+                return;
+            }
         
-        if (dist < distance) { // new closest point
-            distance = dist;
-            closestFacets.clear();
-            indices.clear();
-            closestFacets.add(facet);
-            indices.add(index);
-        } else { // the same distance
-            closestFacets.add(facet);
-            indices.add(index);
+            if (dist < distance) { // new closest point
+                distance = dist;
+                closestFacets.clear();
+                indices.clear();
+                closestFacets.add(facet);
+                indices.add(index);
+            } else { // the same distance
+                closestFacets.add(facet);
+                indices.add(index);
+            }
         }
     }
 }
diff --git a/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/TriangleListVisitor.java b/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/TriangleListVisitor.java
index bad7f8f962636bb68e0b31f2173fbdc140bb1328..d68315b17277833a1dfee477b3222f0e11cbd4bd 100644
--- a/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/TriangleListVisitor.java
+++ b/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/TriangleListVisitor.java
@@ -10,16 +10,29 @@ import java.util.List;
  * A visitor that collects and returns a list of triangles. 
  * It is usefull for collecting triangles of multiple mesh facets.
  * For iterating through triangles of a single facet, use the iterator instead.
- * Or iterate through the facet in a for-each cycle.
- * 
+ * Or iterate through the facet in a for-each cycle. 
+* <p>
+ * This visitor is thread-safe. A single instance of the visitor can be used 
+ * to inspect multiple mesh models or facets simultaneously.
+ * </p>
+  *
  * @author Radek Oslejsek
  */
-public class TriangleListVisitor implements MeshVisitor {
+public class TriangleListVisitor extends MeshVisitor {
     
     private List<MeshTriangle> triangles = new ArrayList<>();
+    
+    /**
+     *
+     * @param concurrently If {@code true} and this visitor is thread-safe, then
+     * the visitor is applied concurrently on multiple mesf facets.
+     */
+    public TriangleListVisitor(boolean concurrently) {
+        super(concurrently);
+    }
 
     @Override
-    public void visitMeshFacet(MeshFacet facet) {
+    protected synchronized void visitMeshFacet(MeshFacet facet) {
         for (MeshTriangle tri : facet) {
             triangles.add(tri);
         }
diff --git a/Comparison/src/test/java/cz/fidentis/analyst/visitors/mesh/BoundingBoxVisitorTest.java b/Comparison/src/test/java/cz/fidentis/analyst/visitors/mesh/BoundingBoxVisitorTest.java
index f4ba298eccfae4528d9df881e79f9e9622e4861d..9fa2e80bfbf5e97c1bfca907a89b91398484e8a2 100644
--- a/Comparison/src/test/java/cz/fidentis/analyst/visitors/mesh/BoundingBoxVisitorTest.java
+++ b/Comparison/src/test/java/cz/fidentis/analyst/visitors/mesh/BoundingBoxVisitorTest.java
@@ -21,8 +21,8 @@ public class BoundingBoxVisitorTest {
     void icoSphereTest() throws IOException {
         MeshModel m = MeshObjLoader.read(new File(testFileDirectory.toFile(), "IcoSphere-20.obj"));
         assertNotNull(m);
-        BoundingBoxVisitor visitor = new BoundingBoxVisitor();
-        m.accept(visitor);
+        BoundingBoxVisitor visitor = new BoundingBoxVisitor(false);
+        m.compute(visitor);
         assertEquals(new Vector3d(0.8944249749183655, 1.0, 0.8506399989128113), visitor.getBoundingBox().getMaxPoint().getPosition());
         assertEquals(new Vector3d(-0.8944249749183655, -1.0, -0.8506399989128113), visitor.getBoundingBox().getMinPoint().getPosition());
     }
@@ -31,12 +31,12 @@ public class BoundingBoxVisitorTest {
     void combinedTest() throws IOException {
         MeshModel m = MeshObjLoader.read(new File(testFileDirectory.toFile(), "IcoSphere-20.obj"));
         assertNotNull(m);
-        BoundingBoxVisitor visitor = new BoundingBoxVisitor();
-        m.accept(visitor);
+        BoundingBoxVisitor visitor = new BoundingBoxVisitor(false);
+        m.compute(visitor);
         
         m = MeshObjLoader.read(new File(testFileDirectory.toFile(), "Tetrahedron.obj"));
         assertNotNull(m);
-        m.accept(visitor);
+        m.compute(visitor);
         
         assertEquals(new Vector3d(1.0, 1.0, 1.0), visitor.getBoundingBox().getMaxPoint().getPosition());
         assertEquals(new Vector3d(-1.0, -1.0, -1.0), visitor.getBoundingBox().getMinPoint().getPosition());
diff --git a/Comparison/src/test/java/cz/fidentis/analyst/visitors/mesh/HausdorffDistMeshTriVisitorTest.java b/Comparison/src/test/java/cz/fidentis/analyst/visitors/mesh/HausdorffDistMeshTriVisitorTest.java
index 6f6b4264778966afdf53d232f49c29051563831a..a7c2f5c67c1baabb7261ec1a5fa095e2febcb36d 100644
--- a/Comparison/src/test/java/cz/fidentis/analyst/visitors/mesh/HausdorffDistMeshTriVisitorTest.java
+++ b/Comparison/src/test/java/cz/fidentis/analyst/visitors/mesh/HausdorffDistMeshTriVisitorTest.java
@@ -31,7 +31,7 @@ public class HausdorffDistMeshTriVisitorTest {
         MeshFacet mainFacet = getTrivialFacet(1, 1);
         MeshFacet comparedFacet = getTrivialFacet(1.5, 1);
 
-        HausdorffDistMeshTriVisitor hausdorffDistance = new HausdorffDistMeshTriVisitor(mainFacet, false);
+        HausdorffDistMeshTriVisitor hausdorffDistance = new HausdorffDistMeshTriVisitor(mainFacet, false, false);
         hausdorffDistance.visitMeshFacet(comparedFacet);
         
         Map<MeshFacet, List<Double>> map = hausdorffDistance.getDistances();
@@ -46,7 +46,7 @@ public class HausdorffDistMeshTriVisitorTest {
         MeshFacet mainFacet = getTrivialFacet(1, 1);
         MeshFacet comparedFacet = getTrivialFacet(-1.5, 1);
 
-        HausdorffDistMeshTriVisitor hausdorffDistance = new HausdorffDistMeshTriVisitor(mainFacet, false);
+        HausdorffDistMeshTriVisitor hausdorffDistance = new HausdorffDistMeshTriVisitor(mainFacet, false, false);
         hausdorffDistance.visitMeshFacet(comparedFacet);
 
         Map<MeshFacet, List<Double>> map = hausdorffDistance.getDistances();
@@ -61,7 +61,7 @@ public class HausdorffDistMeshTriVisitorTest {
         MeshFacet mainFacet = getTrivialFacet(1, 1);
         MeshFacet comparedFacet = getTrivialFacet(1.5, 1);
 
-        HausdorffDistMeshTriVisitor hausdorffDistance = new HausdorffDistMeshTriVisitor(mainFacet, true);
+        HausdorffDistMeshTriVisitor hausdorffDistance = new HausdorffDistMeshTriVisitor(mainFacet, true, false);
         hausdorffDistance.visitMeshFacet(comparedFacet);
 
         Map<MeshFacet, List<Double>> map = hausdorffDistance.getDistances();
@@ -76,7 +76,7 @@ public class HausdorffDistMeshTriVisitorTest {
         MeshFacet mainFacet = getTrivialFacet(1, 1);
         MeshFacet comparedFacet = getTrivialFacet(-1.5, 1);
 
-        HausdorffDistMeshTriVisitor hausdorffDistance = new HausdorffDistMeshTriVisitor(mainFacet, true);
+        HausdorffDistMeshTriVisitor hausdorffDistance = new HausdorffDistMeshTriVisitor(mainFacet, true, false);
         hausdorffDistance.visitMeshFacet(comparedFacet);
 
         Map<MeshFacet, List<Double>> map = hausdorffDistance.getDistances();
diff --git a/Comparison/src/test/java/cz/fidentis/analyst/visitors/mesh/HausdorffDistMeshVisitorTest.java b/Comparison/src/test/java/cz/fidentis/analyst/visitors/mesh/HausdorffDistMeshVisitorTest.java
index ffa1210c0e2db3391d3a7dd27182856040a4eedd..5ad6f5d49c6575faaf2690bc460f7b4b3f2b9d4d 100644
--- a/Comparison/src/test/java/cz/fidentis/analyst/visitors/mesh/HausdorffDistMeshVisitorTest.java
+++ b/Comparison/src/test/java/cz/fidentis/analyst/visitors/mesh/HausdorffDistMeshVisitorTest.java
@@ -31,7 +31,7 @@ public class HausdorffDistMeshVisitorTest {
         MeshFacet mainFacet = getTrivialFacet(1, 1);
         MeshFacet comparedFacet = getTrivialFacet(1.5, 1);
 
-        HausdorffDistMeshVisitor hausdorffDistance = new HausdorffDistMeshVisitor(mainFacet, false);
+        HausdorffDistMeshVisitor hausdorffDistance = new HausdorffDistMeshVisitor(mainFacet, false, false);
         hausdorffDistance.visitMeshFacet(comparedFacet);
         
         Map<MeshFacet, List<Double>> map = hausdorffDistance.getDistances();
@@ -46,7 +46,7 @@ public class HausdorffDistMeshVisitorTest {
         MeshFacet mainFacet = getTrivialFacet(1, 1);
         MeshFacet comparedFacet = getTrivialFacet(-1.5, 1);
 
-        HausdorffDistMeshVisitor hausdorffDistance = new HausdorffDistMeshVisitor(mainFacet, false);
+        HausdorffDistMeshVisitor hausdorffDistance = new HausdorffDistMeshVisitor(mainFacet, false, false);
         hausdorffDistance.visitMeshFacet(comparedFacet);
 
         Map<MeshFacet, List<Double>> map = hausdorffDistance.getDistances();
@@ -61,7 +61,7 @@ public class HausdorffDistMeshVisitorTest {
         MeshFacet mainFacet = getTrivialFacet(1, 1);
         MeshFacet comparedFacet = getTrivialFacet(1.5, 1);
 
-        HausdorffDistMeshVisitor hausdorffDistance = new HausdorffDistMeshVisitor(mainFacet, true);
+        HausdorffDistMeshVisitor hausdorffDistance = new HausdorffDistMeshVisitor(mainFacet, true, false);
         hausdorffDistance.visitMeshFacet(comparedFacet);
 
         Map<MeshFacet, List<Double>> map = hausdorffDistance.getDistances();
@@ -76,7 +76,7 @@ public class HausdorffDistMeshVisitorTest {
         MeshFacet mainFacet = getTrivialFacet(1, 1);
         MeshFacet comparedFacet = getTrivialFacet(-1.5, 1);
 
-        HausdorffDistMeshVisitor hausdorffDistance = new HausdorffDistMeshVisitor(mainFacet, true);
+        HausdorffDistMeshVisitor hausdorffDistance = new HausdorffDistMeshVisitor(mainFacet, true, false);
         hausdorffDistance.visitMeshFacet(comparedFacet);
 
         Map<MeshFacet, List<Double>> map = hausdorffDistance.getDistances();
diff --git a/Comparison/src/test/java/cz/fidentis/analyst/visitors/mesh/KdTreeBuildVisitorTest.java b/Comparison/src/test/java/cz/fidentis/analyst/visitors/mesh/KdTreeBuildVisitorTest.java
index 660ed33aed36afaa016e8a57d6227549e15b2aeb..599c56acb339c5372cde6157862a1f456bd63e79 100644
--- a/Comparison/src/test/java/cz/fidentis/analyst/visitors/mesh/KdTreeBuildVisitorTest.java
+++ b/Comparison/src/test/java/cz/fidentis/analyst/visitors/mesh/KdTreeBuildVisitorTest.java
@@ -21,8 +21,8 @@ public class KdTreeBuildVisitorTest {
     void testCreateVisitorsAndGetKdTree() throws IOException {
         MeshModel m = MeshObjLoader.read(new File(testFileDirectory.toFile(), "IcoSphere-20.obj"));
         assertNotNull(m);
-        KdTreeBuildVisitor visitor = new KdTreeBuildVisitor();
-        m.accept(visitor);
+        KdTreeBuildVisitor visitor = new KdTreeBuildVisitor(false);
+        m.compute(visitor);
         assertEquals(1, m.getFacets().size());
 
         List<MeshPoint> points = new LinkedList<>();
@@ -45,8 +45,8 @@ public class KdTreeBuildVisitorTest {
     void testCreateVisitorsAndGetKdTreeDuplicate() throws IOException {
         MeshModel m = MeshObjLoader.read(new File(testFileDirectory.toFile(), "IcoSphere-20.obj"));
         assertNotNull(m);
-        KdTreeBuildVisitor visitor = new KdTreeBuildVisitor();
-        m.accept(visitor);
+        KdTreeBuildVisitor visitor = new KdTreeBuildVisitor(false);
+        m.compute(visitor);
         assertEquals(1, m.getFacets().size());
 
         List<MeshPoint> points = new LinkedList<>();
diff --git a/Comparison/src/test/java/cz/fidentis/analyst/visitors/mesh/Point2MeshTriVisitorTest.java b/Comparison/src/test/java/cz/fidentis/analyst/visitors/mesh/Point2MeshTriVisitorTest.java
index bb3a99054bc862537821fb3d94562a8001c0ddd8..dbc1a722eaeb995a1baa7dac685328a54e08223b 100644
--- a/Comparison/src/test/java/cz/fidentis/analyst/visitors/mesh/Point2MeshTriVisitorTest.java
+++ b/Comparison/src/test/java/cz/fidentis/analyst/visitors/mesh/Point2MeshTriVisitorTest.java
@@ -38,7 +38,7 @@ public class Point2MeshTriVisitorTest {
         MeshFacet facet = getTrivialFacet(1.5, 1);
         MeshPoint point = new MeshPointImpl(new Vector3d(0,0,0), new Vector3d(0,0,-1), new Vector3d());
         
-        Point2MeshVisitor vis = new Point2MeshTriVisitor(point, false);
+        Point2MeshVisitor vis = new Point2MeshTriVisitor(point, false, false);
         facet.accept(vis);
         assertEquals(1.5, vis.getDistance());
         
@@ -57,7 +57,7 @@ public class Point2MeshTriVisitorTest {
         MeshFacet facet = getTrivialFacet(1.5, 1);
         MeshPoint point = new MeshPointImpl(new Vector3d(0,0,0), new Vector3d(0,0,-1), new Vector3d());
         
-        Point2MeshVisitor vis = new Point2MeshTriVisitor(point, true);
+        Point2MeshVisitor vis = new Point2MeshTriVisitor(point, true, false);
         facet.accept(vis);
         assertEquals(-1.5, vis.getDistance());
         
@@ -78,7 +78,7 @@ public class Point2MeshTriVisitorTest {
         
         System.out.println(facet.getVertices());
         
-        Point2MeshVisitor vis = new Point2MeshTriVisitor(point, false);
+        Point2MeshVisitor vis = new Point2MeshTriVisitor(point, false, false);
         facet.accept(vis);
         assertEquals(0, vis.getDistance());
         
@@ -112,7 +112,7 @@ public class Point2MeshTriVisitorTest {
         );
         args[1] = triangle;
 
-        Point2MeshTriVisitor hausdorffDistance = new Point2MeshTriVisitor(new MeshPointImpl(new Vector3d(), null, null), false);
+        Point2MeshTriVisitor hausdorffDistance = new Point2MeshTriVisitor(new MeshPointImpl(new Vector3d(), null, null), false, false);
         Vector3d result = (Vector3d) method.invoke(hausdorffDistance, args);
 
         Assertions.assertEquals(0d, result.x);
@@ -138,7 +138,7 @@ public class Point2MeshTriVisitorTest {
         );
         args[1] = triangle;
 
-        Point2MeshTriVisitor hausdorffDistance = new Point2MeshTriVisitor(new MeshPointImpl(new Vector3d(), null, null), false);
+        Point2MeshTriVisitor hausdorffDistance = new Point2MeshTriVisitor(new MeshPointImpl(new Vector3d(), null, null), false, false);
         Vector3d result = (Vector3d) method.invoke(hausdorffDistance, args);
 
         Assertions.assertEquals(0d, result.x);
@@ -164,7 +164,7 @@ public class Point2MeshTriVisitorTest {
         );
         args[1] = triangle;
 
-        Point2MeshTriVisitor hausdorffDistance = new Point2MeshTriVisitor(new MeshPointImpl(new Vector3d(), null, null), false);
+        Point2MeshTriVisitor hausdorffDistance = new Point2MeshTriVisitor(new MeshPointImpl(new Vector3d(), null, null), false, false);
         boolean result = (boolean) method.invoke(hausdorffDistance, args);
 
         Assertions.assertTrue(result);
@@ -188,7 +188,7 @@ public class Point2MeshTriVisitorTest {
         );
         args[1] = triangle;
 
-        Point2MeshTriVisitor hausdorffDistance = new Point2MeshTriVisitor(new MeshPointImpl(new Vector3d(), null, null), false);
+        Point2MeshTriVisitor hausdorffDistance = new Point2MeshTriVisitor(new MeshPointImpl(new Vector3d(), null, null), false, false);
         boolean result = (boolean) method.invoke(hausdorffDistance, args);
 
         Assertions.assertFalse(result);
@@ -212,7 +212,7 @@ public class Point2MeshTriVisitorTest {
         );
         args[1] = triangle;
 
-        Point2MeshTriVisitor hausdorffDistance = new Point2MeshTriVisitor(new MeshPointImpl(new Vector3d(), null, null), false);
+        Point2MeshTriVisitor hausdorffDistance = new Point2MeshTriVisitor(new MeshPointImpl(new Vector3d(), null, null), false, false);
         Vector3d result = (Vector3d) method.invoke(hausdorffDistance, args);
 
         Assertions.assertEquals(1d, result.x);
@@ -238,7 +238,7 @@ public class Point2MeshTriVisitorTest {
         );
         args[1] = triangle;
 
-        Point2MeshTriVisitor hausdorffDistance = new Point2MeshTriVisitor(new MeshPointImpl(new Vector3d(), null, null), false);
+        Point2MeshTriVisitor hausdorffDistance = new Point2MeshTriVisitor(new MeshPointImpl(new Vector3d(), null, null), false, false);
         Vector3d result = (Vector3d) method.invoke(hausdorffDistance, args);
 
         Assertions.assertEquals(1d, result.x);
@@ -261,7 +261,7 @@ public class Point2MeshTriVisitorTest {
         args[1] = new Vector3d(1, 2, 0);
         args[2] = new Vector3d(1, 0, 0);
 
-        Point2MeshTriVisitor hausdorffDistance = new Point2MeshTriVisitor(new MeshPointImpl(new Vector3d(), null, null), false);
+        Point2MeshTriVisitor hausdorffDistance = new Point2MeshTriVisitor(new MeshPointImpl(new Vector3d(), null, null), false, false);
         Vector3d result = (Vector3d) method.invoke(hausdorffDistance, args);
 
         Assertions.assertEquals(1d, result.x);
@@ -284,7 +284,7 @@ public class Point2MeshTriVisitorTest {
         args[1] = new Vector3d(1, 2, 0);
         args[2] = new Vector3d(1, 0, 0);
 
-        Point2MeshTriVisitor hausdorffDistance = new Point2MeshTriVisitor(new MeshPointImpl(new Vector3d(), null, null), false);
+        Point2MeshTriVisitor hausdorffDistance = new Point2MeshTriVisitor(new MeshPointImpl(new Vector3d(), null, null), false, false);
         Vector3d result = (Vector3d) method.invoke(hausdorffDistance, args);
 
         Assertions.assertEquals(1d, result.x);
@@ -307,7 +307,7 @@ public class Point2MeshTriVisitorTest {
         args[1] = new Vector3d(1, 2, 0);
         args[2] = new Vector3d(1, 0, 0);
 
-        Point2MeshTriVisitor hausdorffDistance = new Point2MeshTriVisitor(new MeshPointImpl(new Vector3d(), null, null), false);
+        Point2MeshTriVisitor hausdorffDistance = new Point2MeshTriVisitor(new MeshPointImpl(new Vector3d(), null, null), false, false);
         Vector3d result = (Vector3d) method.invoke(hausdorffDistance, args);
 
         Assertions.assertEquals(1d, result.x);
diff --git a/Comparison/src/test/java/cz/fidentis/analyst/visitors/mesh/Point2MeshVisitorTest.java b/Comparison/src/test/java/cz/fidentis/analyst/visitors/mesh/Point2MeshVisitorTest.java
index 7e60cf1d25dc3a0fae7bb06b149348b7332afa8c..d36d119d23a23543129383f4e0aee693f20d8aab 100644
--- a/Comparison/src/test/java/cz/fidentis/analyst/visitors/mesh/Point2MeshVisitorTest.java
+++ b/Comparison/src/test/java/cz/fidentis/analyst/visitors/mesh/Point2MeshVisitorTest.java
@@ -30,7 +30,7 @@ public class Point2MeshVisitorTest {
         MeshFacet facet = getTrivialFacet(1.5, 1);
         MeshPoint point = new MeshPointImpl(new Vector3d(0,0,0), new Vector3d(0,0,-1), new Vector3d());
         
-        Point2MeshVisitor vis = new Point2MeshVisitor(point, false);
+        Point2MeshVisitor vis = new Point2MeshVisitor(point, false, false);
         facet.accept(vis);
         assertEquals(1.5, vis.getDistance());
         
@@ -49,7 +49,7 @@ public class Point2MeshVisitorTest {
         MeshFacet facet = getTrivialFacet(1.5, 1);
         MeshPoint point = new MeshPointImpl(new Vector3d(0,0,0), new Vector3d(0,0,-1), new Vector3d());
         
-        Point2MeshVisitor vis = new Point2MeshVisitor(point, true);
+        Point2MeshVisitor vis = new Point2MeshVisitor(point, true, false);
         facet.accept(vis);
         assertEquals(-1.5, vis.getDistance());
         
@@ -70,7 +70,7 @@ public class Point2MeshVisitorTest {
         
         System.out.println(facet.getVertices());
         
-        Point2MeshVisitor vis = new Point2MeshVisitor(point, false);
+        Point2MeshVisitor vis = new Point2MeshVisitor(point, false, false);
         facet.accept(vis);
         assertEquals(0, vis.getDistance());
         
diff --git a/Comparison/src/test/java/cz/fidentis/analyst/visitors/mesh/TriangleListVisitorTest.java b/Comparison/src/test/java/cz/fidentis/analyst/visitors/mesh/TriangleListVisitorTest.java
index 2cb0a5ed1054cb1c5796280737397c7ec26fe27c..c1688f5b5734e4d27d18b8591dfe93d16bb3c8d3 100644
--- a/Comparison/src/test/java/cz/fidentis/analyst/visitors/mesh/TriangleListVisitorTest.java
+++ b/Comparison/src/test/java/cz/fidentis/analyst/visitors/mesh/TriangleListVisitorTest.java
@@ -21,8 +21,8 @@ public class TriangleListVisitorTest {
     void icoSphereTest() throws IOException {
         MeshModel m = MeshObjLoader.read(new File(testFileDirectory.toFile(), "IcoSphere-20.obj"));
         assertNotNull(m);
-        TriangleListVisitor visitor = new TriangleListVisitor();
-        m.accept(visitor);
+        TriangleListVisitor visitor = new TriangleListVisitor(false);
+        m.compute(visitor);
         assertEquals(20, visitor.getTriangles().size());
     }
     
@@ -30,12 +30,12 @@ public class TriangleListVisitorTest {
     void combinedTest() throws IOException {
         MeshModel m = MeshObjLoader.read(new File(testFileDirectory.toFile(), "IcoSphere-20.obj"));
         assertNotNull(m);
-        TriangleListVisitor visitor = new TriangleListVisitor();
-        m.accept(visitor);
+        TriangleListVisitor visitor = new TriangleListVisitor(false);
+        m.compute(visitor);
         
         m = MeshObjLoader.read(new File(testFileDirectory.toFile(), "Tetrahedron.obj"));
         assertNotNull(m);
-        m.accept(visitor);
+        m.compute(visitor);
         
         assertEquals(24, visitor.getTriangles().size());
     }
diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/MeshVisitor.java b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/MeshVisitor.java
index 3abe008e1ec91c792e3b34341611f2533e9659a7..123157803b824ff50bfc44fb01d02dd2dd85b452 100644
--- a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/MeshVisitor.java
+++ b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/MeshVisitor.java
@@ -1,34 +1,96 @@
 package cz.fidentis.analyst.mesh;
 
 import cz.fidentis.analyst.mesh.core.MeshFacet;
-import cz.fidentis.analyst.mesh.core.MeshModel;
+import java.util.concurrent.Callable;
 
 /**
- * An object, when instantiated, can be applied to multiple meshes.
- * It inspects the state of the meshes one by one, and (cumulatevely) computes results.
- * 
+ * A functional object. When instantiated, it can be applied to multiple mesh facets.
+ * It inspects the state of the mesh facets one by one, and (cumulatevely) computes results.
+ * <p>
  * Implement this interface whenever you want to define new algorithm over a mesh.
+ * </p>
+ * <p>
+ * There are two visitation strategies available.
+ * The {@link cz.fidentis.analyst.mesh.mesh.MeshVisitor#visitMeshFacet} inspects
+ * the facet immediately. On the contrary, 
+ * the {@link cz.fidentis.analyst.mesh.MeshVisitor#visitConcurrently} enable to 
+ * inspect multiple facets concurretly. The later has to be called from a code like this:
+ * </p>
  * 
  * @author Radek Oslejsek
  */
-public interface MeshVisitor {
+public abstract class MeshVisitor implements Callable<MeshVisitor> {
+    
+    private boolean concurrently;
+    
+    /**
+     * Facet stored temporarily for later cuncurrent inspection via 
+     * the {@link cz.fidentis.analyst.mesh.MeshVisitor#call} method.
+     */
+    private MeshFacet facet;
+    
+    
+    /**
+     *
+     * @param concurrently If {@code true} and this visitor is thread-safe, then
+     * the visitor is applied concurrently on multiple mesh facets.
+     */
+    public MeshVisitor(boolean concurrently) {
+        this.concurrently = concurrently;
+    }
     
     /**
-     * Visits a mesh model. This method visits  all facets of the model 
-     * automatically by default.
+     * Returns {@code true} if the implementation is thread-safe and then
+     * a single visitor instance can be applied to multiple mesh facets simultaneously.
+     * If the visitor is not thread-safe, the concurrent inspection 
+     * via the {@link cz.fidentis.analyst.mesh.MeshVisitor#visitConcurrently}
+     * is still possible, but with multiple visitor instances - one for each facet.
+     * <p>
+     * Thread-safe implementation means that any read or write from/to the visitor's 
+     * state is implemented as {@code synchronized}.
+     * </p>
      * 
-     * @param model Mesh model to be visited.
+     * @return {@code true} if the implementation is thread-safe.
      */
-    default void visitMeshModel(MeshModel model) {
-        for (MeshFacet facet: model.getFacets()) {
-            facet.accept(this);
-        }
+    public boolean isThreadSafe() {
+        return true;
     }
-   
+    
     /**
-     * Visits a mesh facet.
+     * Returns {@code true} if this visitor is to be applied concurrently, i.e.,
+     * if the concurrency parameter was set and the visitor is thread-safe.
+     * 
+     * @return {@code true} if this visitor is to be applied concurrently, i.e.,
+     * if the concurrency parameter was set and the visitor is thread-safe.
+     */
+    public boolean concurrently() {
+        return this.concurrently && isThreadSafe();
+    }
+    
+    /**
+     * The inspection method to be implememted by specific visitors.
      * 
      * @param facet Mesh facet to be visited.
      */
-    void visitMeshFacet(MeshFacet facet);
+    protected abstract void visitMeshFacet(MeshFacet facet);
+    
+    /**
+     * The main visitation method
+     * 
+     * @param facet Mesh facet to be visited.
+     */
+    public void visit(MeshFacet facet) {
+        if (concurrently && isThreadSafe()) {
+            this.facet = facet;
+        } else {
+            visitMeshFacet(facet);
+        }
+    }
+    
+    @Override
+    public MeshVisitor call() throws Exception {
+        visitMeshFacet(facet);
+        return this;
+    }
+
 }
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 31417b07d7cc579f6318a4e969992930cb9e522f..a70f32d036bcfc3352a538bddc292a600de0d38a 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
@@ -4,7 +4,9 @@ import java.util.List;
 import cz.fidentis.analyst.mesh.MeshVisitor;
 
 /**
- * An ancapsulated mesh plate (with shared vertices).
+ * An ancapsulated mesh plate, i.e., multiple triangles sharing vertices.
+ * Mesh facet is iterable (triangle as returned) and visitable by 
+ * {@link cz.fidentis.analyst.mesh.MeshVisitor}s.
  *
  * @author Matej Lukes
  */
@@ -65,9 +67,9 @@ public interface MeshFacet extends Iterable<MeshTriangle> {
     int getNumTriangles();
     
     /**
-     * Entry point for visitors. 
+     * Visits this facet.
      * 
      * @param visitor Visitor
      */
-    void accept(MeshVisitor visitor);
+    void accept(MeshVisitor visitor);    
 }
diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshFacetImpl.java b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshFacetImpl.java
index 53dfb144ea91775cde00e565d303d6c7b28d1c0f..058d18edccb15cf33f87f41b98430426dadac180 100644
--- a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshFacetImpl.java
+++ b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshFacetImpl.java
@@ -19,7 +19,7 @@ public class MeshFacetImpl implements MeshFacet {
     
     private List<MeshPoint> vertices = new ArrayList<>();
     private CornerTable cornerTable;
-
+    
     /**
      * Constructor of MeshFacet
      */
@@ -39,9 +39,9 @@ public class MeshFacetImpl implements MeshFacet {
     
     @Override
     public void accept(MeshVisitor visitor) {
-        visitor.visitMeshFacet(this);
+        visitor.visit(this);
     }
-
+    
     @Override
     public MeshPoint getVertex(int index) {
         return vertices.get(index);
@@ -102,6 +102,7 @@ public class MeshFacetImpl implements MeshFacet {
         }
     }
     
+    @Override
     public int getNumTriangles() {
         return cornerTable.getSize();
     }
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 7545d83bb5984b162979858c49b8ed6cbfdd1224..6d3711eb4a8f5d1229d54e67455cf51a64e18ac6 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
@@ -7,48 +7,22 @@ import cz.fidentis.analyst.mesh.MeshVisitor;
 import cz.fidentis.analyst.mesh.events.FacetAddedEvent;
 import java.util.Collections;
 import cz.fidentis.analyst.mesh.events.MeshListener;
-import java.util.concurrent.Callable;
+import java.util.LinkedList;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 /**
  * The main object for triangular meshes. Each mesh model consists  
  * of one or more mesh facets.
  * <p>
- * This class implements the <i>Visitor</i> design pattern for exploration. 
- * Internal structure can be explored by using an object implementing 
- * {@link cz.fidentis.analyst.mesh.MeshVisitor}. To methods are available.
- * Standard {@link cz.fidentis.analyst.mesh.core.MeshModel#visit} invokes 
- * the exploration immediately, and the {@link cz.fidentis.analyst.mesh.core.MeshModel#visitConcurrently},
- * which enables parallel processing. The second method has to be called from a code like this:
- * <pre>
- *      int threads = Runtime.getRuntime().availableProcessors();
- *      ExecutorService executor = Executors.newFixedThreadPool(threards);
- *      List<Future<NeshVisitor>> resultList = new LinkedList<>();
- * 
- *      for (...) {
- *          Future<MeshVisitor> results = executor.submit(meshModel.acceptConcurrently(new ConcreteMeshVisitor()));
- *      }
- * 
- *      executor.shutdown();
- * 
- *      for(Future<MeshVisitor> f : resultList){
- *          try {
- *              MeshVisitor vis = f.get();
- *              vis.getResult(); // process the partial results
- *          } catch (InterruptedException | ExecutionException ex) {
- *              Logger.getLogger(this.class.getName()).log(Level.SEVERE, null, ex);
- *          }
- *      }
- * </pre>
- * Don't use the same instance of the {@code ConcreteMeshVisitor} inside the for-cycle unless
- * you are sure that the visitor's {@code visitMeshModel()} and {@code visitMeshFacet()} 
- * methods are atomic.
- * </p>
- * <p>
  * This class implements the publish-subscribe notifications to changes. 
  * However, the {@link cz.fidentis.analyst.face.HumanFace} class provides similar
  * functionality at the higher level of abstraction. Therefore, we recomend
  * to monitor this class when you want to be informed about changes in concrete human face.
- * </p>
  * <p>
  * Events fired by the class:
  * <ul>
@@ -59,7 +33,7 @@ import java.util.concurrent.Callable;
  * @author Matej Lukes
  * @author Radek Oslejsek
  */
-public class MeshModel implements Callable<MeshVisitor> {
+public class MeshModel {
     
     private final List<MeshFacet> facets = new ArrayList<>();
     
@@ -110,30 +84,51 @@ public class MeshModel implements Callable<MeshVisitor> {
     }
     
     /**
-     * Entry point for visitors. 
+     * Applies the visitor to all mesh facets, either sequentially or in parallel.
      * 
-     * @param visitor Visitor
+     * @param visitor Visitor to be apllied for the computation
+     * @param exec Exisitng executor. If {@code null}, then a new private executor is used.
+     * @throws {@code NullPointerException} if the visitor is {@code null}
      */
-    public void accept(MeshVisitor visitor) {
-        visitor.visitMeshModel(this);
+    public void compute(MeshVisitor visitor, ExecutorService exec) {
+        if (visitor.concurrently()) {
+            ExecutorService executor = exec;
+            if (executor == null) {
+                int threads = Runtime.getRuntime().availableProcessors();
+                executor = Executors.newFixedThreadPool(threads);
+            }
+            
+            List<Future<MeshVisitor>> results = new LinkedList<>();
+            
+            for (MeshFacet f: this.facets) {
+                f.accept(visitor);
+                Future<MeshVisitor> result = executor.submit(visitor); // fork and continue
+                results.add(result);
+            }
+            
+            //executor.shutdown();
+            
+            try {
+                for (Future<MeshVisitor> f : results) { 
+                    f.get(); // wait ntil all computations are finished
+                }
+            } catch (InterruptedException | ExecutionException ex) {
+                Logger.getLogger(MeshModel.class.getName()).log(Level.SEVERE, null, ex);
+            }
+        } else {
+            for (MeshFacet f: this.facets) {
+                f.accept(visitor);
+            }
+        }
     }
     
     /**
-     * Stores the visitor for concurrent exploration.
-     * The visitor's invocation has to done via the
-     * {@link java.util.concurrent.ExecutorService}, which invokes 
-     * {@link cz.fidentis.analyst.mesh.core.MeshModel#call} method.
+     * Applies the visitor to all mesh facets, either sequentially or in parallel.
      * 
-     * @param visitor Visitor
+     * @param visitor Visitor to be apllied
      */
-    public void acceptConcurrently(MeshVisitor visitor) {
-        this.visitor = visitor;
-    }
-    
-    @Override
-    public MeshVisitor call() throws Exception {
-        visitor.visitMeshModel(this);
-        return visitor;
+    public void compute(MeshVisitor visitor) {
+        compute(visitor, null);
     }
     
     /**
diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/events/FacetAddedEvent.java b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/events/FacetAddedEvent.java
index b0c2a8f7bb6837f96a041a31704a01f0a5984e55..03d3523c68172db1efbd8eb24f5d97cffa77f58f 100644
--- a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/events/FacetAddedEvent.java
+++ b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/events/FacetAddedEvent.java
@@ -12,6 +12,10 @@ public class FacetAddedEvent implements MeshEvent {
     
     private final MeshFacet facet;
     
+    /**
+     * 
+     * @param facet Mesdh Facet
+     */
     public FacetAddedEvent(MeshFacet facet) {
         this.facet = facet;
     }