diff --git a/src/include/66/parser.h b/src/include/66/parser.h
index 4e75163da2d5ca14c51cd0aea5b6ec45171641f5..602d993fae3dc49187f6cc3df9585b594a319873 100644
--- a/src/include/66/parser.h
+++ b/src/include/66/parser.h
@@ -104,6 +104,7 @@ struct sv_name_s
     int name ; //pos in keep
     int description ; //pos in keep
     int version ; // pos in keep
+    int intree ; // pos in keep
     int idga ; //pos in stralloc deps -> @depends
     unsigned int nga ; //number of deps in stralloc deps -> @depends
     int idopts ; // pos in stralloc deps -> @optsdepends
@@ -223,6 +224,7 @@ struct sv_alltype_s
     -1 , \
     -1 , \
     -1 , \
+    -1 , \
     0 , \
     -1 , \
     0 , \
@@ -295,33 +297,36 @@ extern void keynocheck_free(keynocheck *nocheck) ;
 extern void section_free(section_t *sec) ;
 extern void freed_parser(void) ;
 extern void ssexec_enable_cleanup(void) ;
+
 /** enable phase */
-extern void start_parser(stralloc *list,ssexec_t *info, unsigned int *nbsv,uint8_t FORCE) ;
+extern void start_parser(char const *sv, ssexec_t *info, uint8_t disable_module, char const *directory_forced) ;
+extern int parse_service(char const *sv, stralloc *parsed_list, ssexec_t *info, uint8_t force, uint8_t conf) ;
+int parse_service_alldeps(sv_alltype *alltype, ssexec_t *info, stralloc *parsed_list, uint8_t force, char const *directory_forced) ;
+extern int parse_service_deps(sv_alltype *alltype, ssexec_t *info, stralloc *parsed_list, uint8_t force, char const *directory_forced) ;
+extern int parse_service_optsdeps(stralloc *rebuild, sv_alltype *alltype, ssexec_t *info, stralloc *parsed_list, uint8_t force, uint8_t field, char const *directory_forced) ;
 extern int parser(sv_alltype *service,stralloc *src,char const *svname,int svtype) ;
-extern int parse_service_check_enabled(char const *tree_directory, char const *svname,uint8_t force,uint8_t *exist) ;
-extern int parse_service_before(ssexec_t *info, stralloc *parsed_list, stralloc *opts_deps_list, char const *sv,unsigned int *nbsv, stralloc *sasv,uint8_t force,uint8_t conf,uint8_t disable_module,char const *directory_forced) ;
-extern int parse_service_all_deps(ssexec_t *info,stralloc *parsed_list, stralloc *tree_list, sv_alltype *sv_before,char const *sv, unsigned int *nbsv,stralloc *sasv,uint8_t force, uint8_t conf,char const *directory_forced) ;
-extern int parse_service_deps(ssexec_t *info,stralloc *parsed_list, stralloc *opts_deps_list, sv_alltype *sv_before, char const *sv,unsigned int *nbsv,stralloc *sasv,uint8_t force,uint8_t conf,char const *directory_forced) ;
-extern int parse_service_opts_deps(stralloc *rebuild,ssexec_t *info,stralloc *parsed_list,stralloc *opts_deps_list,sv_alltype *sv_before,char const *sv,unsigned int *nbsv,stralloc *sasv,uint8_t force,uint8_t conf,uint8_t mandatory,char const *directory_forced) ;
-extern int parse_add_service(stralloc *parsed_list,sv_alltype *sv_before,char const *service,unsigned int *nbsv,uid_t owner,uint8_t conf) ;
-extern int get_svtype(sv_alltype *sv_before, char const *contents) ;
-extern int get_svtype_from_file(char const *file) ;
 
 /** split */
 extern int section_get_range(section_t *sasection,stralloc *src) ;
 extern int key_get_range(genalloc *ga, section_t *sasection) ;
 extern int check_mandatory(sv_alltype *service, section_t *sasection) ;
-extern int nocheck_toservice(keynocheck *nocheck,int svtype, sv_alltype *service) ;
+extern int nocheck_toservice(keynocheck *nocheck, int svtype, sv_alltype *service) ;
+
 /** store */
 extern int keep_common(sv_alltype *service,keynocheck *nocheck,int svtype) ;
 extern int keep_runfinish(sv_exec *exec,keynocheck *nocheck) ;
 extern int keep_logger(sv_execlog *log,keynocheck *nocheck) ;
 extern int keep_environ(sv_alltype *service,keynocheck *nocheck) ;
 extern int keep_regex(sv_module *module,keynocheck *nocheck) ;
+
 /** helper */
+extern int get_svtype(sv_alltype *sv_before, char const *contents) ;
+extern int get_svtype_from_file(char const *file) ;
+extern int get_svintree(sv_alltype *sv_before, char const *contents) ;
 extern int add_pipe(sv_alltype *sv, stralloc *sa) ;
+
 /** write */
-extern void start_write(stralloc *tostart,unsigned int *nclassic,unsigned int *nlongrun,char const *workdir, genalloc *gasv,ssexec_t *info,uint8_t FORCE,uint8_t CONF) ;
+extern void start_write(stralloc *tostart,unsigned int *nclassic,unsigned int *nlongrun,char const *workdir, genalloc *gasv,ssexec_t *info) ;
 extern int write_services(sv_alltype *sv, char const *workdir, uint8_t force,uint8_t conf) ;
 extern int write_classic(sv_alltype *sv, char const *dst, uint8_t force, uint8_t conf) ;
 extern int write_longrun(sv_alltype *sv,char const *dst, uint8_t force, uint8_t conf) ;
