diff --git a/src/main/java/fr/pasteur/ida/zellige/steps/construction/Construction.java b/src/main/java/fr/pasteur/ida/zellige/steps/construction/Construction.java
new file mode 100644
index 0000000000000000000000000000000000000000..f52b373dac82cc7bac807faedf94663796d8d33a
--- /dev/null
+++ b/src/main/java/fr/pasteur/ida/zellige/steps/construction/Construction.java
@@ -0,0 +1,92 @@
+package fr.pasteur.ida.zellige.steps.construction;
+
+import fr.pasteur.ida.zellige.ReferenceSurfaceExtraction;
+import fr.pasteur.ida.zellige.element.ReferenceSurface;
+import fr.pasteur.ida.zellige.element.Surface;
+import fr.pasteur.ida.zellige.steps.construction.exception.NoSurfaceFoundException;
+import fr.pasteur.ida.zellige.steps.construction.rounds.ConstructionParameters;
+import fr.pasteur.ida.zellige.steps.construction.rounds.FirstRoundConstruction;
+import fr.pasteur.ida.zellige.steps.construction.rounds.SecondRoundConstruction;
+import net.imglib2.RandomAccessibleInterval;
+import net.imglib2.img.Img;
+import net.imglib2.img.ImgFactory;
+import net.imglib2.type.NativeType;
+import net.imglib2.type.numeric.RealType;
+import net.imglib2.type.numeric.real.FloatType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+
+public class Construction< T extends RealType< T > & NativeType< T > >
+{
+
+    private final static Logger LOGGER = LoggerFactory.getLogger( Construction.class );
+
+
+    private final ArrayList< ReferenceSurface< T > > referenceSurfaces = new ArrayList<>();
+
+    private int FS_startingOS_count;
+    private int FS_OS_count;
+    private int FS_smallSurfaces;
+    private int FS_goodSurfaces;
+    private int FS_finalizedSurfaces;
+    private int SS_startingOS_count;
+    private int SS_OS_count;
+    private int SS_smallSurfaces;
+    private int SS_goodSurfaces;
+    private long FS_OSConstructionProcessingTime;
+    private long FS_SurfaceConstructionProcessingTime;
+    private long SS_OSConstructionProcessingTime;
+    private long SS_SurfaceConstructionProcessingTime;
+
+
+    public static < T extends RealType< T > & NativeType< T > > ArrayList< ReferenceSurface< T > >
+    run( ConstructionParameters[] constructionParameters,
+         RandomAccessibleInterval< T > input,
+         ImgFactory< T > factory,
+         Img< FloatType > selectedPixels, int bin ) throws NoSurfaceFoundException
+    {
+        Construction< T > construction = new Construction<>();
+        construction.run( constructionParameters, selectedPixels, input, factory, bin );
+        return construction.referenceSurfaces;
+    }
+
+
+    private void run( ConstructionParameters[] constructionParameters, Img< FloatType > selectedPixels, RandomAccessibleInterval< T > input, ImgFactory< T > factory, int bin ) throws NoSurfaceFoundException
+    {
+        LOGGER.debug( "Running construction..." );
+        /*  First round construction*/
+        FirstRoundConstruction step1 = new FirstRoundConstruction( selectedPixels, constructionParameters[ 0 ] );
+        step1.process();
+        ArrayList< Surface > tempSurfaces = step1.getSurfaces();
+        FS_startingOS_count = step1.getStartingOSCount();
+        FS_OS_count = step1.getOSCount();
+        FS_goodSurfaces = step1.getGoodSurfacesCount();
+        FS_smallSurfaces = step1.getSmallSurfacesCount();
+        FS_finalizedSurfaces = tempSurfaces.size();
+        FS_OSConstructionProcessingTime = step1.getOSConstructionProcessingTime();
+        FS_SurfaceConstructionProcessingTime = step1.getConstructionProcessingTime();
+        LOGGER.debug( "first round surfaces = {}", tempSurfaces.size() );
+        /* Second round construction */
+        SecondRoundConstruction step2 =
+                new SecondRoundConstruction( tempSurfaces, constructionParameters[ 1 ] );
+        step2.process();
+        ArrayList< Surface > finalSurfaces = step2.getSurfaces();
+        SS_startingOS_count = step2.getStartingOSCount();
+        SS_OS_count = step2.getOSCount();
+        SS_goodSurfaces = step2.getGoodSurfacesCount();
+        SS_smallSurfaces = step2.getSmallSurfacesCount();
+        SS_OSConstructionProcessingTime = step2.getOSConstructionProcessingTime();
+        SS_SurfaceConstructionProcessingTime = step2.getConstructionProcessingTime();
+        /* Building reference surfaces */
+        referenceSurfaces.addAll( ConstructionCompletion.run( input, factory, finalSurfaces, bin ) );
+        LOGGER.debug( " Constructions of {} surfaces.", referenceSurfaces.size() );
+
+    }
+
+    public ArrayList< ReferenceSurface< T > > getReferenceSurfaces()
+    {
+        return referenceSurfaces;
+    }
+}