diff --git a/src/main/java/fr/inra/po2vocabmanager/utils/DataTreeCell.java b/src/main/java/fr/inra/po2vocabmanager/utils/DataTreeCell.java
index e7deb82ecdea8c6faf94bec608065a74144a704c..325cd0277eb4ba244e3c7b8c95b2aa9e0b47199e 100644
--- a/src/main/java/fr/inra/po2vocabmanager/utils/DataTreeCell.java
+++ b/src/main/java/fr/inra/po2vocabmanager/utils/DataTreeCell.java
@@ -21,6 +21,7 @@ package fr.inra.po2vocabmanager.utils;
 import fr.inra.po2vocabmanager.MainApp;
 import fr.inra.po2vocabmanager.model.DataNode;
 import fr.inrae.po2engine.externalTools.RDF4JTools;
+import fr.inrae.po2engine.model.Replicate;
 import fr.inrae.po2engine.model.dataModel.*;
 import fr.inrae.po2engine.utils.ImportReport;
 import fr.inrae.po2engine.utils.Report;
@@ -182,7 +183,7 @@ public class DataTreeCell extends TextFieldTreeCell<DataNode> {
         return s;
     }
 
-    private static void newStepImport(ItineraryFile iti, StepFile parent) {
+    private static void newStepImport(ItineraryFile iti, StepFile parent, int replicateID) {
         File fileImport = getFile(MainApp.primaryStage);
         if (fileImport == null) {
             return;
@@ -190,7 +191,7 @@ public class DataTreeCell extends TextFieldTreeCell<DataNode> {
         MainApp.logger.info("start importing file " + fileImport.getName());
         ImportReport importReport = iti.checkImportStepFromXLSX(fileImport);
         if(importReport.success()) {
-            StepFile step = iti.importStepFromXLSX(fileImport);
+            StepFile step = iti.importStepFromXLSX(fileImport, replicateID);
             if(parent != null && step != null) {
                 parent.addSubStep(step);
             }
@@ -274,15 +275,15 @@ public class DataTreeCell extends TextFieldTreeCell<DataNode> {
     }
 
 
-    private static void newItineraryObsImport(ItineraryFile iti) {
+    private static void newItineraryObsImport(ItineraryFile iti, int replicateID) {
         File fileImport = getFile(MainApp.primaryStage);
         if (fileImport == null) {
             return;
         }
         MainApp.logger.info("start importing/create file " + fileImport.getName());
-        Report r = iti.checkCreateObservationFromXLSX(fileImport);
+        Report r = iti.checkCreateObservationFromXLSX(fileImport, replicateID);
         if(r.success()) {
-            ObservationFile obs = iti.createObservationFromXLSX(fileImport);
+            ObservationFile obs = iti.createObservationFromXLSX(fileImport, replicateID);
             handleInterfaceUpdate(obs.getItineraryFile().getProcessFile(), r.success(), "File import completed");
             MainApp.getDataControler().selectNode(obs);
             MainApp.logger.info("import done with sucess");
@@ -328,15 +329,402 @@ public class DataTreeCell extends TextFieldTreeCell<DataNode> {
         result.ifPresent(step -> addStepData(itineraryFile, parentStep, current, true, step));
     }
 
-    private void newStepObsImport(StepFile step) {
+    private static void stepImport(StepFile file, boolean isNewStep, int replicateID) {
+            File fileImport = getFile(MainApp.primaryStage);
+            if (fileImport != null) {
+            MainApp.logger.info("start importing file " + fileImport.getName());
+            ImportReport importReport = file.realPreConst(fileImport, isNewStep);
+            if(importReport.success()) {
+
+                // validation de l'import par l'utilisateur
+                Dialog<ButtonType> validateImport = new Dialog();
+                validateImport.setTitle("import validation");
+                validateImport.initOwner(MainApp.primaryStage);
+                validateImport.initModality(Modality.WINDOW_MODAL);
+                ButtonType importButtonType = new ButtonType("Import", ButtonBar.ButtonData.OK_DONE);
+                validateImport.getDialogPane().getButtonTypes().addAll(importButtonType, ButtonType.CANCEL);
+
+                GridPane paneImport = new GridPane();
+                paneImport.setHgap(20);
+                paneImport.setVgap(20);
+
+                Integer comptLine = 0;
+                Text stepText = new Text(file.getNameProperty().getValue());
+                Text sepa = new Text(" : ");
+                paneImport.add(new ImageView(UITools.getImage("resources/images/treeview/step.png")), 0, comptLine);
+                paneImport.add(stepText, 1, comptLine);
+                paneImport.add(sepa, 2, comptLine);
+                paneImport.add(new ImageView(UITools.getImage("resources/images/update_30.png")), 3, comptLine);
+
+                comptLine++;
+
+
+                for (ObservationFile obsF : file.getObservationFiles()) {
+                    Text obsText = new Text(obsF.getCID().getValue().get());
+                    Text sepa2 = new Text(" : ");
+                    paneImport.add(new ImageView(UITools.getImage("resources/images/treeview/observation.png")), 0, comptLine);
+                    paneImport.add(obsText, 1, comptLine);
+                    paneImport.add(sepa2, 2, comptLine);
+                    if (importReport.getObsMapping().containsValue(obsF)) {
+                        paneImport.add(new ImageView(UITools.getImage("resources/images/update_30.png")), 3, comptLine);
+                    } else {
+                        paneImport.add(new ImageView(UITools.getImage("resources/images/del_30.png")), 3, comptLine);
+                    }
+                    comptLine++;
+                }
+
+                for(XSSFSheet oo : importReport.getObsMapping().keySet()) {
+                    if(importReport.getObsMapping().get(oo) == null) { // new obs
+                        Text obsText = new Text(oo.getSheetName());
+                        Text sepa2 = new Text(" : ");
+                        paneImport.add(new ImageView(UITools.getImage("resources/images/treeview/observation.png")), 0, comptLine);
+                        paneImport.add(obsText, 1, comptLine);
+                        paneImport.add(sepa2, 2, comptLine);
+                        paneImport.add(new ImageView(UITools.getImage("resources/images/add_30.png")), 3, comptLine);
+                        comptLine++;
+                    }
+                }
+
+                for (CompositionFile compoF : file.getCompositionFile().keySet()) {
+                    Text compoText = new Text(compoF.getCompositionID().getValue().get());
+                    Text sepa2 = new Text(" : ");
+                    paneImport.add(new ImageView(UITools.getImage("resources/images/treeview/composition.png")), 0, comptLine);
+                    paneImport.add(compoText, 1, comptLine);
+                    paneImport.add(sepa2, 2, comptLine);
+                    if(importReport.getCompoMapping().values().stream().map(org.apache.commons.lang3.tuple.Pair::getLeft).noneMatch(c -> c.equals(compoF))) {
+                        paneImport.add(new ImageView(UITools.getImage("resources/images/del_30.png")), 3, comptLine);
+                    } else {
+                        paneImport.add(new ImageView(UITools.getImage("resources/images/update_30.png")), 3, comptLine);
+                    }
+                    comptLine++;
+                }
+
+                for(XSSFSheet oo : importReport.getCompoMapping().keySet()) {
+                    if(importReport.getCompoMapping().get(oo).getLeft() == null) { // new Compo
+                        Text compoText = new Text(oo.getSheetName());
+                        Text sepa2 = new Text(" : ");
+                        paneImport.add(new ImageView(UITools.getImage("resources/images/treeview/composition.png")), 0, comptLine);
+                        paneImport.add(compoText, 1, comptLine);
+                        paneImport.add(sepa2, 2, comptLine);
+                        paneImport.add(new ImageView(UITools.getImage("resources/images/add_30.png")), 3, comptLine);
+                        comptLine++;
+                    }
+                }
+
+                validateImport.getDialogPane().setContent(paneImport);
+                Optional<ButtonType> result = Optional.empty();
+                if(!isNewStep) {
+                    result = validateImport.showAndWait();
+                }
+                if (isNewStep || result.isPresent() && result.get() == importButtonType) {
+                    // l'utilisateur valide la la mise à jour
+                    Report report = file.constructDataFromImport(fileImport, isNewStep, replicateID);
+                    handleInterfaceUpdate(file.getGeneralFile(), report.success(), report.toString());
+                    MainApp.getDataControler().selectNode(file);
+                }
+            } else {
+                showErrorImportAlert(importReport.toString());
+            }
+        } else {
+        }
+    }
+
+    private static void importObservation(ObservationFile obsFile, int replicateID) {
+        File fileImport = getFile(MainApp.primaryStage);
+        if (fileImport != null) {
+            MainApp.logger.info("start importing/update file " + fileImport.getName());
+            // temp obs file
+            ObservationFile tempF = null;
+            if(obsFile.getStepFile() != null) {
+                Report r = obsFile.getStepFile().checkUpdateObservationFromXLSX(fileImport, obsFile, replicateID);
+                if(r.success()) {
+                    obsFile.getStepFile().updateObservationFromXLSX(fileImport, obsFile, replicateID);
+                    MainApp.getDataControler().refreshTree();
+                    MainApp.getDataControler().showNodeDetails(obsFile, obsFile);
+                    MainApp.logger.info("import done with sucess");
+                } else {
+                    showErrorImportAlert(r.prettyPrintError());
+                }
+            }
+            if(obsFile.getItineraryFile() != null) {
+                Report r = obsFile.getItineraryFile().checkUpdateObservationFromXLSX(fileImport, obsFile, replicateID);
+                if(r.success()) {
+                    obsFile.getItineraryFile().updateObservationFromXLSX(fileImport, obsFile, replicateID);
+                    MainApp.getDataControler().refreshTree();
+                    MainApp.getDataControler().showNodeDetails(obsFile, obsFile);
+                    MainApp.logger.info("import done with sucess");
+                } else {
+                    showErrorImportAlert(r.prettyPrintError());
+                }
+            }
+        }
+    }
+
+    private static void exportObservation(ObservationFile obsFile, int replicateID) {
+        List<String> choices = new ArrayList<>();
+        choices.add("with ontology");
+        choices.add("without ontology");
+        ChoiceDialog<String> dialog = new ChoiceDialog<>("without ontology", choices);
+        dialog.setTitle("Export Observation");
+        dialog.setHeaderText(null);
+        dialog.setContentText("Export Observation data ");
+        dialog.initModality(Modality.WINDOW_MODAL);
+        dialog.initOwner(MainApp.primaryStage);
+        Boolean exportOnto = false;
+        Optional<String> result = dialog.showAndWait();
+
+        if (result.isPresent() ) {
+            exportOnto = result.get().equals("with ontology");
+            Boolean finalExportOnto = exportOnto;
+            if (exportOnto && MainApp.getOntologyControler().getCurrentOntology() == null) {
+                Alert noOntology = new Alert(Alert.AlertType.ERROR);
+                noOntology.setTitle("No ontology loaded");
+                noOntology.setHeaderText("Please load an ontology");
+                noOntology.setContentText("In order to create an export file, please load the corresponding ontology");
+                noOntology.initOwner(MainApp.primaryStage);
+                noOntology.initModality(Modality.APPLICATION_MODAL);
+                noOntology.showAndWait();
+            } else {
+                XSSFWorkbook book = new XSSFWorkbook();
+
+
+                Task<Boolean> taskExport = new Task<Boolean>() {
+                    @Override
+                    protected Boolean call() throws Exception {
+                        XSSFSheet sheet = Tools.createSheet(book,"obs|"+Tools.removeNonAlphaNumChar(obsFile.getNameProperty().getValue()));
+
+                        Integer compteur = 0;
+                        Integer maxColumn = 0;
+                        for (LinkedList<String> line : obsFile.getDataForExcel(replicateID)) {
+                            XSSFRow r = sheet.createRow(compteur++);
+                            Integer compteurCell = 0;
+                            for (String val : line) {
+                                r.createCell(compteurCell++).setCellValue(val);
+                                maxColumn = Math.max(maxColumn, compteurCell);
+                            }
+                        }
+                        Tools.autoResize(sheet, maxColumn);
+
+
+                        if(finalExportOnto) {
+
+                            JSONObject hierarchyVocab = MainApp.getOntologyControler().getHierarchyVocabJSON();
+                            // Récupération de l'ontology au format JSON
+                            XSSFSheet sheetOntoVocab = Tools.createSheet(book,"onto-vocab|" + Tools.removeNonAlphaNumChar(MainApp.getOntologyControler().getCurrentOntology().getName().getValue()));
+                            JSONArray vocab = (JSONArray) hierarchyVocab.get("vocabulary");
+
+                            compteur = 0;
+                            maxColumn = 0;
+                            for (
+                                    int i = 0; i < vocab.length(); i++) {
+                                JSONArray array = (JSONArray) vocab.get(i);
+                                XSSFRow r = sheetOntoVocab.createRow(compteur++);
+                                for (int j = 0; j < array.length(); j++) {
+                                    r.createCell(j).setCellValue((String) array.get(j));
+                                    maxColumn = Math.max(maxColumn, j);
+                                }
+                            }
+                            Tools.autoResize(sheetOntoVocab, maxColumn);
+
+
+                            XSSFSheet sheetOntohierarchy = Tools.createSheet(book,"onto-hierarchy|" + Tools.removeNonAlphaNumChar(MainApp.getOntologyControler().getCurrentOntology().getName().getValue()));
+                            JSONArray hierarchy = (JSONArray) hierarchyVocab.get("hierarchy");
+
+                            compteur = 0;
+                            maxColumn = 0;
+
+                            for (
+                                    int x = 0; x < hierarchy.length(); x++) {
+                                XSSFRow r = sheetOntohierarchy.createRow(compteur++);
+                                JSONArray arrayDesc = (JSONArray) hierarchy.get(x);
+                                for (int j = 0; j < arrayDesc.length(); j++) {
+                                    r.createCell(j).setCellValue((String) arrayDesc.get(j));
+                                    maxColumn = Math.max(maxColumn, j);
+                                }
+                            }
+                            Tools.autoResize(sheetOntohierarchy, maxColumn);
+                        }
+                        return true;
+                    }
+                };
+                taskExport.setOnSucceeded(workerStateEvent -> {
+                    FileChooser fileChooser = new FileChooser();
+                    fileChooser.setTitle("Export file");
+                    String fileName = obsFile.getFileName();
+                    if(replicateID != -1) {
+                        fileName+="-"+replicateID;
+                    }
+                    fileChooser.setInitialFileName(fileName+".xlsx");
+                    File fileExport = fileChooser.showSaveDialog(MainApp.primaryStage);
+                    if (fileExport != null) {
+                        try {
+                            FileOutputStream fout = new FileOutputStream(fileExport, false);
+                            book.write(fout);
+                            fout.close();
+                        } catch (IOException ex) {
+                            MainApp.logger.error(ex.getMessage());
+                        }
+                    }
+                });
+                new Thread(taskExport).start();
+            }
+        }
+    }
+
+    private static void exportStepFile(StepFile stepFile, int replicateID) {
+
+        List<String> choices = new ArrayList<>();
+        choices.add("with ontology");
+        choices.add("without ontology");
+        ChoiceDialog<String> dialog = new ChoiceDialog<>("without ontology", choices);
+        dialog.setTitle("Export Step");
+        dialog.setHeaderText(null);
+        dialog.setContentText("Export step data ");
+        dialog.initModality(Modality.WINDOW_MODAL);
+        dialog.initOwner(MainApp.primaryStage);
+        Boolean exportOnto = false;
+        Optional<String> result = dialog.showAndWait();
+
+        if (result.isPresent() ) {
+            exportOnto = result.get().equals("with ontology");
+            if(exportOnto && MainApp.getOntologyControler().getCurrentOntology() == null) {
+                Alert noOntology = new Alert(Alert.AlertType.ERROR);
+                noOntology.setTitle("No ontology loaded");
+                noOntology.setHeaderText("Please load an ontology");
+                noOntology.setContentText("In order to create an export file, please load the corresponding ontology");
+                noOntology.initOwner(MainApp.primaryStage);
+                noOntology.initModality(Modality.APPLICATION_MODAL);
+                noOntology.showAndWait();
+            } else {
+                XSSFWorkbook book = new XSSFWorkbook();
+                Boolean finalExportOnto = exportOnto;
+                Task<Boolean> taskExport = new Task<Boolean>() {
+                    @Override
+                    protected Boolean call() throws Exception {
+                        XSSFSheet sheet = Tools.createSheet(book,"step|"+ DigestUtils.md5Hex(stepFile.getNameProperty().getValue()));
+
+                        Integer compteur = 0;
+                        Integer maxColumn = 0;
+
+                        for (LinkedList<String> line : stepFile.getDataForExcel(true, replicateID)) {
+                            XSSFRow r = sheet.createRow(compteur++);
+                            Integer compteurCell = 0;
+                            for (String val : line) {
+                                r.createCell(compteurCell++).setCellValue(val);
+                                maxColumn = Math.max(maxColumn, compteurCell);
+                            }
+                        }
+
+
+                        // composition
+                        for (Map.Entry<CompositionFile, Boolean> entry : stepFile.getCompositionFile().entrySet()) {
+                            XSSFSheet sheetCompo = Tools.createSheet(book,"compo-"+(entry.getValue() ? "input" : "output")+"|"+Tools.removeNonAlphaNumChar(entry.getKey().getCompositionID().getValue().get()));
+                            Integer compteurCompo = 0;
+                            Integer maxColumnCompo = 0;
+                            for (LinkedList<String> line : entry.getKey().getDataForExcel()) {
+                                XSSFRow r = sheetCompo.createRow(compteurCompo++);
+                                Integer compteurCell = 0;
+                                for (String val : line) {
+                                    r.createCell(compteurCell++).setCellValue(val);
+                                    maxColumnCompo = Math.max(maxColumnCompo, compteurCell);
+                                }
+                            }
+                            Tools.autoResize(sheetCompo, maxColumnCompo);
+                        }
+
+
+
+                        Tools.autoResize(sheet, maxColumn);
+
+                        for(ObservationFile obs : stepFile.getObservationFiles()) {
+                            XSSFSheet sheetObs = Tools.createSheet(book,"obs|"+Tools.removeNonAlphaNumChar(obs.getCID().getValue().get()));
+
+                            Integer compteurObs = 0;
+                            Integer maxColumnObs = 0;
+                            for (LinkedList<String> line : obs.getDataForExcel(replicateID)) {
+                                XSSFRow r = sheetObs.createRow(compteurObs++);
+                                Integer compteurCell = 0;
+                                for (String val : line) {
+                                    r.createCell(compteurCell++).setCellValue(val);
+                                    maxColumnObs = Math.max(maxColumnObs, compteurCell);
+                                }
+                            }
+                            Tools.autoResize(sheetObs, maxColumnObs);
+                        }
+
+                        if(finalExportOnto) {
+
+                            JSONObject hierarchyVocab = MainApp.getOntologyControler().getHierarchyVocabJSON();
+                            // Récupération de l'ontology au format JSON
+                            XSSFSheet sheetOntoVocab = Tools.createSheet(book,"onto-vocab|" + Tools.removeNonAlphaNumChar(MainApp.getOntologyControler().getCurrentOntology().getName().getValue()));
+                            JSONArray vocab = (JSONArray) hierarchyVocab.get("vocabulary");
+
+                            compteur = 0;
+                            maxColumn = 0;
+                            for (int i = 0; i < vocab.length(); i++) {
+                                JSONArray array = (JSONArray) vocab.get(i);
+                                XSSFRow r = sheetOntoVocab.createRow(compteur++);
+                                for (int j = 0; j < array.length(); j++) {
+                                    r.createCell(j).setCellValue((String) array.get(j));
+                                    maxColumn = Math.max(maxColumn, j);
+                                }
+                            }
+                            Tools.autoResize(sheetOntoVocab, maxColumn);
+
+
+                            XSSFSheet sheetOntohierarchy = Tools.createSheet(book,"onto-hierarchy|" + Tools.removeNonAlphaNumChar(MainApp.getOntologyControler().getCurrentOntology().getName().getValue()));
+                            JSONArray hierarchy = (JSONArray) hierarchyVocab.get("hierarchy");
+
+                            compteur = 0;
+                            maxColumn = 0;
+
+                            for (int x = 0; x < hierarchy.length(); x++) {
+                                XSSFRow r = sheetOntohierarchy.createRow(compteur++);
+                                JSONArray arrayDesc = (JSONArray) hierarchy.get(x);
+                                for (int j = 0; j < arrayDesc.length(); j++) {
+                                    r.createCell(j).setCellValue((String) arrayDesc.get(j));
+                                    maxColumn = Math.max(maxColumn, j);
+                                }
+                            }
+                            Tools.autoResize(sheetOntohierarchy, maxColumn);
+                        }
+                        return true;
+                    }
+                };
+                taskExport.setOnSucceeded(workerStateEvent -> {
+                    FileChooser fileChooser = new FileChooser();
+                    fileChooser.setTitle("Export file");
+                    String fileName = stepFile.getNameProperty().getValue();
+                    if(replicateID != -1) {
+                        fileName+="-"+replicateID;
+                    }
+                    fileChooser.setInitialFileName(fileName+".xlsx");
+                    File fileExport = fileChooser.showSaveDialog(MainApp.primaryStage);
+                    if (fileExport != null) {
+                        try {
+                            FileOutputStream fout = new FileOutputStream(fileExport, false);
+                            book.write(fout);
+                            fout.close();
+                        } catch (IOException ex) {
+                            MainApp.logger.error(ex.getMessage());
+                        }
+                    }
+                });
+                new Thread(taskExport).start();
+            }
+        }
+
+    }
+
+    private void newStepObsImport(StepFile step, int replicateID) {
         File fileImport = getFile(MainApp.primaryStage);
         if (fileImport == null) {
             return;
         }
         MainApp.logger.info("start importing/create file " + fileImport.getName());
-        Report r = step.checkCreateObservationFromXLSX(fileImport);
+        Report r = step.checkCreateObservationFromXLSX(fileImport, replicateID);
         if(r.success()) {
-            ObservationFile obs = step.createObservationFromXLSX(fileImport);
+            ObservationFile obs = step.createObservationFromXLSX(fileImport, replicateID);
             handleInterfaceUpdate(obs.getStepFile().getGeneralFile(), r.success(), "File import completed");
             MainApp.getDataControler().selectNode(obs);
             MainApp.logger.info("import done with sucess");
@@ -345,10 +733,38 @@ public class DataTreeCell extends TextFieldTreeCell<DataNode> {
         }
     }
 
+    private static void handleInterfaceUpdate(GeneralFile file, boolean reportBoolean, String reportString) {
+        if(reportBoolean) {
+            MainApp.getDataControler().buildProcessTree(file);
+            showOkImportAlert();
+        } else {
+            showErrorImportAlert(reportString);
+        }
+    }
+
+    private static void showErrorImportAlert(String report) {
+        Alert errorImport = new Alert(Alert.AlertType.ERROR);
+        errorImport.setTitle("Import error");
+        errorImport.setContentText(report);
+        errorImport.initModality(Modality.APPLICATION_MODAL);
+        errorImport.initOwner(MainApp.primaryStage);
+        errorImport.showAndWait();
+    }
+
+    private static void showOkImportAlert() {
+        Alert okImport = new Alert(Alert.AlertType.INFORMATION);
+        okImport.setGraphic(new ImageView(UITools.getImage("resources/images/valid.png")));
+        okImport.setHeaderText(null);
+        okImport.setTitle("Successful import");
+        okImport.setContentText("Successful import");
+        okImport.initModality(Modality.APPLICATION_MODAL);
+        okImport.initOwner(MainApp.primaryStage);
+        okImport.showAndWait();
+    }
+
     @Override
     public void updateItem(DataNode item, boolean empty) {
         super.updateItem(item, empty);
-
         if (empty || item == null) {
             setText(null);
             setGraphic(null);
@@ -356,30 +772,41 @@ public class DataTreeCell extends TextFieldTreeCell<DataNode> {
             setContextMenu(null);
         } else {
             setText(item.toString());
-            if(/*!item.getType().equals(DataNodeType.ITINERARY) && */item.getFile() != null) {
+            if(item.getFile() != null) {
                 if(item.getFile().isSelectedInTree()) {
                     setBackground(new Background(new BackgroundFill(Color.DEEPSKYBLUE,CornerRadii.EMPTY,Insets.EMPTY)));
                 } else {
                     setBackground(null);
                 }
+            }
+            if (item.getType().equals(DataNodeType.PROCESS)) {
+                GeneralFile processFile = (GeneralFile)item.getFile();
+//                setContentDisplay(ContentDisplay.RIGHT);
+                if(processFile.getListReplicate().size() > 1) {
+                    Label l = new Label();
+                    l.textProperty().bind(item.nameProperty());
+                    ComboBox<Replicate> comboReplicate = new ComboBox<>();
+                    comboReplicate.setItems(processFile.getListReplicate());
+                    if(processFile.getCurrentReplicate() != null) {
+                        comboReplicate.setValue(processFile.getCurrentReplicate());
+                    }
 
+                    comboReplicate.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
+                        if(newValue != null && newValue != oldValue) {
+                            processFile.setCurrentReplicate(newValue);
+                            if(MainApp.getDataControler().getTree().getSelectionModel().getSelectedItem() != null) {
+                                DataNode currentSelectedNode = MainApp.getDataControler().getTree().getSelectionModel().getSelectedItem().getValue();
+                                if(currentSelectedNode.getType().equals(DataNodeType.OBSERVATION) || currentSelectedNode.getType().equals(DataNodeType.STEP) || currentSelectedNode.getType().equals(DataNodeType.PROCESS) ) {
+                                    MainApp.getDataControler().showNodeDetails(currentSelectedNode, currentSelectedNode);
+                                }
+                            }
+                        }
+                    });
+                    setText("");
+                    setGraphic(new HBox(item.getGraphic(), l, comboReplicate));
+                }
             }
 
-//            if(item.getType().equals(DataNodeType.ITINERARY) ) {
-//                if(item.getItineraryFile().getItiPart().isSelectedInTree()) {
-//                    setBackground(new Background(new BackgroundFill(Color.DEEPSKYBLUE,CornerRadii.EMPTY,Insets.EMPTY)));
-//                } else {
-//                    setBackground(null);
-//                }
-//             }
-//            if(item.getItineraryPart() != null) {
-//                if(item.getItineraryPart().isSelectedInTree()) {
-//                    setBackground(new Background(new BackgroundFill(Color.LIGHTGRAY,CornerRadii.EMPTY,Insets.EMPTY)));
-//                } else {
-//                    setBackground(null);
-//                }
-//
-//            }
             setEditable(false);
             ContextMenu menu = new ContextMenu();
             switch (item.getType()) {
@@ -658,6 +1085,19 @@ public class DataTreeCell extends TextFieldTreeCell<DataNode> {
                     menu.getItems().add(downloadSHACLConstraints);
                     break;
                 case PROCESS:
+                    MenuItem newRep = new MenuItem("New biological replicate");
+                    newRep.setGraphic(new ImageView(UITools.getImage("resources/images/treeview/replicate_16.png")));
+                    newRep.disableProperty().bind(Bindings.not(mainApp.getEditProperty()));
+                    newRep.setOnAction(event -> {
+                        GeneralFile current = (GeneralFile) item.getFile();
+                        Replicate newReplicate = current.addReplicate("new replicate", "");
+                        if(newReplicate != null) {
+                            current.setCurrentReplicate(newReplicate);
+                            MainApp.getDataControler().showNodeDetails(getItem(), getItem());
+                        }
+                    });
+                    menu.getItems().add(newRep);
+
                     Menu newIti = new Menu("New Itinerary");
                     newIti.setGraphic(new ImageView(UITools.getImage("resources/images/treeview/itinerary.png")));
                     newIti.disableProperty().bind(Bindings.not(mainApp.getEditProperty()));
@@ -752,6 +1192,7 @@ public class DataTreeCell extends TextFieldTreeCell<DataNode> {
                     menu.getItems().add(deleteProcess);
                     break;
                 case OBSERVATION:
+                    ObservationFile obsFile = (ObservationFile) item.getFile();
                     MenuItem addDataObs = new MenuItem("New Data Table");
                     addDataObs.setGraphic(new ImageView(UITools.getImage("resources/images/add_16.png")));
                     addDataObs.disableProperty().bind(Bindings.not(mainApp.getEditProperty()));
@@ -797,166 +1238,78 @@ public class DataTreeCell extends TextFieldTreeCell<DataNode> {
                     });
                     menu.getItems().add(addDataObs);
 
-                    MenuItem exportObs = new MenuItem("Export Observation");
-                    exportObs.setGraphic(new ImageView(UITools.getImage("resources/images/file-export-16.png")));
-                    exportObs.setOnAction(event -> {
-
-                        List<String> choices = new ArrayList<>();
-                        choices.add("with ontology");
-                        choices.add("without ontology");
-                        ChoiceDialog<String> dialog = new ChoiceDialog<>("without ontology", choices);
-                        dialog.setTitle("Export Observation");
-                        dialog.setHeaderText(null);
-                        dialog.setContentText("Export Observation data ");
-                        dialog.initModality(Modality.WINDOW_MODAL);
-                        dialog.initOwner(MainApp.primaryStage);
-                        Boolean exportOnto = false;
-                        Optional<String> result = dialog.showAndWait();
-
-                        if (result.isPresent() ) {
-                            exportOnto = result.get().equals("with ontology");
-                            Boolean finalExportOnto = exportOnto;
-                            if (exportOnto && mainApp.getOntologyControler().getCurrentOntology() == null) {
-                                Alert noOntology = new Alert(Alert.AlertType.ERROR);
-                                noOntology.setTitle("No ontology loaded");
-                                noOntology.setHeaderText("Please load an ontology");
-                                noOntology.setContentText("In order to create an export file, please load the corresponding ontology");
-                                noOntology.initOwner(MainApp.primaryStage);
-                                noOntology.initModality(Modality.APPLICATION_MODAL);
-                                noOntology.showAndWait();
-                            } else {
-                                ObservationFile file = (ObservationFile) item.getFile();
-                                XSSFWorkbook book = new XSSFWorkbook();
-
-
-                                Task<Boolean> taskExport = new Task<Boolean>() {
-                                    @Override
-                                    protected Boolean call() throws Exception {
-                                        XSSFSheet sheet = Tools.createSheet(book,"obs|"+Tools.removeNonAlphaNumChar(file.getNameProperty().getValue()));
-
-                                        Integer compteur = 0;
-                                        Integer maxColumn = 0;
-                                        for (LinkedList<String> line : file.getDataForExcel()) {
-                                            XSSFRow r = sheet.createRow(compteur++);
-                                            Integer compteurCell = 0;
-                                            for (String val : line) {
-                                                r.createCell(compteurCell++).setCellValue(val);
-                                                maxColumn = Math.max(maxColumn, compteurCell);
-                                            }
-                                        }
-                                        Tools.autoResize(sheet, maxColumn);
+                    GeneralFile processFile = null;
+                    if(obsFile.getStepFile() != null) {
+                        processFile = obsFile.getStepFile().getGeneralFile();
+                    } else {
+                        processFile = obsFile.getItineraryFile().getProcessFile();
+                    }
 
+                    if(processFile.getListReplicate().size() > 1) {
+                        Menu exportObs = new Menu("Export Observation");
+                        exportObs.setGraphic(new ImageView(UITools.getImage("resources/images/file-export-16.png")));
 
-                                        if(finalExportOnto) {
+                        MenuItem exportCurRep = new MenuItem("for current replicate");
+                        GeneralFile finalProcessFile = processFile;
+                        exportCurRep.setOnAction(event -> {
+                            exportObservation(obsFile, finalProcessFile.getCurrentReplicate().getId());
+                        });
+                        MenuItem exportAllRep = new MenuItem("for all replicates");
+                        exportAllRep.setOnAction(event -> {
+                            exportObservation(obsFile, -1);
+                        });
 
-                                            JSONObject hierarchyVocab = mainApp.getOntologyControler().getHierarchyVocabJSON();
-                                            // Récupération de l'ontology au format JSON
-                                            XSSFSheet sheetOntoVocab = Tools.createSheet(book,"onto-vocab|" + Tools.removeNonAlphaNumChar(mainApp.getOntologyControler().getCurrentOntology().getName().getValue()));
-                                            JSONArray vocab = (JSONArray) hierarchyVocab.get("vocabulary");
+                        exportObs.getItems().add(exportCurRep);
+                        exportObs.getItems().add(exportAllRep);
+                        menu.getItems().add(exportObs);
+                    } else {
+                        MenuItem exportObs = new MenuItem("Export Observation");
+                        exportObs.setGraphic(new ImageView(UITools.getImage("resources/images/file-export-16.png")));
+                        exportObs.setOnAction(event -> {
+                            exportObservation(obsFile, 0);
+                        });
+                        menu.getItems().add(exportObs);
+                    }
 
-                                            compteur = 0;
-                                            maxColumn = 0;
-                                            for (
-                                                    int i = 0; i < vocab.length(); i++) {
-                                                JSONArray array = (JSONArray) vocab.get(i);
-                                                XSSFRow r = sheetOntoVocab.createRow(compteur++);
-                                                for (int j = 0; j < array.length(); j++) {
-                                                    r.createCell(j).setCellValue((String) array.get(j));
-                                                    maxColumn = Math.max(maxColumn, j);
-                                                }
-                                            }
-                                            Tools.autoResize(sheetOntoVocab, maxColumn);
 
 
-                                            XSSFSheet sheetOntohierarchy = Tools.createSheet(book,"onto-hierarchy|" + Tools.removeNonAlphaNumChar(mainApp.getOntologyControler().getCurrentOntology().getName().getValue()));
-                                            JSONArray hierarchy = (JSONArray) hierarchyVocab.get("hierarchy");
 
-                                            compteur = 0;
-                                            maxColumn = 0;
+                    if(processFile.getListReplicate().size() > 1) {
+                        Menu importObs = new Menu("Import Observation");
+                        importObs.disableProperty().bind(Bindings.not(mainApp.getEditProperty()));
+                        importObs.setGraphic(new ImageView(UITools.getImage("resources/images/file-import-16.png")));
 
-                                            for (
-                                                    int x = 0; x < hierarchy.length(); x++) {
-                                                XSSFRow r = sheetOntohierarchy.createRow(compteur++);
-                                                JSONArray arrayDesc = (JSONArray) hierarchy.get(x);
-                                                for (int j = 0; j < arrayDesc.length(); j++) {
-                                                    r.createCell(j).setCellValue((String) arrayDesc.get(j));
-                                                    maxColumn = Math.max(maxColumn, j);
-                                                }
-                                            }
-                                            Tools.autoResize(sheetOntohierarchy, maxColumn);
-                                        }
-                                        return true;
-                                    }
-                                };
-                                taskExport.setOnSucceeded(workerStateEvent -> {
-                                    FileChooser fileChooser = new FileChooser();
-                                    fileChooser.setTitle("Export file");
-                                    fileChooser.setInitialFileName(file.getFileName()+".xlsx");
-                                    File fileExport = fileChooser.showSaveDialog(MainApp.primaryStage);
-                                    if (fileExport != null) {
-                                        try {
-                                            FileOutputStream fout = new FileOutputStream(fileExport, false);
-                                            book.write(fout);
-                                            fout.close();
-                                        } catch (IOException ex) {
-                                            MainApp.logger.error(ex.getMessage());
-                                        }
-                                    }
-                                });
-                                new Thread(taskExport).start();
-                            }
-                        }
-                    });
-                    menu.getItems().add(exportObs);
-
-                    MenuItem importObs = new MenuItem("Import Observation");
-                    importObs.setGraphic(new ImageView(UITools.getImage("resources/images/file-import-16.png")));
-                    importObs.disableProperty().bind(Bindings.not(mainApp.getEditProperty()));
-                    importObs.setOnAction(event -> {
-                        ObservationFile file = (ObservationFile) item.getFile();
-                        File fileImport = getFile(mainApp.primaryStage);
-                        if (fileImport != null) {
-                            MainApp.logger.info("start importing/update file " + fileImport.getName());
-                            // temp obs file
-                            ObservationFile tempF = null;
-                            if(file.getStepFile() != null) {
-                                Report r = file.getStepFile().checkUpdateObservationFromXLSX(fileImport, file);
-                                if(r.success()) {
-                                    file.getStepFile().updateObservationFromXLSX(fileImport, file);
-                                    MainApp.getDataControler().refreshTree();
-                                    MainApp.getDataControler().showNodeDetails(file, file);
-                                    MainApp.logger.info("import done with sucess");
-                                } else {
-                                    showErrorImportAlert(r.prettyPrintError());
-                                }
-                            }
-                            if(file.getItineraryFile() != null) {
-                                Report r = file.getItineraryFile().checkUpdateObservationFromXLSX(fileImport, file);
-                                if(r.success()) {
-                                    file.getItineraryFile().updateObservationFromXLSX(fileImport, file);
-                                    MainApp.getDataControler().refreshTree();
-                                    MainApp.getDataControler().showNodeDetails(file, file);
-                                    MainApp.logger.info("import done with sucess");
-                                } else {
-                                    showErrorImportAlert(r.prettyPrintError());
-                                }
-                            }
-                        }
-                    });
-                    menu.getItems().add(importObs);
+                        MenuItem importCurRep = new MenuItem("for current replicate");
+                        importCurRep.disableProperty().bind(Bindings.not(mainApp.getEditProperty()));
+                        GeneralFile finalProcessFile = processFile;
+                        importCurRep.setOnAction(event -> {
+                            importObservation(obsFile, finalProcessFile.getCurrentReplicate().getId());
+                        });
+                        MenuItem importAllRep = new MenuItem("for all replicates");
+                        importAllRep.disableProperty().bind(Bindings.not(mainApp.getEditProperty()));
+                        importAllRep.setOnAction(event -> {
+                            importObservation(obsFile, -1);
+                        });
+
+                        importObs.getItems().add(importCurRep);
+                        importObs.getItems().add(importAllRep);
+                        menu.getItems().add(importObs);
+                    } else {
+                        MenuItem importObs = new MenuItem("Import Observation");
+                        importObs.disableProperty().bind(Bindings.not(mainApp.getEditProperty()));
+                        importObs.setGraphic(new ImageView(UITools.getImage("resources/images/file-import-16.png")));
+                        importObs.setOnAction(event -> {
+                            importObservation(obsFile, 0);
+                        });
+                        menu.getItems().add(importObs);
+                    }
 
                     MenuItem moveObs = new MenuItem("Move Observation");
                     moveObs.setGraphic(new ImageView(UITools.getImage("resources/images/move_16.png")));
                     moveObs.disableProperty().bind(Bindings.not(mainApp.getEditProperty()));
                     menu.getItems().add(moveObs);
+                    GeneralFile finalProcessFile2 = processFile;
                     moveObs.setOnAction(event -> {
-                        ObservationFile obsFile = (ObservationFile) item.getFile();
-                        GeneralFile processFile = null;
-                        if(obsFile.getStepFile() != null) {
-                            processFile = obsFile.getStepFile().getGeneralFile();
-                        } else {
-                            processFile = obsFile.getItineraryFile().getProcessFile();
-                        }
                         Dialog<ButtonType> moveObsDiag = new Dialog<>();
                         moveObsDiag.getDialogPane().setPrefSize(500, 400);
                         moveObsDiag.initModality(Modality.WINDOW_MODAL);
@@ -970,7 +1323,7 @@ public class DataTreeCell extends TextFieldTreeCell<DataNode> {
                         treeStep.setCellFactory(factory -> new TextFieldTreeCell<>(){});
 
                         treeStep.setShowRoot(false);
-                        processFile.getItinerary().forEach(itiFile -> {
+                        finalProcessFile2.getItinerary().forEach(itiFile -> {
                             TreeItem<GenericFile> ckIti = new TreeItem<>(itiFile);
                             fakeRoot.getChildren().add(ckIti);
                             itiFile.getListStep().forEach(step -> {
@@ -1044,7 +1397,7 @@ public class DataTreeCell extends TextFieldTreeCell<DataNode> {
 
                 case STEP:
                     StepFile s = (StepFile) item.getFile();
-
+                    processFile = s.getGeneralFile();
                     Menu newSubStep = new Menu("New SubStep");
                     newSubStep.setGraphic(new ImageView(UITools.getImage("resources/images/treeview/step.png")));
                     newSubStep.disableProperty().bind(Bindings.not(mainApp.getEditProperty()));
@@ -1067,7 +1420,7 @@ public class DataTreeCell extends TextFieldTreeCell<DataNode> {
                     addProcessSubStepFromCSV.setGraphic(new ImageView(UITools.getImage("resources/images/treeview/step_csv.png")));
                     addProcessSubStepFromCSV.disableProperty().bind(Bindings.not(mainApp.getEditProperty()));
                     addProcessSubStepFromCSV.setOnAction(event -> {
-                        newStepImport(item.getItineraryFile(), s);
+                        newStepImport(item.getItineraryFile(), s, -1);
                     });
 
                     newSubStep.getItems().add(newSubStepFC);
@@ -1098,7 +1451,7 @@ public class DataTreeCell extends TextFieldTreeCell<DataNode> {
                     addNewStepObservationFromCsv.setGraphic(new ImageView(UITools.getImage("resources/images/treeview/observation_csv.png")));
                     addNewStepObservationFromCsv.disableProperty().bind(Bindings.not(mainApp.getEditProperty()));
                     addNewStepObservationFromCsv.setOnAction(event -> {
-                        newStepObsImport(s);
+                        newStepObsImport(s, -1);
                     });
 
                     newObs.getItems().add(newObsFC);
@@ -1210,9 +1563,10 @@ public class DataTreeCell extends TextFieldTreeCell<DataNode> {
                     moveStep.setDisable(false);
                     moveStep.disableProperty().bind(Bindings.not(mainApp.getEditProperty()));
                     moveStep.setGraphic(new ImageView(UITools.getImage("resources/images/move_16.png")));
+                    GeneralFile finalProcessFile1 = processFile;
                     moveStep.setOnAction(event -> {
                         StepFile stepFile = (StepFile) item.getFile();
-                        GeneralFile processFile = stepFile.getGeneralFile();
+//                        GeneralFile processFile = stepFile.getGeneralFile();
 
                         Dialog<ButtonType> moveStepDiag = new Dialog<>();
                         moveStepDiag.getDialogPane().setPrefSize(500, 400);
@@ -1227,7 +1581,7 @@ public class DataTreeCell extends TextFieldTreeCell<DataNode> {
                         treeStep.setCellFactory(factory -> new TextFieldTreeCell<>(){});
 
                         treeStep.setShowRoot(false);
-                        processFile.getItinerary().forEach(itiFile -> {
+                        finalProcessFile1.getItinerary().forEach(itiFile -> {
                             TreeItem<GenericFile> ckIti = new TreeItem<>(itiFile);
                             fakeRoot.getChildren().add(ckIti);
                             itiFile.getListStep().forEach(step -> {
@@ -1268,12 +1622,12 @@ public class DataTreeCell extends TextFieldTreeCell<DataNode> {
                                     if(moveTo instanceof StepFile) {
                                         StepFile stepFileFather = (StepFile) moveTo;
                                         stepFileFather.addSubStep(stepFile);
-                                        for(ItineraryFile iti : processFile.getItinerary()) {
+                                        for(ItineraryFile iti : finalProcessFile1.getItinerary()) {
                                             if(iti.contains(stepFileFather)) {
                                                 iti.addStep(stepFile);
                                             }
                                         }
-                                        MainApp.getDataControler().buildProcessTree(processFile);
+                                        MainApp.getDataControler().buildProcessTree(finalProcessFile1);
                                     }
                                     MainApp.getDataControler().selectNode(stepFile);
                                 }
@@ -1284,154 +1638,59 @@ public class DataTreeCell extends TextFieldTreeCell<DataNode> {
                     menu.getItems().add(moveStep);
 
 
-                    MenuItem exportStep = new MenuItem("Export Step");
-                    exportStep.setDisable(false);
-                    exportStep.setGraphic(new ImageView(UITools.getImage("resources/images/file-export-16.png")));
-                    exportStep.setOnAction(event -> {
-                        List<String> choices = new ArrayList<>();
-                        choices.add("with ontology");
-                        choices.add("without ontology");
-                        ChoiceDialog<String> dialog = new ChoiceDialog<>("without ontology", choices);
-                        dialog.setTitle("Export Step");
-                        dialog.setHeaderText(null);
-                        dialog.setContentText("Export step data ");
-                        dialog.initModality(Modality.WINDOW_MODAL);
-                        dialog.initOwner(MainApp.primaryStage);
-                        Boolean exportOnto = false;
-                        Optional<String> result = dialog.showAndWait();
-
-                        if (result.isPresent() ) {
-                            exportOnto = result.get().equals("with ontology");
-                            if(exportOnto && mainApp.getOntologyControler().getCurrentOntology() == null) {
-                                Alert noOntology = new Alert(Alert.AlertType.ERROR);
-                                noOntology.setTitle("No ontology loaded");
-                                noOntology.setHeaderText("Please load an ontology");
-                                noOntology.setContentText("In order to create an export file, please load the corresponding ontology");
-                                noOntology.initOwner(MainApp.primaryStage);
-                                noOntology.initModality(Modality.APPLICATION_MODAL);
-                                noOntology.showAndWait();
-                            } else {
-                                XSSFWorkbook book = new XSSFWorkbook();
-                                Boolean finalExportOnto = exportOnto;
-                                Task<Boolean> taskExport = new Task<Boolean>() {
-                                    @Override
-                                    protected Boolean call() throws Exception {
-                                        XSSFSheet sheet = Tools.createSheet(book,"step|"+ DigestUtils.md5Hex(s.getNameProperty().getValue()));
-
-                                        Integer compteur = 0;
-                                        Integer maxColumn = 0;
-
-                                        for (LinkedList<String> line : s.getDataForExcel(true)) {
-                                            XSSFRow r = sheet.createRow(compteur++);
-                                            Integer compteurCell = 0;
-                                            for (String val : line) {
-                                                r.createCell(compteurCell++).setCellValue(val);
-                                                maxColumn = Math.max(maxColumn, compteurCell);
-                                            }
-                                        }
-
-
-                                        // composition
-                                        for (Map.Entry<CompositionFile, Boolean> entry : s.getCompositionFile().entrySet()) {
-                                            XSSFSheet sheetCompo = Tools.createSheet(book,"compo-"+(entry.getValue() ? "input" : "output")+"|"+Tools.removeNonAlphaNumChar(entry.getKey().getCompositionID().getValue().get()));
-                                            Integer compteurCompo = 0;
-                                            Integer maxColumnCompo = 0;
-                                            for (LinkedList<String> line : entry.getKey().getDataForExcel()) {
-                                                XSSFRow r = sheetCompo.createRow(compteurCompo++);
-                                                Integer compteurCell = 0;
-                                                for (String val : line) {
-                                                    r.createCell(compteurCell++).setCellValue(val);
-                                                    maxColumnCompo = Math.max(maxColumnCompo, compteurCell);
-                                                }
-                                            }
-                                            Tools.autoResize(sheetCompo, maxColumnCompo);
-                                        }
-
-
+                    if(processFile.getListReplicate().size() > 1) {
+                        Menu exportStep = new Menu("Export Step");
+                        exportStep.setGraphic(new ImageView(UITools.getImage("resources/images/file-export-16.png")));
 
-                                        Tools.autoResize(sheet, maxColumn);
-
-                                        for(ObservationFile obs : s.getObservationFiles()) {
-                                            XSSFSheet sheetObs = Tools.createSheet(book,"obs|"+Tools.removeNonAlphaNumChar(obs.getCID().getValue().get()));
-
-                                            Integer compteurObs = 0;
-                                            Integer maxColumnObs = 0;
-                                            for (LinkedList<String> line : obs.getDataForExcel()) {
-                                                XSSFRow r = sheetObs.createRow(compteurObs++);
-                                                Integer compteurCell = 0;
-                                                for (String val : line) {
-                                                    r.createCell(compteurCell++).setCellValue(val);
-                                                    maxColumnObs = Math.max(maxColumnObs, compteurCell);
-                                                }
-                                            }
-                                            Tools.autoResize(sheetObs, maxColumnObs);
-                                        }
+                        MenuItem exportCurRep = new MenuItem("for current replicate");
+                        GeneralFile finalProcessFile = processFile;
+                        exportCurRep.setOnAction(event -> {
+                            exportStepFile(s, finalProcessFile.getCurrentReplicate().getId());
+                        });
+                        MenuItem exportAllRep = new MenuItem("for all replicates");
+                        exportAllRep.setOnAction(event -> {
+                            exportStepFile(s, -1);
+                        });
 
-                                        if(finalExportOnto) {
-
-                                            JSONObject hierarchyVocab = mainApp.getOntologyControler().getHierarchyVocabJSON();
-                                            // Récupération de l'ontology au format JSON
-                                            XSSFSheet sheetOntoVocab = Tools.createSheet(book,"onto-vocab|" + Tools.removeNonAlphaNumChar(mainApp.getOntologyControler().getCurrentOntology().getName().getValue()));
-                                            JSONArray vocab = (JSONArray) hierarchyVocab.get("vocabulary");
-
-                                            compteur = 0;
-                                            maxColumn = 0;
-                                            for (int i = 0; i < vocab.length(); i++) {
-                                                JSONArray array = (JSONArray) vocab.get(i);
-                                                XSSFRow r = sheetOntoVocab.createRow(compteur++);
-                                                for (int j = 0; j < array.length(); j++) {
-                                                    r.createCell(j).setCellValue((String) array.get(j));
-                                                    maxColumn = Math.max(maxColumn, j);
-                                                }
-                                            }
-                                            Tools.autoResize(sheetOntoVocab, maxColumn);
+                        exportStep.getItems().add(exportCurRep);
+                        exportStep.getItems().add(exportAllRep);
+                        menu.getItems().add(exportStep);
+                    } else {
+                        MenuItem exportStep = new MenuItem("Export Step");
+                        exportStep.setGraphic(new ImageView(UITools.getImage("resources/images/file-export-16.png")));
+                        exportStep.setOnAction(event -> {
+                            exportStepFile(s, 0);
+                        });
+                        menu.getItems().add(exportStep);
+                    }
 
 
-                                            XSSFSheet sheetOntohierarchy = Tools.createSheet(book,"onto-hierarchy|" + Tools.removeNonAlphaNumChar(mainApp.getOntologyControler().getCurrentOntology().getName().getValue()));
-                                            JSONArray hierarchy = (JSONArray) hierarchyVocab.get("hierarchy");
+                    if(processFile.getListReplicate().size() > 1) {
+                        Menu importStep = new Menu("Import Step");
+                        importStep.setGraphic(new ImageView(UITools.getImage("resources/images/file-import-16.png")));
 
-                                            compteur = 0;
-                                            maxColumn = 0;
+                        MenuItem importCurRep = new MenuItem("for current replicate");
+                        GeneralFile finalProcessFile = processFile;
+                        importCurRep.setOnAction(event -> {
+                            stepImport(s, false, finalProcessFile.getCurrentReplicate().getId());
+                        });
+                        MenuItem importAllRep = new MenuItem("for all replicates");
+                        importAllRep.setOnAction(event -> {
+                            stepImport(s, false, -1);
+                        });
 
-                                            for (int x = 0; x < hierarchy.length(); x++) {
-                                                XSSFRow r = sheetOntohierarchy.createRow(compteur++);
-                                                JSONArray arrayDesc = (JSONArray) hierarchy.get(x);
-                                                for (int j = 0; j < arrayDesc.length(); j++) {
-                                                    r.createCell(j).setCellValue((String) arrayDesc.get(j));
-                                                    maxColumn = Math.max(maxColumn, j);
-                                                }
-                                            }
-                                            Tools.autoResize(sheetOntohierarchy, maxColumn);
-                                        }
-                                        return true;
-                                    }
-                                };
-                                taskExport.setOnSucceeded(workerStateEvent -> {
-                                    FileChooser fileChooser = new FileChooser();
-                                    fileChooser.setTitle("Export file");
-                                    fileChooser.setInitialFileName(s.getNameProperty().getValue()+".xlsx");
-                                    File fileExport = fileChooser.showSaveDialog(MainApp.primaryStage);
-                                    if (fileExport != null) {
-                                        try {
-                                            FileOutputStream fout = new FileOutputStream(fileExport, false);
-                                            book.write(fout);
-                                            fout.close();
-                                        } catch (IOException ex) {
-                                            MainApp.logger.error(ex.getMessage());
-                                        }
-                                    }
-                                });
-                                new Thread(taskExport).start();
-                            }
-                        }
-                    });
-                    menu.getItems().add(exportStep);
+                        importStep.getItems().add(importCurRep);
+                        importStep.getItems().add(importAllRep);
+                        menu.getItems().add(importStep);
+                    } else {
+                        MenuItem importStep = new MenuItem("Export Step");
+                        importStep.setGraphic(new ImageView(UITools.getImage("resources/images/file-export-16.png")));
+                        importStep.setOnAction(event -> {
+                            stepImport(s, false, 0);
+                        });
+                        menu.getItems().add(importStep);
+                    }
 
-                    MenuItem importStep = new MenuItem("Import Step");
-                    importStep.setGraphic(new ImageView(UITools.getImage("resources/images/file-import-16.png")));
-                    importStep.disableProperty().bind(Bindings.not(mainApp.getEditProperty()));
-                    importStep.setOnAction(event -> stepImport((StepFile) item.getFile(), false));
-                    menu.getItems().add(importStep);
 
                     MenuItem deleteStepButton = new MenuItem("Delete Step");
                     deleteStepButton.setGraphic(new ImageView(UITools.getImage("resources/images/del_16.png")));
@@ -1537,7 +1796,7 @@ public class DataTreeCell extends TextFieldTreeCell<DataNode> {
                     addProcessStepFromCSV.disableProperty().bind(Bindings.not(mainApp.getEditProperty()));
                     addProcessStepFromCSV.setOnAction(event -> {
                         ItineraryFile iti = (ItineraryFile) item.getFile();
-                        newStepImport(iti, null);
+                        newStepImport(iti, null, -1);
                     });
 
                     newStep.getItems().add(addProcessStep);
@@ -1573,7 +1832,7 @@ public class DataTreeCell extends TextFieldTreeCell<DataNode> {
                     addNewItineraryObservationFromCsv.disableProperty().bind(Bindings.not(mainApp.getEditProperty()));
                     addNewItineraryObservationFromCsv.setOnAction(event -> {
                         ItineraryFile iti = (ItineraryFile) item.getFile();
-                        newItineraryObsImport(iti);
+                        newItineraryObsImport(iti, -1);
                     });
 
                     newObsIti.getItems().add(newObsItiFC);
@@ -1593,136 +1852,4 @@ public class DataTreeCell extends TextFieldTreeCell<DataNode> {
             this.setContextMenu(menu);
         }
     }
-
-        private static void stepImport(StepFile file, boolean isNewStep) {
-            File fileImport = getFile(MainApp.primaryStage);
-            if (fileImport != null) {
-            MainApp.logger.info("start importing file " + fileImport.getName());
-            ImportReport importReport = file.realPreConst(fileImport, isNewStep);
-            if(importReport.success()) {
-
-                // validation de l'import par l'utilisateur
-                Dialog<ButtonType> validateImport = new Dialog();
-                validateImport.setTitle("import validation");
-                validateImport.initOwner(MainApp.primaryStage);
-                validateImport.initModality(Modality.WINDOW_MODAL);
-                ButtonType importButtonType = new ButtonType("Import", ButtonBar.ButtonData.OK_DONE);
-                validateImport.getDialogPane().getButtonTypes().addAll(importButtonType, ButtonType.CANCEL);
-
-                GridPane paneImport = new GridPane();
-                paneImport.setHgap(20);
-                paneImport.setVgap(20);
-
-                Integer comptLine = 0;
-                Text stepText = new Text(file.getNameProperty().getValue());
-                Text sepa = new Text(" : ");
-                paneImport.add(new ImageView(UITools.getImage("resources/images/treeview/step.png")), 0, comptLine);
-                paneImport.add(stepText, 1, comptLine);
-                paneImport.add(sepa, 2, comptLine);
-                paneImport.add(new ImageView(UITools.getImage("resources/images/update_30.png")), 3, comptLine);
-
-                comptLine++;
-
-
-                for (ObservationFile obsF : file.getObservationFiles()) {
-                    Text obsText = new Text(obsF.getCID().getValue().get());
-                    Text sepa2 = new Text(" : ");
-                    paneImport.add(new ImageView(UITools.getImage("resources/images/treeview/observation.png")), 0, comptLine);
-                    paneImport.add(obsText, 1, comptLine);
-                    paneImport.add(sepa2, 2, comptLine);
-                    if (importReport.getObsMapping().containsValue(obsF)) {
-                        paneImport.add(new ImageView(UITools.getImage("resources/images/update_30.png")), 3, comptLine);
-                    } else {
-                        paneImport.add(new ImageView(UITools.getImage("resources/images/del_30.png")), 3, comptLine);
-                    }
-                    comptLine++;
-                }
-
-                for(XSSFSheet oo : importReport.getObsMapping().keySet()) {
-                    if(importReport.getObsMapping().get(oo) == null) { // new obs
-                        Text obsText = new Text(oo.getSheetName());
-                        Text sepa2 = new Text(" : ");
-                        paneImport.add(new ImageView(UITools.getImage("resources/images/treeview/observation.png")), 0, comptLine);
-                        paneImport.add(obsText, 1, comptLine);
-                        paneImport.add(sepa2, 2, comptLine);
-                        paneImport.add(new ImageView(UITools.getImage("resources/images/add_30.png")), 3, comptLine);
-                        comptLine++;
-                    }
-                }
-
-                for (CompositionFile compoF : file.getCompositionFile().keySet()) {
-                    Text compoText = new Text(compoF.getCompositionID().getValue().get());
-                    Text sepa2 = new Text(" : ");
-                    paneImport.add(new ImageView(UITools.getImage("resources/images/treeview/composition.png")), 0, comptLine);
-                    paneImport.add(compoText, 1, comptLine);
-                    paneImport.add(sepa2, 2, comptLine);
-                    if(importReport.getCompoMapping().values().stream().map(org.apache.commons.lang3.tuple.Pair::getLeft).noneMatch(c -> c.equals(compoF))) {
-                        paneImport.add(new ImageView(UITools.getImage("resources/images/del_30.png")), 3, comptLine);
-                    } else {
-                        paneImport.add(new ImageView(UITools.getImage("resources/images/update_30.png")), 3, comptLine);
-                    }
-                    comptLine++;
-                }
-
-                for(XSSFSheet oo : importReport.getCompoMapping().keySet()) {
-                    if(importReport.getCompoMapping().get(oo).getLeft() == null) { // new Compo
-                        Text compoText = new Text(oo.getSheetName());
-                        Text sepa2 = new Text(" : ");
-                        paneImport.add(new ImageView(UITools.getImage("resources/images/treeview/composition.png")), 0, comptLine);
-                        paneImport.add(compoText, 1, comptLine);
-                        paneImport.add(sepa2, 2, comptLine);
-                        paneImport.add(new ImageView(UITools.getImage("resources/images/add_30.png")), 3, comptLine);
-                        comptLine++;
-                    }
-                }
-
-                validateImport.getDialogPane().setContent(paneImport);
-                Optional<ButtonType> result = Optional.empty();
-                if(!isNewStep) {
-                    result = validateImport.showAndWait();
-                }
-                if (isNewStep || result.isPresent() && result.get() == importButtonType) {
-                    // l'utilisateur valide la la mise à jour
-                    Report report = file.constructDataFromImport(fileImport, isNewStep);
-                    handleInterfaceUpdate(file.getGeneralFile(), report.success(), report.toString());
-                    MainApp.getDataControler().selectNode(file);
-                }
-
-            } else {
-                showErrorImportAlert(importReport.toString());
-            }
-        } else {
-        }
-    }
-
-    private static void handleInterfaceUpdate(GeneralFile file, boolean reportBoolean, String reportString) {
-        if(reportBoolean) {
-            MainApp.getDataControler().buildProcessTree(file);
-            showOkImportAlert();
-        } else {
-            showErrorImportAlert(reportString);
-        }
-    }
-
-    private static void showErrorImportAlert(String report) {
-        Alert errorImport = new Alert(Alert.AlertType.ERROR);
-        errorImport.setTitle("Import error");
-        errorImport.setContentText(report);
-        errorImport.initModality(Modality.APPLICATION_MODAL);
-        errorImport.initOwner(MainApp.primaryStage);
-        errorImport.showAndWait();
-    }
-
-    private static void showOkImportAlert() {
-        Alert okImport = new Alert(Alert.AlertType.INFORMATION);
-        okImport.setGraphic(new ImageView(UITools.getImage("resources/images/valid.png")));
-        okImport.setHeaderText(null);
-        okImport.setTitle("Successful import");
-        okImport.setContentText("Successful import");
-        okImport.initModality(Modality.APPLICATION_MODAL);
-        okImport.initOwner(MainApp.primaryStage);
-        okImport.showAndWait();
-    }
-
-
 }
diff --git a/src/main/java/fr/inra/po2vocabmanager/utils/UITools.java b/src/main/java/fr/inra/po2vocabmanager/utils/UITools.java
index d4ed78b183fd82f9b0180e7da7ea8914797c7031..a087e37f7f999465d4ea4ad978df17a7e26e4dae 100644
--- a/src/main/java/fr/inra/po2vocabmanager/utils/UITools.java
+++ b/src/main/java/fr/inra/po2vocabmanager/utils/UITools.java
@@ -20,9 +20,7 @@ package fr.inra.po2vocabmanager.utils;
 
 import fr.inra.po2vocabmanager.MainApp;
 import fr.inrae.po2engine.externalTools.CloudConnector;
-import fr.inrae.po2engine.model.ComplexField;
-import fr.inrae.po2engine.model.Ontology;
-import fr.inrae.po2engine.model.VocabConcept;
+import fr.inrae.po2engine.model.*;
 import fr.inrae.po2engine.model.dataModel.KeyWords;
 import fr.inrae.po2engine.model.partModel.ComplexTable;
 import fr.inrae.po2engine.model.partModel.GenericTable;
@@ -39,10 +37,12 @@ import javafx.beans.property.ObjectProperty;
 import javafx.beans.property.SimpleObjectProperty;
 import javafx.beans.property.SimpleStringProperty;
 import javafx.beans.property.StringProperty;
+import javafx.beans.value.ChangeListener;
 import javafx.beans.value.ObservableValue;
 import javafx.collections.FXCollections;
 import javafx.collections.MapChangeListener;
 import javafx.collections.ObservableList;
+import javafx.collections.ObservableMap;
 import javafx.collections.transformation.FilteredList;
 import javafx.concurrent.Task;
 import javafx.event.ActionEvent;
@@ -562,13 +562,26 @@ public class UITools {
         tField.styleProperty().bind(Bindings.when(cField.stateProperty().isEqualTo(FieldState.WARNING)).then("-fx-border-color: orange;").otherwise(Bindings.when(cField.stateProperty().isEqualTo(FieldState.ERROR)).then("-fx-border-color: red;").otherwise("")));
     }
     public static void simpleBindValue(ComplexField cField, TextField tField) {
-        cField.getValue().unbind();
+        cField.unbindReplicatesValues();
         tField.setText(cField.getValue().getValue());
         cField.getValue().bind(tField.textProperty());
         tField.styleProperty().unbind();
         tField.styleProperty().bind(Bindings.when(cField.stateProperty().isEqualTo(FieldState.WARNING)).then("-fx-border-color: orange;").otherwise(Bindings.when(cField.stateProperty().isEqualTo(FieldState.ERROR)).then("-fx-border-color: red;").otherwise("")));
     }
 
+    public static void simpleBindValue(ComplexField cField, Replicate replicate, TextField tField) {
+        cField.unbindReplicatesValues();
+        int replicateID = replicate != null ? replicate.getId() : 0;
+        tField.setText(cField.getValueWithReplicate(replicateID).getValue());
+        cField.getValueWithReplicate(replicateID).bind(tField.textProperty());
+        tField.styleProperty().unbind();
+        if(replicate == null) {
+            tField.styleProperty().bind(Bindings.when(cField.stateProperty().isEqualTo(FieldState.WARNING)).then("-fx-border-color: orange;").otherwise(Bindings.when(cField.stateProperty().isEqualTo(FieldState.ERROR)).then("-fx-border-color: red;").otherwise("")));
+        } else {
+            tField.styleProperty().bind(Bindings.when(cField.stateProperty().isEqualTo(FieldState.WARNING)).then("-fx-border-color: orange;").otherwise(Bindings.when(cField.stateProperty().isEqualTo(FieldState.ERROR)).then("-fx-border-color: red;").otherwise("-fx-border-color: DarkSlateBlue;")));
+        }
+    }
+
     public static void simpleBindValue(ComplexField cField, TextArea tField) {
         cField.getValue().unbind();
         tField.setText(cField.getValue().getValue());
@@ -577,6 +590,68 @@ public class UITools {
         tField.styleProperty().bind(Bindings.when(cField.stateProperty().isEqualTo(FieldState.WARNING)).then("-fx-border-color: orange;").otherwise(Bindings.when(cField.stateProperty().isEqualTo(FieldState.ERROR)).then("-fx-border-color: red;").otherwise("")));
     }
 
+    public static void bindComboBoxAgent(ObservableMap<Integer, ObjectProperty<HashMap<KeyWords, ComplexField>>> agentProp, ObservableList<HashMap<KeyWords, ComplexField>> list, Replicate replicate, ComboBox<HashMap<KeyWords, ComplexField>> comboField) {
+        int replicateID = replicate != null ? replicate.getId() : 0;
+        comboField.setConverter(new StringConverter<HashMap<KeyWords, ComplexField>>() {
+            @Override
+            public String toString(HashMap<KeyWords, ComplexField> keyWordsComplexFieldHashMap) {
+                if (keyWordsComplexFieldHashMap == null){
+                    return null;
+                } else {
+                    return Tools.agentToString(keyWordsComplexFieldHashMap);
+                }
+            }
+
+            @Override
+            public HashMap<KeyWords, ComplexField> fromString(String s) {
+                HashMap<KeyWords, ComplexField> val = list.stream().filter(keyWordsComplexFieldHashMap -> {
+                    return s.equalsIgnoreCase(Tools.agentToString(keyWordsComplexFieldHashMap));
+                }).findFirst().orElse(null);
+                return val;
+            }
+        });
+        comboField.setCellFactory(p -> {
+            return new ListCell<HashMap<KeyWords, ComplexField>>() {
+
+                @Override
+                protected void updateItem(HashMap<KeyWords, ComplexField> item, boolean empty) {
+                    super.updateItem(item, empty);
+                    if (item == null || empty) {
+                        setGraphic(null);
+                        setText("");
+                    } else {
+                        setGraphic(null);
+                        setText(Tools.agentToString(item));
+                    }
+                }
+            };
+        });
+
+        comboField.setValue(null);
+        ObservableList<HashMap<KeyWords, ComplexField>> listCopy = FXCollections.observableArrayList();
+        listCopy.add(Tools.createFakeAgentFromString(""));
+
+        agentProp.computeIfAbsent(replicateID, k -> {
+            SimpleObjectProperty sop = new SimpleObjectProperty<>();
+            sop.addListener(Data.changeListener);
+            return sop;
+        } );
+
+        if(!list.contains(agentProp.get(replicateID).getValue())) {
+            if(!Tools.agentToString(agentProp.get(replicateID).getValue()).isBlank()) {
+                listCopy.add(agentProp.get(replicateID).getValue());
+            }
+        }
+        listCopy.addAll(list);
+        comboField.setItems(listCopy);
+        comboField.setValue(agentProp.get(replicateID).getValue());
+        agentProp.get(replicateID).bind(comboField.valueProperty());
+
+        comboField.styleProperty().unbind();
+        BooleanBinding containAgent = Bindings.createBooleanBinding( () -> list.contains( agentProp.get(replicateID).getValue() ) || Tools.agentToString(agentProp.get(replicateID).getValue()).isEmpty(), list, agentProp );
+        comboField.styleProperty().bind(Bindings.when(containAgent).then("-fx-border-color: DarkSlateBlue;").otherwise("-fx-border-color: red;"));
+    }
+
     public static void bindComboBoxAgent(ObjectProperty<HashMap<KeyWords, ComplexField>> agentProp, ObservableList<HashMap<KeyWords, ComplexField>> list, ComboBox<HashMap<KeyWords, ComplexField>> comboField) {
         comboField.setConverter(new StringConverter<HashMap<KeyWords, ComplexField>>() {
             @Override
@@ -631,18 +706,22 @@ public class UITools {
         comboField.styleProperty().bind(Bindings.when(containAgent).then("").otherwise("-fx-border-color: red;"));
     }
 
-    public static void bindTable(GenericTable table, TableView tableView) {
+    public static void bindTable(GenericTable table, Replicate replicate,  TableView tableView) {
         if(table instanceof SimpleTable) {
-            bindSimpleTable((SimpleTable) table, tableView);
+            bindSimpleTable((SimpleTable) table, replicate, tableView);
         }
         if(table instanceof ComplexTable) {
-            bindComplexTable((ComplexTable) table, tableView);
+            bindComplexTable((ComplexTable) table, replicate, tableView);
         }
     }
 
-    public static void bindComplexTable(ComplexTable complexTable, TableView tableView) {
+    public static void bindComplexTable(ComplexTable complexTable, Replicate replicate, TableView tableView) {
+        ChangeListener changeListener = (observable, oldValue, newValue) -> {
+            complexTable.getData().setModified(true);
+        };
         tableView.getColumns().clear();
         tableView.setTableMenuButtonVisible(true);
+        int replicateID = replicate != null ? replicate.getId() : 0;
 
         Button addLine = new Button("New line ");
         addLine.disableProperty().bind(tableView.editableProperty().not());
@@ -688,7 +767,7 @@ public class UITools {
         colAdd.setGraphic(new ImageView(UITools.getImage("resources/images/add_col-16.png")));
         colAdd.setOnAction(actionEvent -> {
             complexTable.addColumn(-1);
-            UITools.bindComplexTable(complexTable, tableView);
+            UITools.bindComplexTable(complexTable, replicate, tableView);
         });
         colAdd.disableProperty().bind(tableView.editableProperty().not());
         colAction.setGraphic(colAdd);
@@ -738,7 +817,7 @@ public class UITools {
             };
         });
 
-            for(ComplexField c : complexTable.getTableHeader()) {
+        for(ComplexField c : complexTable.getTableHeader()) {
                 if(!c.equals(ComplexTable.numC) && !c.equals(ComplexTable.actionC)) {
                     TableColumn<Map<ComplexField, ComplexField>, ComplexField> colType = new TableColumn();
                     tableView.getColumns().add(colType);
@@ -748,7 +827,7 @@ public class UITools {
                     delete.setOnAction(event -> {
                         complexTable.deleteColumn(c);
                         complexTable.getData().setModified(true);
-                        UITools.bindComplexTable(complexTable, tableView);
+                        UITools.bindComplexTable(complexTable, replicate, tableView);
                     });
                     Button edit = new Button("");
                     edit.disableProperty().bind(tableView.editableProperty().not());
@@ -938,10 +1017,10 @@ public class UITools {
                                     TextField text = new TextField();
                                     text.editableProperty().bind(tableView.editableProperty());
                                     text.styleProperty().bind(item.styleProperty());
-                                    item.getValue().unbind();
-                                    text.setText(item.getValue().get());
-                                    item.getValue().bind(text.textProperty());
-
+                                    item.unbindReplicatesValues();
+                                    text.setText(item.getValueWithReplicate(replicateID).get());
+                                    item.getValueWithReplicate(replicateID).bind(text.textProperty());
+                                    item.setValuesListener(changeListener);
 
                                     text.setOnMouseClicked(event -> {
                                         if(text.isEditable() && event.getClickCount() == 2) {
@@ -1002,9 +1081,6 @@ public class UITools {
                                         }
                                     });
                                     setGraphic(text);
-                                    item.getValue().addListener((observable, oldValue, newValue) -> {
-                                        complexTable.getData().setModified(true);
-                                    });
                                 }
                             }
                         };
@@ -1020,7 +1096,11 @@ public class UITools {
         tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
     }
 
-    public static void bindSimpleTable(SimpleTable simpleTable, TableView tableView) {
+    public static void bindSimpleTable(SimpleTable simpleTable, Replicate replicate, TableView tableView) {
+        ChangeListener changeListener = (observable, oldValue, newValue) -> {
+            simpleTable.getData().setModified(true);
+        };
+
         tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
         tableView.setTableMenuButtonVisible(true);
         Button addLine = new Button("New line ");
@@ -1150,10 +1230,7 @@ public class UITools {
                                 UITools.addAutoComplete(combo, item.getListConstraint());
 //                                UITools.addPopOver(combo, Ontology.Attribut);
                                 item.getValue().bind(combo.textProperty());
-
-                                item.getValue().addListener((observable, oldValue, newValue) -> {
-                                    simpleTable.getData().setModified(true);
-                                });
+                                item.setValuesListener(changeListener);
                                 combo.styleProperty().bind(item.styleProperty());
                                 setGraphic(combo);
                             } else {
@@ -1319,10 +1396,7 @@ public class UITools {
                                                 UITools.addAutoComplete(combo, item.getListConstraint());
 //                                                UITools.addPopOver(combo, Ontology.Component);
                                                 item.getValue().bind(combo.textProperty());
-
-                                                item.getValue().addListener((observable, oldValue, newValue) -> {
-                                                    simpleTable.getData().setModified(true);
-                                                });
+                                                item.setValuesListener(changeListener);
                                                 combo.styleProperty().bind(item.styleProperty());
                                                 setGraphic(combo);
                                             } else {
@@ -1356,10 +1430,11 @@ public class UITools {
                                                 TextField text = new TextField();
                                                 text.editableProperty().bind(tableView.editableProperty());
                                                 text.styleProperty().bind(item.styleProperty());
-                                                item.getValue().unbind();
-                                                text.setText(item.getValue().get());
-                                                item.getValue().bind(text.textProperty());
-
+                                                item.unbindReplicatesValues();
+                                                int replicateID = replicate != null ? replicate.getId() : 0;
+                                                text.setText(item.getValueWithReplicate(replicateID).getValue());
+                                                item.getValueWithReplicate(replicateID).bind(text.textProperty());
+                                                item.setValuesListener(changeListener);
 
                                                 text.setOnMouseClicked(event -> {
                                                     if (text.isEditable() && event.getClickCount() == 2) {
@@ -1421,13 +1496,10 @@ public class UITools {
                                                 });
 
                                                 setGraphic(text);
-                                                item.getValue().addListener((observable, oldValue, newValue) -> {
-                                                    simpleTable.getData().setModified(true);
-                                                });
                                             } else {
                                                 TextField combo = new TextField();
                                                 combo.maxWidthProperty().bind(widthProperty());
-                                                item.getValue().unbind();
+                                                item.unbindReplicatesValues();
                                                 if (item.isEditable()) {
                                                     combo.editableProperty().bind(tableView.editableProperty());
                                                 } else {
@@ -1436,17 +1508,12 @@ public class UITools {
                                                 combo.disableProperty().bind(combo.editableProperty().not());
                                                 combo.setText(item.getValue().get());
                                                 UITools.addAutoComplete(combo, item.getListConstraint());
-//                                                if(item.getConceptConstraint() != null && item.getConceptConstraint().size() > 0) {
-//                                                    UITools.addPopOver(combo, item.getConceptConstraint().toArray(new String[0]));
-//                                                }
-                                                item.getValue().bind(combo.textProperty());
+                                                int replicateID = replicate != null ? replicate.getId() : 0;
+                                                item.getValueWithReplicate(replicateID).bind(combo.textProperty());
 
                                                 combo.styleProperty().bind(item.styleProperty());
                                                 setGraphic(combo);
-                                                item.getValue().addListener((observable, oldValue, newValue) -> {
-                                                    simpleTable.getData().setModified(true);
-                                                });
-
+                                                item.setValuesListener(changeListener);
                                             }
                                         }
                                     }
@@ -1470,11 +1537,8 @@ public class UITools {
                                             item.getValue().unbind();
                                             text.setText(item.getValue().get());
                                             item.getValue().bind(text.textProperty());
-
+                                            item.setValuesListener(changeListener);
                                             setGraphic(text);
-                                            item.getValue().addListener((observable, oldValue, newValue) -> {
-                                                simpleTable.getData().setModified(true);
-                                            });
                                         }
                                     }
                                 };
diff --git a/src/main/java/fr/inra/po2vocabmanager/view/dataView/DataOverviewController.java b/src/main/java/fr/inra/po2vocabmanager/view/dataView/DataOverviewController.java
index 8f86f5dc0f1653beb59c14816715c02f9dc35ad1..66b40f84f1f72d09a2767911d4969da03350160a 100644
--- a/src/main/java/fr/inra/po2vocabmanager/view/dataView/DataOverviewController.java
+++ b/src/main/java/fr/inra/po2vocabmanager/view/dataView/DataOverviewController.java
@@ -287,13 +287,13 @@ public class DataOverviewController {
             case STEP:
                 newNode.getFile().setSelectedInTree(true);
                 stepControler.setMainApp(this.mainApp);
-                stepControler.showNodeDetails(newNode);
+                stepControler.showNodeDetails(newNode, newNode.getItineraryFile().getProcessFile().getCurrentReplicate());
                 infoPane.getChildren().add(stepOverview);
                 break;
             case OBSERVATION:
                 newNode.getFile().setSelectedInTree(true);
                 observationControler.setMainApp(this.mainApp);
-                observationControler.showNodeDetails(newNode);
+                observationControler.showNodeDetails(newNode, newNode.getItineraryFile().getProcessFile().getCurrentReplicate());
                 infoPane.getChildren().add(observationOverview);
                 break;
             case ITINERARY:
@@ -521,6 +521,12 @@ public class DataOverviewController {
         }
         listDataNode.get(file).add(node);
         node.setFile(file);
+        if(node.getType().equals(DataNodeType.ITINERARY)) {
+            node.setItineraryFile((ItineraryFile) file);
+        }
+        if(father != null && father.getItineraryFile() != null) {
+            node.setItineraryFile(father.getItineraryFile());
+        }
         node.nameProperty().bindBidirectional(file.getNameProperty());
         if(father != null) {
             father.addSubNode(node);
diff --git a/src/main/java/fr/inra/po2vocabmanager/view/dataView/MaterialMethodLinkOverviewController.java b/src/main/java/fr/inra/po2vocabmanager/view/dataView/MaterialMethodLinkOverviewController.java
index 09517f7781db13f307ee939a620271d5aa977b89..ba2fecc1f2d813f382be353ab4a5538fbdeae449 100644
--- a/src/main/java/fr/inra/po2vocabmanager/view/dataView/MaterialMethodLinkOverviewController.java
+++ b/src/main/java/fr/inra/po2vocabmanager/view/dataView/MaterialMethodLinkOverviewController.java
@@ -325,7 +325,7 @@ public class MaterialMethodLinkOverviewController {
                                 TableView tableConsign = new TableView();
                                 tableConsign.editableProperty().bind(mainApp.getEditProperty());
 
-                                UITools.bindSimpleTable(newValue.getConsignPart().getDataTable(), tableConsign);
+                                UITools.bindSimpleTable(newValue.getConsignPart().getDataTable(), null, tableConsign);
                                 grid.add(tableConsign, 0, 1);
                                 GridPane.setFillWidth(tableConsign, true);
                                 grid.getColumnConstraints().addAll(c);
diff --git a/src/main/java/fr/inra/po2vocabmanager/view/dataView/MaterialMethodOverviewController.java b/src/main/java/fr/inra/po2vocabmanager/view/dataView/MaterialMethodOverviewController.java
index ba314ab12135f6c033554e48c103b4cec12e9bbe..7d53888f193f3838b8cce75bfe151071feb5a1e1 100644
--- a/src/main/java/fr/inra/po2vocabmanager/view/dataView/MaterialMethodOverviewController.java
+++ b/src/main/java/fr/inra/po2vocabmanager/view/dataView/MaterialMethodOverviewController.java
@@ -318,7 +318,7 @@ public class MaterialMethodOverviewController {
 //                                addLine.setOnMouseClicked(event -> newValue.addLine());
                                 TableView tableView = new TableView();
                                 tableView.editableProperty().bind(mainApp.getEditProperty());
-                                UITools.bindSimpleTable(newValue.getDataTable(), tableView);
+                                UITools.bindSimpleTable(newValue.getDataTable(), null,  tableView);
 //                                newValue.bindData(tableView);
 //                                grid.add(tableView, 0, 0);
 //                                grid.add(addLine, 0, 1);
diff --git a/src/main/java/fr/inra/po2vocabmanager/view/dataView/ObservationOverviewController.java b/src/main/java/fr/inra/po2vocabmanager/view/dataView/ObservationOverviewController.java
index 4f593653190f24cbadea601896093ae2d51ac42f..2409e55faf685b7e6f5bad4644a268d39d18ecb1 100644
--- a/src/main/java/fr/inra/po2vocabmanager/view/dataView/ObservationOverviewController.java
+++ b/src/main/java/fr/inra/po2vocabmanager/view/dataView/ObservationOverviewController.java
@@ -22,6 +22,7 @@ import fr.inra.po2vocabmanager.MainApp;
 import fr.inra.po2vocabmanager.model.DataNode;
 import fr.inra.po2vocabmanager.utils.UITools;
 import fr.inrae.po2engine.model.ComplexField;
+import fr.inrae.po2engine.model.Replicate;
 import fr.inrae.po2engine.model.dataModel.CompositionFile;
 import fr.inrae.po2engine.model.dataModel.KeyWords;
 import fr.inrae.po2engine.model.dataModel.ObservationFile;
@@ -135,22 +136,26 @@ public class ObservationOverviewController {
     }
 
 
-    public void showNodeDetails(DataNode node) {
+    public void showNodeDetails(DataNode node, Replicate replicate) {
 
         ToggleGroup groupFOI = new ToggleGroup();
 
-
         file = (ObservationFile) node.getFile();
         file.checkValue();
+        if(replicate != null) {
+            observationPanel.setText("Observation (replicate : " + replicate.getName() + ")");
+        } else {
+            observationPanel.setText("Observation");
+        }
         UITools.simpleBindValue(file.getCName(), observationType);
 
         UITools.simpleBindValue(file.getCID(), observationName);
-        UITools.simpleBindValue(file.getCDate(), observationDate);
-        UITools.simpleBindValue(file.getCDuree(), observationTimeD);
-        UITools.simpleBindValue(file.getCHeure(), observationTime);
+        UITools.simpleBindValue(file.getCDate(),replicate, observationDate);
+        UITools.simpleBindValue(file.getCDuree(),replicate, observationTimeD);
+        UITools.simpleBindValue(file.getCHeure(),replicate,observationTime);
         UITools.simpleBindValue(file.getCDescrition(), observationDesc);
         UITools.simpleBindValue(file.getCScale(), observationScale);
-        UITools.bindComboBoxAgent(file.getAgentProperty(),file.getData().getProjectFile().getListAgent(),  orgAgent);
+        UITools.bindComboBoxAgent(file.getAgentsMap(),file.getData().getProjectFile().getListAgent(), replicate, orgAgent);
         UITools.addAutoComplete(observationScale, file.getCScale().getListConstraint());
 
 
@@ -165,7 +170,7 @@ public class ObservationOverviewController {
             listItem.add(new MutablePair<>("Step - " + file.getStepFile().getId(), new MutablePair<>("step", new SimpleBooleanProperty(false))));
 
             for (CompositionFile comp : file.getStepFile().getCompositionFile().keySet()) {
-                String inout = file.getStepFile().getCompositionFile().get(comp) ? "Input" : "Output";
+                String inout = Boolean.TRUE.equals(file.getStepFile().getCompositionFile().get(comp)) ? "Input" : "Output";
                 listItem.add(new MutablePair<>(inout+" - " + comp.getHeaderPart().getCompositionID() , new MutablePair<>(comp.getFileName(), new SimpleBooleanProperty(false))));
             }
 
@@ -208,36 +213,6 @@ public class ObservationOverviewController {
             return cell;
         });
 
-        Label titlePane = new Label("Observation");
-        titlePane.setAlignment(Pos.CENTER_LEFT);
-//        Button exportExcel = new Button(null, new ImageView(UITools.getImage("resources/images/file-export-16.png")));
-//        exportExcel.setTooltip(new Tooltip("Export Observation"));
-//        exportExcel.setOnMouseClicked(event -> {
-//            // Export des données.
-//
-//        });
-        Button importExcel = new Button(null, new ImageView(UITools.getImage("resources/images/file-import-16.png")));
-        importExcel.setTooltip(new Tooltip("Export Observation"));
-        importExcel.setOnMouseClicked(event -> {
-
-        });
-
-
-
-
-        importExcel.disableProperty().bind(this.mainApp.getEditProperty().not());
-
-        Label emptyLabelTitle = new Label(" ");
-        emptyLabelTitle.setMaxWidth(Double.MAX_VALUE);
-        HBox bbT = new HBox();
-        bbT.setAlignment(Pos.CENTER_RIGHT);
-        bbT.getChildren().addAll(titlePane,emptyLabelTitle/*, exportExcel, importExcel*/);
-        HBox.setHgrow(emptyLabelTitle, Priority.ALWAYS);
-        bbT.setPadding(new Insets(0,3,0,0));
-        bbT.minWidthProperty().bind(observationPanel.widthProperty().subtract(25));
-
-        observationPanel.setGraphic(bbT);
-
         boxContent.getChildren().retainAll(observationPanel);
 
         TitledPane matMetPane = new TitledPane();
@@ -268,7 +243,7 @@ public class ObservationOverviewController {
             TableView table = new TableView();
             table.setMinHeight(200);
             table.editableProperty().bind(this.mainApp.getEditProperty());
-            UITools.bindTable(tablePart.getTable(), table);
+            UITools.bindTable(tablePart.getTable(), replicate, table);
             tablePane.setContent(table);
             boxContent.getChildren().add(tablePane);
 
@@ -304,7 +279,7 @@ public class ObservationOverviewController {
                 Optional<ButtonType> res = a.showAndWait();
                 if(res.get() == ButtonType.OK) {
                     file.removeTablePart(tablePart);
-                    showNodeDetails(node);
+                    showNodeDetails(node, replicate);
                 }
 
             });
diff --git a/src/main/java/fr/inra/po2vocabmanager/view/dataView/ProcessOverviewController.java b/src/main/java/fr/inra/po2vocabmanager/view/dataView/ProcessOverviewController.java
index fb9108daa337a9e7ef519bb4d648a76adb3a096c..530d629bfb99c63993fdaffcfc60326bd4dbd391 100644
--- a/src/main/java/fr/inra/po2vocabmanager/view/dataView/ProcessOverviewController.java
+++ b/src/main/java/fr/inra/po2vocabmanager/view/dataView/ProcessOverviewController.java
@@ -22,12 +22,15 @@ import fr.inra.po2vocabmanager.MainApp;
 import fr.inra.po2vocabmanager.model.DataNode;
 import fr.inra.po2vocabmanager.utils.UITools;
 import fr.inra.po2vocabmanager.utils.XCell;
+import fr.inrae.po2engine.model.Replicate;
 import fr.inrae.po2engine.model.dataModel.GeneralFile;
 import fr.inrae.po2engine.model.dataModel.StepFile;
 import javafx.animation.TranslateTransition;
 import javafx.beans.binding.Bindings;
+import javafx.beans.property.SimpleIntegerProperty;
 import javafx.beans.property.SimpleObjectProperty;
 import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.value.ChangeListener;
 import javafx.collections.FXCollections;
 import javafx.collections.ListChangeListener;
 import javafx.collections.ObservableList;
@@ -44,6 +47,7 @@ import org.controlsfx.control.textfield.AutoCompletionBinding;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Optional;
+import java.util.concurrent.atomic.AtomicReference;
 import java.util.stream.Collectors;
 
 public class ProcessOverviewController {
@@ -59,6 +63,8 @@ public class ProcessOverviewController {
     @FXML
     TitledPane stepAvailable;
     @FXML
+    TitledPane replicatesPane;
+    @FXML
     TextArea description;
     @FXML
     Label linksLabel;
@@ -70,6 +76,12 @@ public class ProcessOverviewController {
     TreeTableColumn<StepFile, String> colIti;
     TreeTableColumn<StepFile, StepFile> colDel;
 
+    TableView<Replicate> replicateTable;
+    TableColumn<Replicate, Replicate> colRepName;
+    TableColumn<Replicate, Integer> colRepId;
+    TableColumn<Replicate, Replicate> colRepDesc;
+    TableColumn<Replicate, Replicate> colRepDel;
+
     TreeItem<StepFile> rootTree;
 
 
@@ -89,7 +101,6 @@ public class ProcessOverviewController {
         endDate.editableProperty().bind(mainApp.getEditProperty());
         processType.editableProperty().bind(mainApp.getEditProperty());
         description.editableProperty().bind(mainApp.getEditProperty());
-
     }
 
     private TranslateTransition createTranslateTransition(final Shape group) {
@@ -135,6 +146,9 @@ public class ProcessOverviewController {
         generalFile.unbind();
         generalFile.checkValue();
 
+        ChangeListener changeListener = (observable, oldValue, newValue) -> {
+            generalFile.getData().setModified(true);
+        };
 
         UITools.simpleBindValue(generalFile.getCTitle(), processTitle);
         UITools.simpleBindValue(generalFile.getCStartDate(), startDate);
@@ -145,7 +159,7 @@ public class ProcessOverviewController {
         UITools.simpleBindValue(generalFile.getCDescription(), description);
 
         listAutoCompletion.add(UITools.addAutoComplete(processType, generalFile.getCType().getListConstraint()));
-
+        generalFile.getListReplicate().forEach(r -> r.setValuesListener(changeListener));
 
         ArrayList<String> ls = generalFile.getExternalLinks();
         String[] arrayLink = new String [ls.size()];
@@ -248,6 +262,109 @@ public class ProcessOverviewController {
 
         stepAvailable.setContent(treeTableView);
 
+        replicateTable = new TableView<>();
+        replicateTable.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
+        replicateTable.editableProperty().bind(mainApp.getEditProperty());
+        colRepId = new TableColumn<>("id");
+        colRepId.setCellValueFactory(cellData -> new SimpleIntegerProperty(cellData.getValue().getId()).asObject());
+        colRepId.setMaxWidth(60);
+        colRepId.setMinWidth(60);
+        colRepId.setPrefWidth(60);
+
+        colRepName = new TableColumn<>("Name");
+        colRepName.setCellValueFactory(cellData -> new SimpleObjectProperty<>(cellData.getValue()));
+        colRepName.setCellFactory(param -> {
+                return new TableCell<Replicate, Replicate>() {
+                    @Override
+                    public void updateItem(Replicate item, boolean empty) {
+                        super.updateItem(item, empty);
+                        TextField text = new TextField();
+                        if (item != null && !empty) {
+                            text.editableProperty().bind(replicateTable.editableProperty());
+                            item.nameProperty().unbind();
+                            text.setText(item.getName());
+                            item.nameProperty().bind(text.textProperty());
+                            setGraphic(text);
+                        } else {
+                            setText(null);
+                            setStyle(null);
+                            setGraphic(null);
+                        }
+                    }
+                };
+        });
+
+        colRepDesc = new TableColumn<>("Description");
+        colRepDesc.setCellValueFactory(cellData -> new SimpleObjectProperty<>(cellData.getValue()));
+        colRepDesc.setCellFactory(param -> {
+            return new TableCell<Replicate, Replicate>() {
+                @Override
+                public void updateItem(Replicate item, boolean empty) {
+                    super.updateItem(item, empty);
+                    TextField text = new TextField();
+                    if (item != null && !empty) {
+                        text.editableProperty().bind(replicateTable.editableProperty());
+                        item.descriptionProperty().unbind();
+                        text.setText(item.getDescription());
+                        item.descriptionProperty().bind(text.textProperty());
+                        setGraphic(text);
+                    } else {
+                        setText(null);
+                        setStyle(null);
+                        setGraphic(null);
+                    }
+                }
+            };
+        });
+
+        colRepDel = new TableColumn<>();
+        colRepDel.setCellValueFactory(cellData -> new SimpleObjectProperty<>(cellData.getValue()));
+        colRepDel.setMaxWidth(60);
+        colRepDel.setMinWidth(60);
+        colRepDel.setPrefWidth(60);
+        AtomicReference<GeneralFile> currentGF = new AtomicReference<>(generalFile);
+
+        colRepDel.setCellFactory(cell -> {
+
+            return new TableCell<>(){
+                @Override
+                protected void updateItem(Replicate replicate, boolean b) {
+                    super.updateItem(replicate, b);
+
+                    if(replicate == null || b) {
+                        setGraphic(null);
+                    } else {
+                        Button buttonDel = new Button();
+                        buttonDel.setGraphic(new ImageView(UITools.getImage("resources/images/del_16.png")));
+                        if(replicate.getId() == 0) {
+                            buttonDel.setDisable(true);
+                        } else {
+                            buttonDel.disableProperty().bind(Bindings.not(mainApp.getEditProperty()));
+                        }
+                        buttonDel.setOnAction(event -> {
+                            Alert a = new Alert(Alert.AlertType.CONFIRMATION);
+                            a.setTitle("Delete Replicate");
+                            a.setHeaderText("Delete Replicate " + replicate.getName());
+                            a.initModality(Modality.WINDOW_MODAL);
+                            a.initOwner(MainApp.primaryStage);
+                            Optional<ButtonType> res = a.showAndWait();
+                            if (res.get() == ButtonType.OK) {
+                                GeneralFile gf = currentGF.get();
+                                gf.removeReplicate(replicate);
+                                gf.getData().setModified(true);
+                            }
+                        });
+                        setGraphic(buttonDel);
+                    }
+                }
+            };
+        });
+
+        replicateTable.getColumns().addAll(colRepId, colRepName, colRepDesc, colRepDel);
+
+        replicatesPane.setContent(replicateTable);
+        replicateTable.setItems(generalFile.getListReplicate());
+
     }
 
     private void updateListLink() {
diff --git a/src/main/java/fr/inra/po2vocabmanager/view/dataView/StepOverviewController.java b/src/main/java/fr/inra/po2vocabmanager/view/dataView/StepOverviewController.java
index b8b498c4f07b276e858a0db60d23169c833a944e..208ca9da8add26d8c107531d7146135c5f6de548 100644
--- a/src/main/java/fr/inra/po2vocabmanager/view/dataView/StepOverviewController.java
+++ b/src/main/java/fr/inra/po2vocabmanager/view/dataView/StepOverviewController.java
@@ -22,6 +22,7 @@ import fr.inra.po2vocabmanager.MainApp;
 import fr.inra.po2vocabmanager.model.DataNode;
 import fr.inra.po2vocabmanager.utils.UITools;
 import fr.inrae.po2engine.model.ComplexField;
+import fr.inrae.po2engine.model.Replicate;
 import fr.inrae.po2engine.model.dataModel.CompositionFile;
 import fr.inrae.po2engine.model.dataModel.KeyWords;
 import fr.inrae.po2engine.model.dataModel.StepFile;
@@ -108,19 +109,26 @@ public class StepOverviewController {
         scale.disableProperty().bind(this.mainApp.getEditProperty().not());
     }
 
-    public void showNodeDetails(DataNode node) {
+    public void showNodeDetails(DataNode node, Replicate replicate) {
         for(AutoCompletionBinding auto : listAutoCompletion) {
             auto.dispose();
         }
         f = (StepFile) node.getFile();
         f.checkValue();
+
+        if(replicate != null) {
+            stepPanel.setText("Step (replicate : " + replicate.getName() + ")");
+        } else {
+            stepPanel.setText("Step");
+        }
+
         UITools.simpleBindValue(f.getCType(), stepTitle);
         UITools.simpleBindValue(f.getCId(), stepID);
         UITools.simpleBindValue(f.getCDescrition(), description);
-        UITools.simpleBindValue(f.getCDate(), date);
-        UITools.simpleBindValue(f.getCTime(), time);
-        UITools.simpleBindValue(f.getCDuration(), duree);
-        UITools.bindComboBoxAgent(f.getAgentProperty(),f.getData().getProjectFile().getListAgent(),  orgAgent);
+        UITools.simpleBindValue(f.getCDate(), replicate, date);
+        UITools.simpleBindValue(f.getCTime(), replicate, time);
+        UITools.simpleBindValue(f.getCDuration(), replicate, duree);
+        UITools.bindComboBoxAgent(f.getAgentsMap(),f.getData().getProjectFile().getListAgent(), replicate, orgAgent);
         UITools.simpleBindValue(f.getCScale(), scale);
         listAutoCompletion.add(UITools.addAutoComplete(scale, f.getCScale().getListConstraint()));
 
@@ -216,7 +224,7 @@ public class StepOverviewController {
                 Optional<ButtonType> res = a.showAndWait();
                 if(res.get() == ButtonType.OK) {
                     f.removeCompositionFile(compoFile);
-                    showNodeDetails(node);
+                    showNodeDetails(node, replicate);
                 }
 
             });
diff --git a/src/main/resources/fr/inra/po2vocabmanager/view/dataView/ProcessOverview.fxml b/src/main/resources/fr/inra/po2vocabmanager/view/dataView/ProcessOverview.fxml
index ef01250e85cc3bff006a9a3a4a44cc524a8bc05c..43ecc3bcb3b6b452edbb8ee8487e180ae2fe786e 100644
--- a/src/main/resources/fr/inra/po2vocabmanager/view/dataView/ProcessOverview.fxml
+++ b/src/main/resources/fr/inra/po2vocabmanager/view/dataView/ProcessOverview.fxml
@@ -91,6 +91,7 @@
 
             </TitledPane>
             <TitledPane fx:id="stepAvailable" maxHeight="Infinity" prefHeight="428.0" prefWidth="718.0" text="Steps available" VBox.vgrow="ALWAYS" />
+            <TitledPane fx:id="replicatesPane" animated="false" text="Replicates" />
          </children>
       </VBox>
    </children>