@@ -335,8 +340,9 @@ extern int write_consprod(sv_alltype *sv,char const *prodname,char const *consna
 extern int write_dependencies(unsigned int nga,unsigned int idga,char const *dst,char const *filename) ;
 extern int write_env(char const *name,char const *contents,char const *dst) ;
 extern int write_oneshot_logger(stralloc *destlog, sv_alltype *sv) ;
+
 /** module */
-extern int parse_module(sv_alltype *sv_before,ssexec_t *info,stralloc *parsed_list,stralloc *tree_list, char const *svname,char const *src_frontend,unsigned int *nbsv, stralloc *sasv,uint8_t force,uint8_t conf) ;
+extern int parse_module(sv_alltype *alltype, ssexec_t *info, stralloc *parsed_list, uint8_t force) ;
 extern int regex_get_file_name(char *filename,char const *str) ;
 extern int regex_get_replace(char *replace, char const *str) ;
 extern int regex_get_regex(char *regex, char const *str) ;
diff --git a/src/lib66/parser_module.c b/src/lib66/parse_module.c
similarity index 68%
rename from src/lib66/parser_module.c
rename to src/lib66/parse_module.c
index 3e4516893c602d77f104097a41526ffc367784d4..915eb483ab33d71f889edb6fd46e4326f50870f6 100644
--- a/src/lib66/parser_module.c
+++ b/src/lib66/parse_module.c
@@ -1,5 +1,5 @@
 /*
- * parser.c
+ * parse_module.c
  *
  * Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
  *
@@ -60,11 +60,12 @@ static int check_dir(char const *src,char const *dir)
 
     r = scan_mode(tsrc,S_IFDIR) ;
     if (r < 0) { errno = EEXIST ; log_warnusys_return(LOG_EXIT_ZERO,"conflicting format of: ",tsrc) ; }
-    if (!r)
-    {
+    if (!r) {
+
         if (!dir_create_parent(tsrc,0755))
             log_warnusys_return(LOG_EXIT_ZERO,"create directory: ",tsrc) ;
     }
+
     return 1 ;
 }
 
@@ -75,58 +76,73 @@ static int get_list(stralloc *list, stralloc *sdir,size_t len, char const *svnam
     sdir->len = len ;
     if (!auto_stra(sdir,SS_MODULE_SERVICE)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ;
 
-    if (!sastr_dir_get_recursive(list,sdir->s,"",mode, 0))
+    char const *exclude[1] = { 0 } ;
+    if (!sastr_dir_get_recursive(list,sdir->s,exclude,mode,1))
         log_warnusys_return(LOG_EXIT_ZERO,"get file(s) of module: ",svname) ;
 
     sdir->len = len ;
 
     if (!auto_stra(sdir,SS_MODULE_SERVICE_INSTANCE)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ;
 
-    if (!sastr_dir_get_recursive(list,sdir->s,"",mode, 0))
+    if (!sastr_dir_get_recursive(list,sdir->s,exclude,mode,1))
         log_warnusys_return(LOG_EXIT_ZERO,"get file(s) of module: ",svname) ;
 
     return 1 ;
 }
 
-static int rebuild_list(sv_alltype *sv_before,stralloc *list,stralloc *sv_all_type, stralloc *module_service)
+static int rebuild_list(sv_alltype *alltype,stralloc *list,stralloc *sv_all_type, stralloc *module_service)
 {
     log_flow() ;
 
     size_t pos, id, did, nid, dnid ;
     sv_alltype_ref sv ;
-    id = sv_before->cname.idga, nid = sv_before->cname.nga ;
-    for (;nid; id += strlen(deps.s + id) + 1, nid--)
+    id = alltype->cname.idga, nid = alltype->cname.nga ;
+    for (; nid ; id += strlen(deps.s + id) + 1, nid--)
     {
         char *deps_name = deps.s + id ;
         /** if we check the dependencies of a module which was declared
          * inside the main module, the recursive operation enter on infinite loop.
-         * So, break it by dependencies addition comparison */
+         * So, break it by dependency addition comparison */
         if (sastr_cmp(sv_all_type,deps_name) == -1) {
 
-            for (pos = 0 ; pos < genalloc_len(sv_alltype,&gasv) ; pos++)
-            {
+            for (pos = 0 ; pos < genalloc_len(sv_alltype,&gasv) ; pos++) {
+
                 sv = &genalloc_s(sv_alltype,&gasv)[pos] ;
                 int type = sv->cname.itype == TYPE_MODULE ? 1 : 0 ;
                 char *n = keep.s + sv->cname.name ;
-                if (!strcmp(n,deps_name))
-                {
-                    if (!stralloc_catb(list,keep.s + sv->src,strlen(keep.s + sv->src) + 1)) return 0 ;
-                    if (!sv->cname.nga) continue ;
+
+                if (!strcmp(n,deps_name)) {
+
+                    if (!stralloc_catb(list,keep.s + sv->src,strlen(keep.s + sv->src) + 1))
+                        return 0 ;
+
+                    if (!sv->cname.nga)
+                        continue ;
+
                     did = type ? sv->cname.idcontents : sv->cname.idga, dnid = type ? sv->cname.ncontents : sv->cname.nga ;
-                    for (;dnid; did += strlen(deps.s + did) + 1, dnid--)
-                    {
-                        if (sastr_cmp(list,deps.s + did) >= 0) continue ;
+
+                    for (;dnid; did += strlen(deps.s + did) + 1, dnid--) {
+
+                        if (sastr_cmp(list,deps.s + did) >= 0)
+                            continue ;
+
                         if (!rebuild_list(sv,list,sv_all_type,module_service))
                             log_warnu(LOG_EXIT_ZERO,"rebuild dependencies list of: ",deps.s + did) ;
                     }
                 }
             }
-            if (!stralloc_catb(sv_all_type,deps_name,strlen(deps_name) + 1)) return 0 ;
+
+            if (!stralloc_catb(sv_all_type,deps_name,strlen(deps_name) + 1))
+                return 0 ;
         }
-        if (sastr_cmp(module_service,deps_name) == -1)
-            if (!stralloc_catb(module_service,deps_name,strlen(deps_name) + 1)) return 0 ;
+
+        if (!stralloc_catb(module_service,deps_name,strlen(deps_name) + 1))
+            return 0 ;
     }
 
+    if (!sastr_sortndrop_element(module_service))
+        return 0 ;
+
     return 1 ;
 }
 
@@ -135,195 +151,205 @@ static int rebuild_list(sv_alltype *sv_before,stralloc *list,stralloc *sv_all_ty
  * return 2 on already enabled
  * @svname do not contents the path of the frontend file*/
 
-int parse_module(sv_alltype *sv_before,ssexec_t *info,stralloc *parsed_list,stralloc *tree_list, char const *svname,char const *src_frontend,unsigned int *nbsv, stralloc *sasv,uint8_t force,uint8_t conf)
+int parse_module(sv_alltype *alltype, ssexec_t *info, stralloc *parsed_list, uint8_t force)
 {
     log_flow() ;
 
-    log_trace("start parse process of module: ",svname) ;
-    int r, err = 1, insta = -1, svtype = -1, from_ext_insta = 0, already_parsed = 0 ;
+    int r, err = 1, insta = -1, minsta = -1, svtype = -1, from_ext_insta = 0, already_parsed = 0 ;
     size_t pos = 0, id, nid, newlen ;
     stralloc sdir = STRALLOC_ZERO ; // service dir
     stralloc list = STRALLOC_ZERO ;
     stralloc tmp = STRALLOC_ZERO ;
-    stralloc moduleinsta = STRALLOC_ZERO ;
     stralloc addonsv = STRALLOC_ZERO ;
+    char *sv = keep.s + alltype->cname.name ;
+    char src[strlen(keep.s + alltype->src) + 1] ;
+    uint8_t conf = alltype->overwrite_conf ;
+
+    if (!ob_dirname(src, keep.s + alltype->src))
+        log_dieu(LOG_EXIT_SYS,"get dirname of: ", keep.s + alltype->src) ;
+
+    log_trace("start parse process of module: ",sv) ;
 
     /** should be always right,
      * be paranoid and check it */
-    insta = instance_check(svname) ;
+    insta = instance_check(sv) ;
     if (insta <= 0)
-        log_warn_return(LOG_EXIT_ZERO,"invalid module instance name: ",svname);
+        log_die(LOG_EXIT_SYS, "invalid module instance name: ",sv);
 
-    if (!ss_resolve_module_path(&sdir,&tmp,svname,src_frontend,info->owner)) return 0 ;
+    minsta = insta ;
+
+    if (!ss_resolve_module_path(&sdir, &tmp, sv, src, info->owner))
+        log_dieu(LOG_EXIT_SYS,"resolve source of module: ",sv);
 
     /** check mandatory directories:
      * module/module_name, module/module_name/{configure,service,service@} */
-    if (!check_dir(tmp.s,"")) return 0 ;
-    if (!check_dir(tmp.s,SS_MODULE_CONFIG_DIR)) return 0 ;
-    if (!check_dir(tmp.s,SS_MODULE_SERVICE)) return 0 ;
-    if (!check_dir(tmp.s,SS_MODULE_SERVICE_INSTANCE)) return 0 ;
+    if (!check_dir(tmp.s, "")) return 0 ;
+    if (!check_dir(tmp.s, SS_MODULE_CONFIG_DIR)) return 0 ;
+    if (!check_dir(tmp.s, SS_MODULE_SERVICE)) return 0 ;
+    if (!check_dir(tmp.s, SS_MODULE_SERVICE_INSTANCE)) return 0 ;
 
     newlen = sdir.len ;
 
     char permanent_sdir[sdir.len + 2] ;
-    auto_strings(permanent_sdir,sdir.s,"/") ;
+    auto_strings(permanent_sdir, sdir.s, "/") ;
+
+    r = scan_mode(sdir.s, S_IFDIR) ;
+    if (r < 0) { errno = EEXIST ; log_dieusys(LOG_EXIT_SYS,"conflicting format of: ", sdir.s) ; }
+    else if (!r) {
+
+        if (!hiercopy(tmp.s, sdir.s))
+            log_dieusys(LOG_EXIT_SYS, "copy: ", tmp.s, " to: ", sdir.s) ;
+
+    } else {
 
-    r = scan_mode(sdir.s,S_IFDIR) ;
-    if (r < 0) { errno = EEXIST ; log_warnusys_return(LOG_EXIT_ZERO,"conflicting format of: ",sdir.s) ; }
-    else if (!r)
-    {
-        if (!hiercopy(tmp.s,sdir.s))
-            log_warnusys_return(LOG_EXIT_ZERO,"copy: ",tmp.s," to: ",sdir.s) ;
-    }
-    else
-    {
         /** Must reconfigure all services of the module */
-        if (force < 2)
-        {
-            log_warn("skip configuration of the module: ",svname," -- already configured") ;
+        if (force < 2) {
+
+            log_warn("skip configuration of the module: ", sv, " -- already configured") ;
             err = 2 ;
             goto make_deps ;
         }
 
         if (rm_rf(sdir.s) < 0)
-            log_warnusys_return (LOG_EXIT_ZERO,"remove: ",sdir.s) ;
+            log_dieusys (LOG_EXIT_SYS, "remove: ", sdir.s) ;
 
-        if (!hiercopy(tmp.s,sdir.s))
-            log_warnusys_return(LOG_EXIT_ZERO,"copy: ",tmp.s," to: ",sdir.s) ;
+        if (!hiercopy(tmp.s, sdir.s))
+            log_dieusys(LOG_EXIT_SYS,"copy: ", tmp.s, " to: ", sdir.s) ;
     }
 
     /** regex file content */
     list.len = 0 ;
 
-    if (!get_list(&list,&sdir,newlen,svname,S_IFREG)) return 0 ;
-    if (!regex_replace(&list,sv_before,svname)) return 0 ;
+    if (!get_list(&list, &sdir, newlen, sv, S_IFREG)) return 0 ;
+    if (!regex_replace(&list, alltype, sv)) return 0 ;
 
     /* regex directories name */
-    if (!get_list(&list,&sdir,newlen,svname,S_IFDIR)) return 0 ;
-    if (!regex_rename(&list,sv_before->type.module.iddir,sv_before->type.module.ndir,sdir.s)) return 0 ;
+    if (!get_list(&list, &sdir, newlen, sv, S_IFDIR)) return 0 ;
+    if (!regex_rename(&list, alltype->type.module.iddir, alltype->type.module.ndir, sdir.s)) return 0 ;
 
     /* regex files name */
     list.len = 0 ;
 
-    if (!get_list(&list,&sdir,newlen,svname,S_IFREG)) return 0 ;
-    if (!regex_rename(&list,sv_before->type.module.idfiles,sv_before->type.module.nfiles,sdir.s)) return 0 ;
+    if (!get_list(&list,&sdir, newlen, sv, S_IFREG)) return 0 ;
+    if (!regex_rename(&list, alltype->type.module.idfiles, alltype->type.module.nfiles, sdir.s)) return 0 ;
 
     /* launch configure script */
-    if (!regex_configure(sv_before,info,permanent_sdir,svname,conf)) return 0 ;
+    if (!regex_configure(alltype, info, permanent_sdir, sv, conf)) return 0 ;
 
     make_deps:
 
     tmp.len = 0 ;
     list.len = 0 ;
 
-    if (!auto_stra(&tmp,permanent_sdir,SS_MODULE_SERVICE + 1))
-        log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ;
+    if (!auto_stra(&tmp, permanent_sdir, SS_MODULE_SERVICE + 1))
+        log_die_nomem("stralloc") ;
 
     /** get all services */
-    if (!sastr_dir_get_recursive(&list,tmp.s,"",S_IFREG, 0))
-        log_warnusys_return(LOG_EXIT_ZERO,"get file(s) of module: ",svname) ;
+    char const *exclude[1] = { 0 } ;
+    if (!sastr_dir_get_recursive(&list, tmp.s, exclude, S_IFREG, 1))
+        log_dieusys(LOG_EXIT_SYS, "get file(s) of module: ", sv) ;
+
+    /** add addon services */
+    if (alltype->type.module.naddservices > 0) {
+
+        id = alltype->type.module.idaddservices, nid = alltype->type.module.naddservices ;
+        for (; nid ; id += strlen(keep.s + id) + 1, nid--) {
 
-    /** add addon service */
-    if (sv_before->type.module.naddservices > 0)
-    {
-        id = sv_before->type.module.idaddservices, nid = sv_before->type.module.naddservices ;
-        for (;nid; id += strlen(keep.s + id) + 1, nid--)
-        {
             char *name = keep.s + id ;
-            if (ss_resolve_src_path(&list,name,info->owner,0) < 1)
-                    log_warnu_return(LOG_EXIT_ZERO,"resolve source path of: ",name) ;
+            if (ss_resolve_src_path(&list, name, info->owner,0) < 1)
+                    log_die(LOG_EXIT_SYS, "resolve source path of: ", name) ;
         }
     }
 
     tmp.len = 0 ;
     sdir.len = 0 ;
 
-    /** remake the deps field
-     * incoporate the module service deps inside the list to parse
+    /** remake the depends field.
+     * incoporate the module services dependencies inside the list to parse
      * and each dependency of each module service dependency.
      * Do it recursively. */
-    if (!rebuild_list(sv_before,&list,&tmp,&sdir))
-        log_warnu(LOG_EXIT_ZERO,"rebuild dependencies list of; ",svname) ;
+    if (!rebuild_list(alltype, &list, &tmp, &sdir))
+        log_dieu(LOG_EXIT_SYS,"rebuild dependencies list of: ", sv) ;
 
     /** parse all services of the modules */
-    for (pos = 0 ; pos < list.len ; pos += strlen(list.s + pos) + 1)
-    {
-        insta = 0, svtype = -1 , from_ext_insta = 0 , already_parsed = 0 ;
-        char *sv = list.s + pos ;
-        size_t len = strlen(sv) ;
+    for (pos = 0 ; pos < list.len ; pos += strlen(list.s + pos) + 1) {
+
+        insta = 0, svtype = -1, from_ext_insta = 0, already_parsed = 0 ;
+        char *svname = list.s + pos ;
+        size_t len = strlen(svname) ;
         char bname[len + 1] ;
         char *pbname = 0 ;
 
         addonsv.len = 0 ;
 
-        if (sastr_cmp(parsed_list,sv) >= 0)
-        {
+        if (sastr_cmp(parsed_list, svname) >= 0) {
+
             /** already parsed ? */
             size_t idx = 0 ;
-            for (; idx < genalloc_len(sv_alltype,&gasv) ; idx++)
-            {
-                char *name = keep.s + genalloc_s(sv_alltype,&gasv)[idx].src ;
+            for (; idx < genalloc_len(sv_alltype, &gasv) ; idx++) {
+
+                char *name = keep.s + genalloc_s(sv_alltype, &gasv)[idx].src ;
 
-                if (!strcmp(name,sv))
-                {
-                    sv = name ;
+                if (!strcmp(name, svname)) {
+
+                    svname = name ;
                     break ;
                 }
             }
             already_parsed = 1 ;
         }
 
-        if (!ob_basename(bname,sv))
-            log_warnu_return(LOG_EXIT_ZERO,"find basename of: ",sv) ;
+        if (!ob_basename(bname,svname))
+            log_dieu(LOG_EXIT_SYS,"find basename of: ", svname) ;
 
         pbname = bname ;
 
         /** detect cyclic call. Sub-module cannot call it itself*/
-        if (!strcmp(svname,bname))
-            log_warn_return(LOG_EXIT_ZERO,"cyclic call detected -- ",svname," call ",bname) ;
+        if (!strcmp(sv, bname))
+            log_die(LOG_EXIT_SYS,"cyclic call detected -- ", sv, " call ", bname) ;
 
         insta = instance_check(bname) ;
-        if (!insta) log_warn_return(LOG_EXIT_ZERO,"invalid instance name: ",sv) ;
-        if (insta > 0)
-        {
+        if (!insta) log_die(LOG_EXIT_SYS,"invalid instance name: ", svname) ;
+        if (insta > 0) {
+
             /** we can't know the origin of the instanciated service.
              * Search first at service@ directory, if it not found
              * pass through the classic ss_resolve_src_path() */
 
             pbname = bname ;
-            if (!already_parsed)
-            {
+            if (!already_parsed) {
+
                 int found = 0 ;
                 size_t l = strlen(permanent_sdir) ;
                 char tmp[l + SS_MODULE_SERVICE_INSTANCE_LEN + 2] ;
-                auto_strings(tmp,permanent_sdir,SS_MODULE_SERVICE_INSTANCE + 1,"/") ;
+                auto_strings(tmp, permanent_sdir, SS_MODULE_SERVICE_INSTANCE + 1, "/") ;
+
+                r = ss_resolve_src(&addonsv, pbname, tmp, &found) ;
 
-                r = ss_resolve_src(&addonsv,pbname,tmp,&found) ;
+                if (r == -1) log_dieusys(LOG_EXIT_SYS,"parse source directory: ", tmp) ;
+                if (!r) {
 
-                if (r == -1) log_warnusys_return(LOG_EXIT_ZERO,"parse source directory: ",tmp) ;
-                if (!r)
-                {
-                    if (ss_resolve_src_path(&addonsv,pbname,info->owner,0) < 1)
-                        log_warnu_return(LOG_EXIT_ZERO,"resolve source path of: ",pbname) ;
+                    if (ss_resolve_src_path(&addonsv, pbname, info->owner, 0) < 1)
+                        log_dieu(LOG_EXIT_SYS,"resolve source path of: ", pbname) ;
                 }
-                sv = addonsv.s ;
+                svname = addonsv.s ;
             }
             from_ext_insta++ ;
-            len = strlen(sv) ;
+            len = strlen(svname) ;
         }
 
         if (!already_parsed)
-            if (!parse_service_before(info,parsed_list,tree_list,sv,nbsv,sasv,force,conf,0,permanent_sdir))
-                log_warnu_return(LOG_EXIT_ZERO,"parse: ",sv," from module: ",svname) ;
+            start_parser(svname, info, 0, permanent_sdir) ;
 
         char ext_insta[len + 1] ;
         if (from_ext_insta) {
-            size_t len = strlen(sv) ;
-            r = get_rlen_until(sv,'@',len) + 1 ;
+
+            size_t len = strlen(svname) ;
+            r = get_rlen_until(svname, '@', len) + 1 ;
             size_t newlen = len - (len - r) ;
-            auto_strings(ext_insta,sv) ;
+            auto_strings(ext_insta, svname) ;
             ext_insta[newlen] = 0 ;
-            sv = ext_insta ;
+            svname = ext_insta ;
         }
 
         /** we want the configuration file for each service inside
@@ -331,32 +357,34 @@ int parse_module(sv_alltype *sv_before,ssexec_t *info,stralloc *parsed_list,stra
          * In case of sub-module, we skip it.
          * Also, we skip every dependency of the sub-module,
          * each module contains its own services.*/
-        char *version = keep.s + sv_before->cname.version ;
+        char *version = keep.s + alltype->cname.version ;
+
         {
             stralloc tmpenv = STRALLOC_ZERO ;
-            /** 512 is the maximum of services set by default
-             * that can be supervised by s6-svscan. It should be large
-             * enough for the majority of the cases */
-            size_t pos, spos, id, nid, idmodule[512] = { 0 } ;
+            /** SS_MAX_SERVICE is the maximum of services set at compile time
+             * that can be supervised by s6-svscan. 500 is the default which
+             * should be large enough for the majority of the cases */
+            size_t pos, spos, id, nid, idmodule[SS_MAX_SERVICE] = { 0 } ;
             sv_alltype_ref svref ;
 
-            if (!env_resolve_conf(&tmpenv,svname,info->owner))
-                log_warnu_return(LOG_EXIT_ZERO,"get path of the configuration file") ;
+            if (!env_resolve_conf(&tmpenv, sv, info->owner))
+                log_dieu(LOG_EXIT_SYS,"get path of the configuration file") ;
 
-            if (!auto_stra(&tmpenv,"/")) log_warn_return(LOG_EXIT_ZERO,"stralloc") ;
+            if (!auto_stra(&tmpenv, "/"))
+                log_die_nomem("stralloc") ;
 
             /** search first for all sub-modules */
-            for (pos = 0 ; pos < genalloc_len(sv_alltype,&gasv);pos++)
-            {
-                if (genalloc_s(sv_alltype,&gasv)[pos].cname.itype == TYPE_MODULE)
-                {
+            for (pos = 0 ; pos < genalloc_len(sv_alltype,&gasv); pos++) {
+
+                if (genalloc_s(sv_alltype,&gasv)[pos].cname.itype == TYPE_MODULE) {
+
                     idmodule[pos] = 1 ;
 
                     svref = &genalloc_s(sv_alltype,&gasv)[pos] ;
 
                     id = svref->cname.idcontents, nid = svref->cname.ncontents ;
-                    for (;nid; id += strlen(deps.s + id) + 1, nid--)
-                    {
+                    for (;nid; id += strlen(deps.s + id) + 1, nid--) {
+
                         char *name = deps.s + id ;
 
                         for (spos = 0 ; spos < genalloc_len(sv_alltype,&gasv);spos++)
@@ -366,63 +394,79 @@ int parse_module(sv_alltype *sv_before,ssexec_t *info,stralloc *parsed_list,stra
                 }
             }
 
-            for (pos = 0 ; pos < genalloc_len(sv_alltype,&gasv);pos++)
-            {
+            for (pos = 0 ; pos < genalloc_len(sv_alltype,&gasv); pos++) {
+
                 if (!genalloc_s(sv_alltype,&gasv)[pos].opts[2] ||
                 idmodule[pos]) continue ;
                 char *n = keep.s + genalloc_s(sv_alltype,&gasv)[pos].cname.name ;
 
-                if (!strcmp(n,bname))
-                {
+                if (!strcmp(n,bname)) {
+
                     genalloc_s(sv_alltype,&gasv)[pos].srconf = keep.len ;
                     if (!auto_stra(&tmpenv,version,"/",bname)) log_warn_return(LOG_EXIT_ZERO,"stralloc") ;
 
                     if (!stralloc_catb(&keep,tmpenv.s,strlen(tmpenv.s) + 1))
-                        log_warn_return(LOG_EXIT_ZERO,"stralloc") ;
+                        log_die_nomem("stralloc") ;
                     break ;
                 }
             }
             stralloc_free(&tmpenv) ;
         }
 
-        svtype = get_svtype_from_file(sv) ;
-        if (svtype == -1) log_warnu_return(LOG_EXIT_ZERO,"get svtype of: ",sv) ;
+        svtype = get_svtype_from_file(svname) ;
+        if (svtype == -1) log_dieu(LOG_EXIT_SYS,"get svtype of: ",svname) ;
 
         if (sastr_cmp(&sdir,pbname) == -1)
             if (!stralloc_catb(&sdir,pbname,strlen(pbname) + 1))
-                log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ;
+                log_die_nomem("stralloc") ;
 
         if (sastr_cmp(&tmp,pbname) == -1)
             if (svtype != TYPE_CLASSIC)
                 if (!stralloc_catb(&tmp,pbname,strlen(pbname) + 1))
-                    log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ;
+                    log_die_nomem("stralloc") ;
     }
 
-    sv_before->cname.idga = deps.len ;
-    sv_before->cname.nga = 0 ;
-    for (pos = 0 ;pos < tmp.len ; pos += strlen(tmp.s + pos) + 1)
-    {
-        stralloc_catb(&deps,tmp.s + pos,strlen(tmp.s + pos) + 1) ;
-        sv_before->cname.nga++ ;
+    /** prefix each service inside the module with the name of the module */
+    list.len = 0 ;
+    if (!instance_splitname(&list,sv,minsta,SS_INSTANCE_NAME))
+            log_dieu(LOG_EXIT_SYS, "split instance service: ",sv) ;
+
+    list.len-- ; //instance_splitname close the string
+
+    if (!auto_stra(&list,"-"))
+        log_die_nomem("stralloc") ;
+
+    alltype->cname.idga = deps.len ;
+    alltype->cname.nga = 0 ;
+    for (pos = 0 ;pos < tmp.len ; pos += strlen(tmp.s + pos) + 1) {
+
+        if (!stralloc_catb(&deps,list.s, list.len) ||
+            !stralloc_catb(&deps,tmp.s + pos,strlen(tmp.s + pos) + 1))
+                log_die_nomem("stralloc") ;
+
+        alltype->cname.nga++ ;
     }
 
-    sv_before->cname.idcontents = deps.len ;
-    for (pos = 0 ;pos < sdir.len ; pos += strlen(sdir.s + pos) + 1)
-    {
-        stralloc_catb(&deps,sdir.s + pos,strlen(sdir.s + pos) + 1) ;
-        sv_before->cname.ncontents++ ;
+    alltype->cname.idcontents = deps.len ;
+    for (pos = 0 ;pos < sdir.len ; pos += strlen(sdir.s + pos) + 1) {
+
+        if (!stralloc_catb(&deps,list.s, list.len) ||
+            !stralloc_catb(&deps,sdir.s + pos,strlen(sdir.s + pos) + 1))
+                log_die_nomem("stralloc") ;
+
+        alltype->cname.ncontents++ ;
     }
 
     tmp.len = 0 ;
     if (!auto_stra(&tmp,permanent_sdir,SS_MODULE_CONFIG_DIR + 1))
-        log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ;
+        log_die_nomem("stralloc") ;
+
     if (rm_rf(tmp.s) < 0)
-        log_warnusys_return(LOG_EXIT_ZERO,"remove: ",tmp.s) ;
+        log_dieusys(LOG_EXIT_SYS,"remove: ",tmp.s) ;
 
     stralloc_free(&sdir) ;
     stralloc_free(&list) ;
     stralloc_free(&tmp) ;
-    stralloc_free(&moduleinsta) ;
     stralloc_free(&addonsv) ;
 
     return err ;
@@ -487,7 +531,7 @@ int regex_get_regex(char *regex, char const *str)
     return 1 ;
 }
 
-int regex_replace(stralloc *list,sv_alltype *sv_before,char const *svname)
+int regex_replace(stralloc *list,sv_alltype *alltype,char const *svname)
 {
     log_flow() ;
 
@@ -511,7 +555,7 @@ int regex_replace(stralloc *list,sv_alltype *sv_before,char const *svname)
         if (!r) log_warnusys_return(LOG_EXIT_ZERO,"read file: ",str) ;
         if (r == -1) continue ;
 
-        pos = sv_before->type.module.start_infiles, inlen = sv_before->type.module.end_infiles ;
+        pos = alltype->type.module.start_infiles, inlen = alltype->type.module.end_infiles ;
         for (; pos < inlen ; pos += strlen(keep.s + pos) + 1)
         {
             int all = 0, fpos = 0 ;
@@ -603,13 +647,13 @@ int regex_rename(stralloc *list, int id, unsigned int nid, char const *sdir)
     return 1 ;
 }
 
-int regex_configure(sv_alltype *sv_before,ssexec_t *info, char const *module_dir,char const *module_name,uint8_t conf)
+int regex_configure(sv_alltype *alltype,ssexec_t *info, char const *module_dir,char const *module_name,uint8_t conf)
 {
     log_flow() ;
 
     int wstat, r ;
     pid_t pid ;
-    size_t clen = sv_before->type.module.configure > 0 ? 1 : 0 ;
+    size_t clen = alltype->type.module.configure > 0 ? 1 : 0 ;
     size_t module_dirlen = strlen(module_dir), n ;
 
     stralloc env = STRALLOC_ZERO ;
@@ -658,13 +702,13 @@ int regex_configure(sv_alltype *sv_before,ssexec_t *info, char const *module_dir
                 log_warnu_return(LOG_EXIT_ZERO,"append environment variables") ;
         }
         /** environment is not mandatory */
-        if (sv_before->opts[2] > 0)
+        if (alltype->opts[2] > 0)
         {
             stralloc oenv = STRALLOC_ZERO ;
             stralloc name = STRALLOC_ZERO ;
             stralloc dst = STRALLOC_ZERO ;
 
-            if (!env_prepare_for_write(&name,&dst,&oenv,sv_before,conf))
+            if (!env_prepare_for_write(&name,&dst,&oenv,alltype,conf))
                 return 0 ;
 
             if (!write_env(name.s,oenv.s,dst.s))
@@ -697,8 +741,8 @@ int regex_configure(sv_alltype *sv_before,ssexec_t *info, char const *module_dir
         m = 0 ;
         newargv[m++] = config_script ;
 
-        if (sv_before->type.module.configure > 0)
-            newargv[m++] = keep.s + sv_before->type.module.configure ;
+        if (alltype->type.module.configure > 0)
+            newargv[m++] = keep.s + alltype->type.module.configure ;
 
         newargv[m++] = 0 ;
 
diff --git a/src/lib66/parse_service.c b/src/lib66/parse_service.c
new file mode 100644
index 0000000000000000000000000000000000000000..6c49e57b76daa01e072517f31c5e93c59a18192f
--- /dev/null
+++ b/src/lib66/parse_service.c
@@ -0,0 +1,415 @@
+/*
+ * parse_service.c
+ *
+ * Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
+ *
+ * All rights reserved.
+ *
+ * This file is part of Obarun. It is subject to the license terms in
+ * the LICENSE file found in the top-level directory of this
+ * distribution.
+ * This file may not be copied, modified, propagated, or distributed
+ * except according to the terms contained in the LICENSE file./
+ */
+
+#include <66/parser.h>
+
+#include <stdint.h>
+#include <string.h>
+
+#include <oblibs/log.h>
+#include <oblibs/sastr.h>
+#include <oblibs/string.h>
+#include <oblibs/types.h>
+
+#include <skalibs/stralloc.h>
+#include <skalibs/genalloc.h>
+
+#include <66/utils.h>
+#include <66/constants.h>
+#include <66/ssexec.h>
+#include <66/service.h>
+#include <66/tree.h>
+
+static void parse_service_instance(stralloc *frontend, char const *svsrc, char const *sv, int insta)
+{
+    log_flow() ;
+
+    stralloc sa = STRALLOC_ZERO ;
+
+    if (!instance_splitname(&sa, sv, insta, SS_INSTANCE_TEMPLATE))
+        log_die(LOG_EXIT_SYS, "split instance service: ", sv) ;
+
+    log_trace("read frontend service of: ", svsrc, sa.s) ;
+
+    if (read_svfile(frontend, sa.s, svsrc) <= 0)
+        log_dieusys(LOG_EXIT_SYS, "read frontend service of: ", svsrc, sa.s) ;
+
+    stralloc_free(&sa) ;
+
+    if (!instance_create(frontend, sv, SS_INSTANCE_REGEX, insta))
+        log_die(LOG_EXIT_SYS, "create instance service: ", sv) ;
+
+    /** ensure that we have an empty line at the end of the string*/
+    if (!auto_stra(frontend, "\n"))
+        log_die_nomem("stralloc") ;
+
+}
+
+static int parse_add_service(stralloc *parsed_list, sv_alltype *alltype, char const *service, uint8_t conf)
+{
+    log_flow() ;
+
+    log_trace("add service: ", service) ;
+
+    // keep overwrite_conf
+    alltype->overwrite_conf = conf ;
+
+    // keep source of the frontend file
+    alltype->src = keep.len ;
+
+    if (!sastr_add_string(&keep, service))
+        return 0 ;
+
+    // keep service on current list
+    if (!sastr_add_string(parsed_list, service))
+        return 0 ;
+
+    if (!genalloc_append(sv_alltype, &gasv, alltype))
+        return 0 ;
+
+    return 1 ;
+}
+
+static void set_info(ssexec_t *info)
+{
+    log_flow() ;
+
+    info->tree.len = 0 ;
+    int r = ssexec_set_treeinfo(info) ;
+    if (r == -4) log_die(LOG_EXIT_USER,"You're not allowed to use the tree: ",info->tree.s) ;
+    if (r == -3) log_dieu(LOG_EXIT_USER,"find the current tree. You must use the -t options") ;
+    if (r == -2) log_dieu(LOG_EXIT_USER,"set the tree name") ;
+    if (r == -1) log_dieu(LOG_EXIT_USER,"parse seed file") ;
+    if (!r) log_dieusys(LOG_EXIT_SYS,"find tree: ", info->treename.s) ;
+
+}
+#include <stdio.h>
+/* @sv -> name of the service to parse with
+ * the path of the frontend file source
+ * @Return 0 on fail
+ * @Return 1 on success
+ * @Return 2 -> already parsed */
+int parse_service(char const *sv, stralloc *parsed_list, ssexec_t *info, uint8_t force, uint8_t conf)
+{
+
+    log_flow() ;
+
+    if (sastr_cmp(parsed_list, sv) >= 0) {
+
+        log_warn("ignoring: ", sv, " service -- already parsed") ;
+        return 2 ;
+    }
+
+    log_trace("parse service: ", sv) ;
+
+    int insta, r ;
+    size_t svlen = strlen(sv) ;
+    char svname[svlen + 1], svsrc[svlen + 1] ;
+
+    sv_alltype alltype = SV_ALLTYPE_ZERO ;
+    stralloc frontend = STRALLOC_ZERO ;
+    stralloc satree = STRALLOC_ZERO ;
+
+    if (!ob_basename(svname, sv))
+        log_dieu(LOG_EXIT_SYS, "get basename of: ", sv) ;
+
+    if (!ob_dirname(svsrc, sv))
+        log_dieu(LOG_EXIT_SYS, "get dirname of: ", sv) ;
+
+    insta = instance_check(svname) ;
+    if (!insta) {
+
+        log_die(LOG_EXIT_SYS, "invalid instance name: ", svname) ;
+
+    } else if (insta > 0) {
+
+        parse_service_instance(&frontend, svsrc, svname, insta) ;
+
+    } else {
+
+        log_trace("read frontend service of: ", sv) ;
+
+        if (read_svfile(&frontend, svname, svsrc) <= 0)
+            log_dieusys(LOG_EXIT_SYS, "read frontend service of: ", sv) ;
+    }
+
+    r = service_isenabledat(&satree, svname) ;
+    if (r < -1)
+        log_dieu(LOG_EXIT_SYS, "check already enabled services") ;
+
+    if (r > 0) {
+
+        if (force) {
+
+            /* -t option was used */
+            if (!info->skip_opt_tree) {
+
+                if (strcmp(info->treename.s, satree.s))
+                    log_die(LOG_EXIT_SYS,"you can not force to enable again a service on different tree -- current: ", satree.s, " asked: ", info->treename.s, ". Try first to disable it") ;
+
+            } else {
+
+                if (!auto_stra(&info->treename, satree.s))
+                    log_die_nomem("stralloc") ;
+            }
+
+            goto set ;
+
+        } else {
+
+            log_info("ignoring service: ", sv, " -- already enabled at tree: ", satree.s) ;
+
+            /** we don't care about the use of the -t option. The define of the
+             * info->tree and info->treename is just made to avoid segmentation fault
+             * at the rest of the process. The service is not parsed or enable again anyway. */
+
+            info->treename.len = 0 ;
+            if (!auto_stra(&info->treename, satree.s))
+                log_die_nomem("stralloc") ;
+
+            set_info(info) ;
+
+            sv_alltype_free(&alltype) ;
+            stralloc_free(&frontend) ;
+            stralloc_free(&satree) ;
+            return 2 ;
+        }
+    }
+
+    if (info->skip_opt_tree) {
+
+        /** first try to find the @intree key at the frontend file*/
+        if (!get_svintree(&alltype,frontend.s))
+            log_die(LOG_EXIT_USER, "invalid value for key: ",get_key_by_enum(ENUM_KEY_SECTION_MAIN,KEY_MAIN_INTREE)," in service file: ", sv) ;
+
+        if (alltype.cname.intree >= 0) {
+
+            info->treename.len = 0 ;
+            if (!auto_stra(&info->treename, keep.s + alltype.cname.intree))
+                log_die_nomem("stralloc") ;
+
+        }
+    }
+
+    set:
+
+    set_info(info) ;
+
+    if (!get_svtype(&alltype, frontend.s))
+        log_die(LOG_EXIT_USER, "invalid value for key: ", get_key_by_enum(ENUM_KEY_SECTION_MAIN, KEY_MAIN_TYPE), " at frontend service: ", sv) ;
+
+    /** contents of directory should be listed by ss_resolve_src_path
+     * except for module type */
+    if (scan_mode(sv,S_IFDIR) == 1 && alltype.cname.itype != TYPE_MODULE)
+        goto freed ;
+
+    alltype.cname.name = keep.len ;
+    if (!sastr_add_string(&keep, svname))
+        log_die_nomem("stralloc") ;
+
+    if (!parser(&alltype, &frontend, svname, alltype.cname.itype))
+        log_dieu(LOG_EXIT_SYS, "parse service: ", sv) ;
+
+    if (!parse_add_service(parsed_list, &alltype, sv, conf))
+        log_dieu(LOG_EXIT_SYS, "add service: ", sv) ;
+
+    freed:
+    stralloc_free(&frontend) ;
+    stralloc_free(&satree) ;
+
+    return 1 ;
+}
+
+int parse_service_deps(sv_alltype *alltype, ssexec_t *info, stralloc *parsed_list, uint8_t force, char const *directory_forced)
+{
+
+    log_flow() ;
+
+    int r, e = 0 ;
+    stralloc sa = STRALLOC_ZERO ;
+
+    if (alltype->cname.nga) {
+
+        size_t id = alltype->cname.idga, nid = alltype->cname.nga ;
+        for (; nid ; id += strlen(deps.s + id) + 1, nid--) {
+
+            sa.len = 0 ;
+
+            if (alltype->cname.itype != TYPE_BUNDLE) {
+
+                log_trace("service: ", keep.s + alltype->cname.name, " depends on: ", deps.s + id) ;
+
+            } else log_trace("bundle: ", keep.s + alltype->cname.name, " contents: ", deps.s + id," as service") ;
+
+            r = ss_resolve_src_path(&sa, deps.s + id, info->owner, directory_forced) ;
+            if (r < 1) goto err ;//don't warn here, the ss_revolve_src_path do it
+
+            if (!parse_service(sa.s, parsed_list, info, force, alltype->overwrite_conf))
+                goto err ;
+        }
+
+    } else log_trace(keep.s + alltype->cname.name,": haven't dependencies") ;
+
+    e = 1 ;
+
+    err:
+        stralloc_free(&sa) ;
+        return e ;
+}
+
+int parse_service_optsdeps(stralloc *rebuild, sv_alltype *alltype, ssexec_t *info, stralloc *parsed_list, uint8_t force, uint8_t field, char const *directory_forced)
+{
+    log_flow() ;
+
+    int r, e = 0 ;
+    stralloc sa = STRALLOC_ZERO ;
+
+    size_t id, nid ;
+    uint8_t ext = field == KEY_MAIN_EXTDEPS ? 1 : 0 ;
+
+    int idref = alltype->cname.idopts ;
+    unsigned int nref = alltype->cname.nopts ;
+    if (ext) {
+        idref = alltype->cname.idext ;
+        nref = alltype->cname.next ;
+    }
+
+    if (nref) {
+
+        id = (size_t)idref, nid = (size_t)nref ;
+        for (; nid ; id += strlen(deps.s + id) + 1, nid--) {
+
+            sa.len = 0 ;
+            // 0 -> not found, 1 -> found, -1 -> system error
+            r = service_isenabled(deps.s + id) ;
+            if (r == -1)
+                log_dieu(LOG_EXIT_SYS, "check already enabled services") ;
+
+            if (r > 0) {
+                if (!ext)
+                    break ;
+                else
+                    continue ;
+            }
+
+            r = ss_resolve_src_path(&sa, deps.s + id, info->owner, directory_forced) ;
+            if (r == -1)
+                goto err ;
+
+            if (!r) {
+
+                log_trace("unable to find", ext ? " external " : " optional ", "dependency: ", deps.s + id, " for service: ", keep.s + alltype->cname.name) ;
+
+                // external deps must exist
+                if (ext)
+                    goto err ;
+
+                continue ;
+            }
+
+            if (!parse_service(sa.s, parsed_list, info, force, alltype->overwrite_conf))
+                goto err ;
+
+            if (!sastr_add_string(rebuild, deps.s + id))
+                log_die_nomem("stralloc") ;
+
+            // we only keep the first optsdepends found
+            if (!ext) break ;
+        }
+
+    } else log_trace(keep.s + alltype->cname.name,": haven't", ext ? " external " : " optional ", "dependencies") ;
+
+    e = 1 ;
+
+    err:
+        stralloc_free(&sa) ;
+        return e ;
+}
+
+int parse_service_alldeps(sv_alltype *alltype, ssexec_t *info, stralloc *parsed_list, uint8_t force, char const *directory_forced)
+{
+    log_flow() ;
+
+    int e = 0 ;
+    size_t id, nid, pos ;
+    char *name = keep.s + alltype->cname.name ;
+    stralloc sa = STRALLOC_ZERO ;
+    stralloc rebuild = STRALLOC_ZERO ;
+
+    if (!parse_service_deps(alltype, info, parsed_list, force, directory_forced)) {
+        log_warnu("parse dependencies of: ", name) ;
+        goto err ;
+    }
+
+    if (!parse_service_optsdeps(&rebuild, alltype, info, parsed_list, force, KEY_MAIN_EXTDEPS,  directory_forced)) {
+        log_warnu("parse external dependencies of: ", name) ;
+        goto err ;
+    }
+
+    if (!parse_service_optsdeps(&rebuild, alltype, info, parsed_list, force, KEY_MAIN_OPTSDEPS,  directory_forced)) {
+        log_warnu("parse optional dependencies of: ", name) ;
+        goto err ;
+    }
+
+    // rebuild the dependencies list of the service to add the new dependencies.
+    if (rebuild.len) {
+
+        pos = 0 ;
+        sa.len = 0 ;
+        id = alltype->cname.idga ;
+        nid = alltype->cname.nga ;
+
+        {
+            for (; nid ; id += strlen(deps.s + id) + 1, nid--) {
+                if (!sastr_add_string(&sa, deps.s + id)) {
+                    log_warn("stralloc") ;
+                    goto err ;
+                }
+            }
+
+
+            FOREACH_SASTR(&rebuild, pos) {
+                if (!sastr_add_string(&sa, rebuild.s + pos)) {
+                    log_warn("stralloc") ;
+                    goto err ;
+                }
+            }
+
+        }
+
+        alltype->cname.idga = deps.len ;
+        alltype->cname.nga = 0 ;
+
+        pos = 0 ;
+        FOREACH_SASTR(&sa, pos) {
+
+            log_info("rebuil list", sa.s + pos) ;
+
+            if (!sastr_add_string(&deps,sa.s + pos)) {
+                log_warn("stralloc") ;
+                goto err ;
+            }
+
+            alltype->cname.nga++ ;
+        }
+    }
+
+    e = 1 ;
+
+    err:
+        stralloc_free(&rebuild) ;
+        stralloc_free(&sa) ;
+
+    return e ;
+}
diff --git a/src/lib66/parser_enabled.c b/src/lib66/parser_enabled.c
deleted file mode 100644
index c7a3f3d034f50dc276739dd5be868ac5e124cbb1..0000000000000000000000000000000000000000
--- a/src/lib66/parser_enabled.c
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
- * parser.c
- *
- * Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
- *
- * All rights reserved.
- *
- * This file is part of Obarun. It is subject to the license terms in
- * the LICENSE file found in the top-level directory of this
- * distribution.
- * This file may not be copied, modified, propagated, or distributed
- * except according to the terms contained in the LICENSE file./
- */
-
-#include <66/parser.h>
-
-#include <string.h>
-
-#include <oblibs/string.h>
-#include <oblibs/types.h>
-#include <oblibs/log.h>
-#include <oblibs/sastr.h>
-#include <oblibs/files.h>
-
-#include <skalibs/stralloc.h>
-#include <skalibs/djbunix.h>//environ
-
-#include <66/resolve.h>
-#include <66/utils.h>
-#include <66/constants.h>
-#include <66/environ.h>
-
-/* @sv -> name of the service to parse with
- * the path of the frontend file source
- * @Return 0 on fail
- * @Return 1 on success
- * @Return 2 -> already parsed */
-int parse_service_before(ssexec_t *info,stralloc *parsed_list,stralloc *tree_list, char const *sv,unsigned int *nbsv, stralloc *sasv,uint8_t force,uint8_t conf,uint8_t disable_module,char const *directory_forced)
-{
-    log_flow() ;
-
-    log_trace("start parse process of service: ",sv) ;
-
-    if (sastr_cmp(parsed_list,sv) >= 0)
-    {
-        log_warn("ignoring: ",sv," service: already parsed") ;
-        sasv->len = 0 ;
-        return 2 ;
-    }
-
-    int insta ;
-    uint8_t exist = 0 ;
-    size_t svlen = strlen(sv), svnamelen ;
-    char svname[svlen + 1], svsrc[svlen + 1] ;
-    if (!ob_basename(svname,sv)) log_warnu_return(LOG_EXIT_ZERO,"get basename of: ",sv) ;
-    if (!ob_dirname(svsrc,sv)) log_warnu_return(LOG_EXIT_ZERO,"get dirname of: ",sv) ;
-
-    svnamelen = strlen(svname) ;
-    char tree[info->tree.len + SS_SVDIRS_LEN + 1] ;
-    auto_strings(tree,info->tree.s,SS_SVDIRS) ;
-
-    int r = parse_service_check_enabled(tree,svname,force,&exist) ;
-    if (!r) { sasv->len = 0 ; return 2 ; }
-
-    sv_alltype sv_before = SV_ALLTYPE_ZERO ;
-    sasv->len = 0 ;
-
-    insta = instance_check(svname) ;
-    if (!insta)
-    {
-        log_warn_return(LOG_EXIT_ZERO, "invalid instance name: ",svname) ;
-    }
-    else if (insta > 0)
-    {
-        stralloc tmp = STRALLOC_ZERO ;
-        instance_splitname(&tmp,svname,insta,SS_INSTANCE_TEMPLATE) ;
-        log_trace("read service file of: ",svsrc,tmp.s) ;
-        if (read_svfile(sasv,tmp.s,svsrc) <= 0) return 0 ;
-        stralloc_free(&tmp) ;
-    }
-    else {
-        log_trace("read service file of: ",svsrc,svname) ;
-        if (read_svfile(sasv,svname,svsrc) <= 0) return 0 ;
-    }
-
-    if (!get_svtype(&sv_before,sasv->s))
-        log_warn_return (LOG_EXIT_ZERO,"invalid value for key: ",get_key_by_enum(ENUM_KEY_SECTION_MAIN,KEY_MAIN_TYPE)," in service file: ",svsrc,svname) ;
-
-
-    sv_before.cname.name = keep.len ;
-    if (!stralloc_catb(&keep,svname,svnamelen + 1)) return 0 ;
-
-    /** contents of directory should be listed by ss_resolve_src_path
-     * execpt for module type */
-    if (scan_mode(sv,S_IFDIR) == 1 && sv_before.cname.itype != TYPE_MODULE) return 1 ;
-
-    if (insta > 0)
-    {
-        if (!instance_create(sasv,svname,SS_INSTANCE_REGEX,insta))
-            log_warn_return(LOG_EXIT_ZERO,"create instance service: ",svname) ;
-
-        /** ensure that we have an empty line at the end of the string*/
-        if (!stralloc_cats(sasv,"\n")) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ;
-        if (!stralloc_0(sasv)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ;
-    }
-
-    if (!parser(&sv_before,sasv,svname,sv_before.cname.itype)) return 0 ;
-
-    if ((sv_before.cname.itype > TYPE_CLASSIC && force > 1) || !exist)
-        if (!parse_service_all_deps(info,parsed_list,tree_list,&sv_before,sv,nbsv,sasv,force,conf,directory_forced)) return 0 ;
-
-    if (sv_before.cname.itype == TYPE_MODULE)
-    {
-        r = parse_module(&sv_before,info,parsed_list,tree_list,svname,svsrc,nbsv,sasv,force,conf) ;
-        if (!r) return 0 ;
-        else if (r == 2)
-        {
-            sasv->len = 0 ;
-            goto add ;
-        }
-
-        if (force > 1 && exist && disable_module)
-        {
-            char const *newargv[4] ;
-            unsigned int m = 0 ;
-
-            newargv[m++] = "fake_name" ;
-            newargv[m++] = svname ;
-            newargv[m++] = 0 ;
-            if (ssexec_disable(m,newargv,(const char *const *)environ,info))
-                log_warnu_return(LOG_EXIT_ZERO,"disable module: ",svname) ;
-        }
-    }
-    add:
-    if (!parse_add_service(parsed_list,&sv_before,sv,nbsv,info->owner,conf)) return 0 ;
-
-    return 1 ;
-}
-
-int parse_service_all_deps(ssexec_t *info,stralloc *parsed_list, stralloc *tree_list, sv_alltype *sv_before,char const *sv, unsigned int *nbsv,stralloc *sasv,uint8_t force, uint8_t conf,char const *directory_forced)
-{
-    log_flow() ;
-
-    stralloc rebuild = STRALLOC_ZERO ;
-
-    if (!parse_service_deps(info,parsed_list,tree_list,sv_before,sv,nbsv,sasv,force,conf,directory_forced)) return 0 ;
-    if (!parse_service_opts_deps(&rebuild,info,parsed_list,tree_list,sv_before,sv,nbsv,sasv,force,conf,KEY_MAIN_EXTDEPS,0)) return 0 ;
-    if (!parse_service_opts_deps(&rebuild,info,parsed_list,tree_list,sv_before,sv,nbsv,sasv,force,conf,KEY_MAIN_OPTSDEPS,0)) return 0 ;
-
-    if (rebuild.len)
-    {
-        size_t pos = 0 ;
-        stralloc old = STRALLOC_ZERO ;
-
-        //rebuild the dependencies list of the service
-        int id = sv_before->cname.idga ;
-        unsigned int nid = sv_before->cname.nga ;
-
-        for (;nid; id += strlen(deps.s + id) + 1, nid--)
-        {
-            if (!stralloc_catb(&old,deps.s + id,strlen(deps.s + id) + 1))
-                    log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ;
-        }
-        for (pos = 0 ; pos < rebuild.len ; pos += strlen(rebuild.s + pos) + 1)
-        {
-            if (!stralloc_catb(&old,rebuild.s + pos,strlen(rebuild.s + pos) + 1))
-                log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ;
-        }
-
-        sv_before->cname.idga = deps.len ;
-        sv_before->cname.nga = 0 ;
-
-        for (pos = 0 ; pos < old.len ; pos += strlen(old.s + pos) + 1)
-        {
-            if (!stralloc_catb(&deps,old.s + pos,strlen(old.s + pos) + 1))
-                log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ;
-            sv_before->cname.nga++ ;
-        }
-        stralloc_free(&old) ;
-    }
-
-    stralloc_free(&rebuild) ;
-
-    return 1 ;
-}
-
-int parse_service_deps(ssexec_t *info,stralloc *parsed_list,stralloc *tree_list, sv_alltype *sv_before, char const *sv,unsigned int *nbsv,stralloc *sasv,uint8_t force,uint8_t conf,char const *directory_forced)
-{
-    log_flow() ;
-
-    int r ;
-    char *dname = 0 ;
-    stralloc newsv = STRALLOC_ZERO ;
-
-    if (sv_before->cname.nga)
-    {
-        size_t id = sv_before->cname.idga, nid = sv_before->cname.nga ;
-        for (;nid; id += strlen(deps.s + id) + 1, nid--)
-        {
-            newsv.len = 0 ;
-            if (sv_before->cname.itype != TYPE_BUNDLE)
-            {
-                log_trace("service: ",sv, " depends on: ",deps.s+id) ;
-            }else log_trace("bundle: ",sv, " contents: ",deps.s+id," as service") ;
-            dname = deps.s + id ;
-            r = ss_resolve_src_path(&newsv,dname,info->owner,directory_forced) ;
-            if (r < 1) goto err ;//don't warn here, the ss_revolve_src_path already warn user
-
-            if (!parse_service_before(info,parsed_list,tree_list,newsv.s,nbsv,sasv,force,conf,0,directory_forced)) goto err ;
-        }
-    }
-    else log_trace(sv,": haven't dependencies") ;
-    stralloc_free(&newsv) ;
-    return 1 ;
-    err:
-        stralloc_free(&newsv) ;
-        return 0 ;
-}
-
-int parse_service_opts_deps(stralloc *rebuild,ssexec_t *info,stralloc *parsed_list,stralloc *tree_list,sv_alltype *sv_before,char const *sv,unsigned int *nbsv,stralloc *sasv,uint8_t force,uint8_t conf,uint8_t mandatory,char const *directory_forced)
-{
-    log_flow() ;
-
-    int r ;
-    stralloc newsv = STRALLOC_ZERO ;
-
-    size_t pos = 0 , baselen = strlen(info->base.s) + SS_SYSTEM_LEN ;
-    uint8_t found = 0, ext = mandatory == KEY_MAIN_EXTDEPS ? 1 : 0 ;
-    char *optname = 0 ;
-    char btmp[baselen + 1] ;
-    auto_strings(btmp,info->base.s,SS_SYSTEM) ;
-
-    int idref = sv_before->cname.idopts ;
-    unsigned int nref = sv_before->cname.nopts ;
-    if (ext) {
-        idref = sv_before->cname.idext ;
-        nref = sv_before->cname.next ;
-    }
-    // only pass here for the first time
-    if (!tree_list->len)
-    {
-        if (!sastr_dir_get(tree_list, btmp,SS_BACKUP + 1, S_IFDIR)) log_warnusys_return(LOG_EXIT_ZERO,"get list of tree at: ",btmp) ;
-    }
-
-    if (nref)
-    {
-        // may have no tree yet
-        if (tree_list->len)
-        {
-            size_t id = idref, nid = nref ;
-            for (;nid; id += strlen(deps.s + id) + 1, nid--)
-            {
-
-                newsv.len = 0 ;
-                optname = deps.s + id ;
-
-                for(pos = 0 ; pos < tree_list->len ; pos += strlen(tree_list->s + pos) +1 )
-                {
-                    found = 0 ;
-                    char *tree = tree_list->s + pos ;
-                    if (obstr_equal(tree,info->treename.s)) continue ;
-                    size_t treelen = strlen(tree) ;
-                    char tmp[baselen + 1 + treelen + SS_SVDIRS_LEN + 1] ;
-                    auto_strings(tmp,btmp,"/",tree,SS_SVDIRS) ;
-
-                    parse_service_check_enabled(tmp,optname,force,&found) ;
-                    if (found)
-                    {
-                        log_trace(ext ? "external" : "optional"," service dependency: ",optname," is already enabled at tree: ",btmp,"/",tree) ;
-                        break ;
-                    }
-                }
-                if (!found)
-                {
-                    // -1 mean system error. If the service doesn't exist it return 0
-                    r = ss_resolve_src_path(&newsv,optname,info->owner,directory_forced) ;
-                    if (r == -1) {
-                        goto err ; //don't warn here, the ss_revolve_src_path already warn user
-                    }
-                    else if (!r) {
-                        if (ext) goto err ;
-                    }
-                    // be paranoid with the else if
-                    else if (r == 1) {
-                        if (!parse_service_before(info,parsed_list,tree_list,newsv.s,nbsv,sasv,force,conf,0,directory_forced))
-                            goto err ;
-
-                        // add the new deps
-                        if (!stralloc_catb(rebuild,optname,strlen(optname) + 1))
-                            log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ;
-
-                        // we only keep the first found on optsdepends
-                        if (!ext) break ;
-                    }
-                }
-            }
-        }
-    }
-
-    stralloc_free(&newsv) ;
-    return 1 ;
-    err:
-        stralloc_free(&newsv) ;
-        return 0 ;
-}
-
-/** General helper */
-
-int parse_service_check_enabled(char const *tree,char const *svname,uint8_t force,uint8_t *exist)
-{
-    log_flow() ;
-
-    /** char const tree -> tree.s + SS_SVDIRS */
-    size_t namelen = strlen(svname), newlen = strlen(tree) ;
-    char tmp[newlen + SS_DB_LEN + SS_SRC_LEN + 1 + namelen + 1] ;
-    auto_strings(tmp,tree,SS_DB,SS_SRC,"/",svname) ;
-    /** search in db first, the most used */
-    if (scan_mode(tmp,S_IFDIR) > 0)
-    {
-        (*exist) = 1 ;
-        if (!force) goto found ;
-    }
-    /** svc */
-    auto_string_from(tmp,newlen,SS_SVC,"/",svname) ;
-    if (scan_mode(tmp,S_IFDIR) > 0)
-    {
-        (*exist) = 1 ;
-        if (!force) goto found ;
-    }
-
-    return 1 ;
-    found:
-        log_info("ignoring: ",svname," service: already enabled") ;
-        return 0 ;
-}
-
-int parse_add_service(stralloc *parsed_list,sv_alltype *sv_before,char const *service,unsigned int *nbsv,uid_t owner,uint8_t conf)
-{
-    log_flow() ;
-
-    log_trace("add service: ",service) ;
-    stralloc saconf = STRALLOC_ZERO ;
-    size_t svlen = strlen(service) ;
-    // keep overwrite_conf
-    sv_before->overwrite_conf = conf ;
-    // keep source of the frontend file
-    sv_before->src = keep.len ;
-    if (!stralloc_catb(&keep,service,svlen + 1)) goto err ;
-    // keep service on current list
-    if (!stralloc_catb(parsed_list,service,svlen + 1)) goto err ;
-    if (!genalloc_append(sv_alltype,&gasv,sv_before)) goto err ;
-    (*nbsv)++ ;
-    stralloc_free(&saconf) ;
-    return 1 ;
-    err:
-        stralloc_free(&saconf) ;
-        return 0 ;
-}
diff --git a/src/lib66/ssexec_enable.c b/src/lib66/ssexec_enable.c
index 650be9871d5707f18ee0aff5e690f32624c1826a..683f7d551223c061e65980a8d03b84793755075f 100644
--- a/src/lib66/ssexec_enable.c
+++ b/src/lib66/ssexec_enable.c
@@ -16,6 +16,8 @@
 #include <stdint.h>
 #include <errno.h>
 
+#include <stdio.h>
+
 #include <oblibs/obgetopt.h>
 #include <oblibs/log.h>
 #include <oblibs/string.h>
@@ -35,8 +37,11 @@
 #include <66/resolve.h>
 #include <66/ssexec.h>
 #include <66/environ.h>
+#include <66/service.h>
 
 static stralloc workdir = STRALLOC_ZERO ;
+stralloc PARSED_LIST = STRALLOC_ZERO ;
+
 /** force == 1, only rewrite the service
  * force == 2, rewrite the service and it dependencies*/
 static uint8_t FORCE = 0 ;
@@ -60,35 +65,76 @@ static void check_identifier(char const *name)
 
     int logname = get_rstrlen_until(name,SS_LOG_SUFFIX) ;
     if (logname > 0) log_die(LOG_EXIT_USER,"service: ",name,": ends with reserved suffix -log") ;
-    if (!memcmp(name,SS_MASTER+1,6)) log_die(LOG_EXIT_USER,"service: ",name,": starts with reserved prefix Master") ;
+    if (!memcmp(name, SS_MASTER + 1, 6)) log_die(LOG_EXIT_USER,"service: ",name,": starts with reserved prefix Master") ;
     if (!strcmp(name,SS_SERVICE)) log_die(LOG_EXIT_USER,"service as service name is a reserved name") ;
     if (!strcmp(name,"service@")) log_die(LOG_EXIT_USER,"service@ as service name is a reserved name") ;
 }
 
-void start_parser(stralloc *list,ssexec_t *info, unsigned int *nbsv,uint8_t force)
+void start_parser(char const *sv, ssexec_t *info, uint8_t disable_module, char const *directory_forced)
 {
     log_flow() ;
 
-    size_t i = 0 ;
+    size_t pos = 0 ;
 
-    stralloc sasv = STRALLOC_ZERO ;
     stralloc parsed_list = STRALLOC_ZERO ;
-    stralloc tree_list = STRALLOC_ZERO ;
-    uint8_t disable_module = 1 ;
 
-    FOREACH_SASTR(list,i) {
+    char *name = 0 ;
+    int r ;
+
+    r = parse_service(sv, &parsed_list, info, FORCE, CONF) ;
+    if (!r)
+        log_dieu(LOG_EXIT_SYS, "parse service file: ",name,": or its dependencies") ;
+
+    // already enabled
+    if (r == 2)
+        goto freed ;
+
+    // parse deps
+    pos = 0 ;
+    for (; pos < genalloc_len(sv_alltype, &gasv) ; pos ++) {
+
+        sv_alltype_ref sv = &genalloc_s(sv_alltype,&gasv)[pos] ;
+
+        name = keep.s + sv->cname.name ;
+
+        int exist = service_isenabled(name) ;
+
+        if (sv->cname.itype != TYPE_CLASSIC) {
 
-        char *name = list->s + i ;
+            if (FORCE > 1 || !exist) {
 
-        if (!parse_service_before(info,&parsed_list,&tree_list,name,nbsv,&sasv,force,CONF,disable_module,0))
-            log_dieu(LOG_EXIT_SYS,"parse service file: ",name,": or its dependencies") ;
+                if (!parse_service_alldeps(sv, info, &parsed_list, FORCE, directory_forced))
+                    log_dieu(LOG_EXIT_SYS, "parse dependencies of: ", name) ;
+
+                if (sv->cname.itype == TYPE_MODULE) {
+
+                    r = parse_module(sv, info, &parsed_list, FORCE) ;
+                    if (!r)
+                        log_dieu(LOG_EXIT_SYS, "parse module: ", name) ;
+
+                    else if (r == 2)
+                        continue ;
+
+                    if ((FORCE > 1) && (exist > 0) && disable_module) {
+
+                        char const *newargv[4] ;
+                        unsigned int m = 0 ;
+
+                        newargv[m++] = "fake_name" ;
+                        newargv[m++] = name ;
+                        newargv[m++] = 0 ;
+                        if (ssexec_disable(m, newargv, (char const *const *)environ, info))
+                            log_dieu(LOG_EXIT_SYS, "disable module: ", name) ;
+                    }
+                }
+            }
+        }
     }
-    stralloc_free(&sasv) ;
+    freed:
     stralloc_free(&parsed_list) ;
-    stralloc_free(&tree_list) ;
 }
 
-void start_write(stralloc *tostart,unsigned int *nclassic,unsigned int *nlongrun,char const *workdir, genalloc *gasv,ssexec_t *info,uint8_t FORCE,uint8_t CONF)
+void start_write(stralloc *tostart,unsigned int *nclassic,unsigned int *nlongrun,char const *workdir, genalloc *gasv,ssexec_t *info)
 {
     log_flow() ;
 
@@ -300,14 +346,24 @@ int ssexec_enable(int argc, char const *const *argv,char const *const *envp,ssex
             directory_forced = dname ;
         } else  sv = *argv ;
 
-        if (ss_resolve_src_path(&sasrc,sv,info->owner,!directory_forced ? 0 : directory_forced) < 1) log_dieu(LOG_EXIT_SYS,"resolve source path of: ",*argv) ;
+        if (ss_resolve_src_path(&sasrc,sv,info->owner,!directory_forced ? 0 : directory_forced) < 1)
+            log_dieu(LOG_EXIT_SYS,"resolve source path of: ",*argv) ;
     }
 
-    start_parser(&sasrc,info,&nbsv,FORCE) ;
-
+    FOREACH_SASTR(&sasrc, pos)
+        start_parser(sasrc.s + pos, info, 1, 0) ;
+
+    /**
+     *
+     *
+     * ATTENTION si -t ne pas passait alors info->tree et info->treename.s
+     * n'est pas definie
+     *
+     *
+     * */
     if (!tree_copy(&workdir,info->tree.s,info->treename.s)) log_dieusys(LOG_EXIT_SYS,"create tmp working directory") ;
 
-    start_write(&tostart,&nclassic,&nlongrun,workdir.s,&gasv,info,FORCE,CONF) ;
+    start_write(&tostart,&nclassic,&nlongrun,workdir.s,&gasv,info) ;
 
     if (nclassic)
     {
@@ -353,7 +409,7 @@ int ssexec_enable(int argc, char const *const *argv,char const *const *envp,ssex
     stralloc_free(&workdir) ;
     stralloc_free(&sasrc) ;
 
-    for (; pos < tostart.len; pos += strlen(tostart.s + pos) + 1)
+    for (pos = 0 ; pos < tostart.len; pos += strlen(tostart.s + pos) + 1)
         log_info("Enabled successfully: ", tostart.s + pos) ;
 
     if (start && tostart.len)