 the same way as any Vaadin component : so, we can use it anywhere. 
        We configure the component by setting properties, and the component notifies us of events through listeners.
        Creating a reusable component is as simple as making sure it can be configured through : 
        setters, and that it fires events whenever something happens. 
        Using the component should not have side effects, for instance it shouldn’t change anything in the database by itself.
    */

    //CIF
    private TypePartenaireBusiness typePartenaireBusiness;
    private ArrayList<TypePartenaire> typePartenaireList = new ArrayList<TypePartenaire>();
    private ListDataProvider<TypePartenaire> typePartenaireDataProvider; 
    
    /* Fields to edit properties in Creancier entity */
    private SuperTextField txtCodePartenaire = new SuperTextField();
    private SuperTextField txtLibellePartenaire = new SuperTextField();
    private SuperTextField txtLibelleCourtPartenaire = new SuperTextField();
    private ComboBox<TypePartenaire> cboCodeTypePartenaire = new ComboBox<>();
    //private ComboBox<TypePartenaire> cboCodeTypePartenaire = new ComboBox<>("Type Creancier");
    private SuperTextField txtAdresse = new SuperTextField();
    private SuperTextField txtVille = new SuperTextField();
    private SuperTextField txtNoTelephone = new SuperTextField();
    private SuperTextField txtNoMobile = new SuperTextField();
    private SuperTextField txtEmail = new SuperTextField();
    private Checkbox chkInactif = new Checkbox();
    
    public EditerPartenaireDialog() {
        //Cette méthode contient les instructions pour créer les composants
        super();
        this.binder = new BeanValidationBinder<>(Creancier.class);
        this.configureComponents(); 
    }

    public static EditerPartenaireDialog getInstance() {
        try 
        {
            if (VaadinSession.getCurrent().getAttribute(EditerPartenaireDialog.class) ==  null) {
                //Register an instance - We use this registre as a CACHE, i.e we store it only once
                VaadinSession.getCurrent().setAttribute(EditerPartenaireDialog.class, new EditerPartenaireDialog());
            }
            return (EditerPartenaireDialog)(VaadinSession.getCurrent().getAttribute(EditerPartenaireDialog.class));
        } 
        catch (Exception e) 
        {
            MessageDialogHelper.showAlertDialog("EditerPartenaireDialog.getInstance", e.toString());
            e.printStackTrace();
            return null;
        }
    } //public static EditerPartenaireDialog getInstance() {
    

    // Show Dialog
    public void showDialog(String dialogTitle, ModeFormulaireEditerEnum modeFormulaireEditerEnum, ArrayList<Creancier> targetBeanList, ArrayList<Creancier> referenceBeanList, String newComboValue, EventBus.UIEventBus uiEventBus, TypePartenaireBusiness typePartenaireBusiness) {
        //Cette méthode contient les instructions ad hoc
        try 
        {
            //1- Initialisation des paramètres passés
            this.customSetDialogTitle(dialogTitle);
            this.customSetModeFormulaireEditer(modeFormulaireEditerEnum);
            this.customSetReferenceBeanList(referenceBeanList);

            if (this.modeFormulaireEditer == ModeFormulaireEditerEnum.AJOUTERCIF) {
                this.customSetNewComboValue(newComboValue);
            }
            
            this.uiEventBus = uiEventBus;
            this.typePartenaireBusiness = typePartenaireBusiness;
            
            this.uiEventBus.subscribe(this, false);//Use false as the second constructor parameter to indicate that the event does not come from the client

            //2- CIF
            this.typePartenaireList = (ArrayList)this.typePartenaireBusiness.findAll();
            this.typePartenaireDataProvider = DataProvider.ofCollection(this.typePartenaireList);
            // Make the dataProvider sorted by LibelleTypePartenaire in ascending order
            this.typePartenaireDataProvider.setSortOrder(TypePartenaire::getLibelleTypePartenaire, SortDirection.ASCENDING);

            //3- Setup ReadOnly Field Mode - Configure ReadOnly Field Set ComboBox DataProvider - Manage ToolBars
            this.customManageReadOnlyFieldMode();
            this.configureReadOnlyField();
            this.setComboBoxDataProvider();
            this.customManageToolBars();
        
            //4- Set up Target Bean - TargetBeanSet : cette instruction doit être exécutée avant l'exécution de Collections.sort(this.targetBeanList.....
            this.targetBeanList = targetBeanList;

            //5 - Make the this.targetBeanList sorted by LibellePartenaire in ascending order
            Collections.sort(this.targetBeanList, Comparator.comparing(Creancier::getCodePartenaire));

            //6- LoadFirstBean : cette instruction doit être exécutée après l'exécution de this.configureComponents() de façon à s'assurer de traiter les données une fois que les champs sont injectés
            this.customLoadFirstBean();

            //7 - Open the dialog
            this.dialog.open();
        } 
        catch (Exception e) 
        {
            MessageDialogHelper.showAlertDialog("EditerPartenaireDialog.showDialog", e.toString());
            e.printStackTrace();
        }
    }

    private void configureComponents() {
        //Associate the data with the formLayout columns and load the data. 
        
        try 
        {
            //1 - Set properties of the form
            this.formLayout.addClassName("fichier-form");
            this.formLayout.setSizeFull(); //sets the form size to fill the screen.
            
            //2 - Define the Fields instances to use - We don't use.setLabel since we will use addFormItem instead of add to add items to the form - addFormItem allows us to set SuperTextField with on a FormaLayout when add doesn't
            this.txtCodePartenaire.setWidth(100, Unit.PIXELS);
            this.txtCodePartenaire.setRequired(true);
            this.txtCodePartenaire.setRequiredIndicatorVisible(true);
            this.txtCodePartenaire.addClassName(TEXTFIELD_LEFT_LABEL);
            
            this.txtLibellePartenaire.setWidth(400, Unit.PIXELS);
            this.txtLibellePartenaire.addClassName(TEXTFIELD_LEFT_LABEL);
            
            this.txtLibelleCourtPartenaire.setWidth(150, Unit.PIXELS);
            this.txtLibelleCourtPartenaire.addClassName(TEXTFIELD_LEFT_LABEL);
            
            this.cboCodeTypePartenaire.setWidth(150, Unit.PIXELS);
            this.cboCodeTypePartenaire.addClassName(COMBOBOX_LEFT_LABEL);
            
            // Choose which property from TypePartenaire is the presentation value
            this.cboCodeTypePartenaire.setItemLabelGenerator(TypePartenaire::getLibelleTypePartenaire);
            this.cboCodeTypePartenaire.setRequired(true);
            this.cboCodeTypePartenaire.setRequiredIndicatorVisible(true);
            //???this.cboCodeTypePartenaire.setLabel("TypePartenaire");
            //???this.cboCodeTypePartenaire.setId("person");
            
            this.cboCodeTypePartenaire.setClearButtonVisible(true);
            //Add Filtering
            this.cboCodeTypePartenaire.setAllowCustomValue(true);
            this.cboCodeTypePartenaire.setPreventInvalidInput(true);
            
            this.cboCodeTypePartenaire.addValueChangeListener(event -> {
                if (event.getValue()!= null) {
                    //BeforeUpdate CodeTypePartenaire (CIF): Contrôle de Inactif
                    if (event.getValue().isInactif() == true) {
                        MessageDialogHelper.showWarningDialog("Erreur de Saisie", "Le Type Creancier choisi est actuellement désactivé. Veuillez en saisir un autre.");
                        //Cancel
                        this.cboCodeTypePartenaire.setValue(event.getOldValue());
                    } //if (event.getValue()!= null) {
                }
            });
            
            /**
            * Allow users to enter a value which doesn't exist in the data set, and
            * set it as