}
    }
 #endif
-   Dmsg3(200, "Create %s Replace=%c FT=%d\n", attr->ofname, (char)replace, attr->type);
+
+   Dmsg2(400, "Replace=%c %d\n", (char)replace, replace);
    if (lstat(attr->ofname, &mstatp) == 0) {
       exists = true;
-      /*
-       * For directories we do not apply the replace options, because
-       * we must always create directories that do not exist, and thus
-       * when the directory end record comes, the directory exists.  So
-       * we always apply the FT_DIREND record for directories.
-       */
-      if (attr->type != FT_DIREND) {
-         switch (replace) {
-         case REPLACE_IFNEWER:
-            if (attr->statp.st_mtime <= mstatp.st_mtime) {
-               Qmsg(jcr, M_SKIPPED, 0, _("File skipped. Not newer: %s\n"), attr->ofname);
-               return CF_SKIP;
-            }
-            break;
-
-         case REPLACE_IFOLDER:
-            if (attr->statp.st_mtime >= mstatp.st_mtime) {
-               Qmsg(jcr, M_SKIPPED, 0, _("File skipped. Not older: %s\n"), attr->ofname);
-               return CF_SKIP;
-            }
-            break;
+      switch (replace) {
+      case REPLACE_IFNEWER:
+         if (attr->statp.st_mtime <= mstatp.st_mtime) {
+            Qmsg(jcr, M_SKIPPED, 0, _("File skipped. Not newer: %s\n"), attr->ofname);
+            return CF_SKIP;
+         }
+         break;
 
-         case REPLACE_NEVER:
-            Qmsg(jcr, M_SKIPPED, 0, _("File skipped. Already exists: %s\n"), attr->ofname);
+      case REPLACE_IFOLDER:
+         if (attr->statp.st_mtime >= mstatp.st_mtime) {
+            Qmsg(jcr, M_SKIPPED, 0, _("File skipped. Not older: %s\n"), attr->ofname);
             return CF_SKIP;
+         }
+         break;
 
-         case REPLACE_ALWAYS:
+      case REPLACE_NEVER:
+         /* Set attributes if we created this directory */
+         if (attr->type == FT_DIREND && path_list_lookup(jcr, attr->ofname)) {
             break;
          }
+         Qmsg(jcr, M_SKIPPED, 0, _("File skipped. Already exists: %s\n"), attr->ofname);
+         return CF_SKIP;
+
+      case REPLACE_ALWAYS:
+         break;
       }
    }
    switch (attr->type) {
          attr->ofname[pnl] = 0;                 /* terminate path */
 
          if (!path_already_seen(jcr, attr->ofname, pnl)) {
+            Dmsg1(400, "Make path %s\n", attr->ofname);
             /*
              * If we need to make the directory, ensure that it is with
              * execute bit set (i.e. parent_mode), and preserve what already
              * exists. Normally, this should do nothing.
              */
-            Dmsg1(400, "makepath %s\n", attr->ofname);
             if (!makepath(attr, attr->ofname, parent_mode, parent_mode, uid, gid, 1)) {
                Dmsg1(10, "Could not make path. %s\n", attr->ofname);
                attr->ofname[pnl] = savechr;     /* restore full name */
 
             ff->strip_path = fo->strip_path;
             ff->fstypes = fo->fstype;
             ff->drivetypes = fo->drivetype;
+            ff->plugin = fo->plugin; /* TODO: generate a plugin event ? */
+            ff->opt_plugin = (ff->plugin != NULL)? true : false;
             bstrncat(ff->VerifyOpts, fo->VerifyOpts, sizeof(ff->VerifyOpts));
             if (fo->AccurateOpts[0]) {
                bstrncpy(ff->AccurateOpts, fo->AccurateOpts, sizeof(ff->AccurateOpts));
 
    char VerifyOpts[MAX_FOPTS];        /* verify options */
    char AccurateOpts[MAX_FOPTS];      /* accurate mode options */
    char BaseJobOpts[MAX_FOPTS];       /* basejob mode options */
+   char *plugin;                      /* Plugin that handle this section */
    alist regex;                       /* regex string(s) */
    alist regexdir;                    /* regex string(s) for directories */
    alist regexfile;                   /* regex string(s) for files */
    char *link;                        /* link if file linked */
    char *object_name;                 /* Object name */
    char *object;                      /* restore object */
+   char *plugin;                      /* Current Options{Plugin=} name */
    POOLMEM *sys_fname;                /* system filename */
    POOLMEM *fname_save;               /* save when stripping path */
    POOLMEM *link_save;                /* save when stripping path */
    int Compress_level;                /* compression level */
    int strip_path;                    /* strip path count */
    bool cmd_plugin;                   /* set if we have a command plugin */
+   bool opt_plugin;                   /* set if we have an option plugin */
    alist fstypes;                     /* allowed file system types */
    alist drivetypes;                  /* allowed drive types */
 
 
 #include "bacula.h"
 #include "jcr.h"
 
+#define dbglvl 50
+
+typedef struct PrivateCurDir {
+   hlink link;
+   char fname[1];
+} CurDir;
+
+/* Initialize the path hash table */
+static bool path_list_init(JCR *jcr)
+{
+   CurDir *elt = NULL;
+   jcr->path_list = (htable *)malloc(sizeof(htable));
+
+   /* Hard to know in advance how many directories will
+    * be stored in this hash
+    */
+   jcr->path_list->init(elt, &elt->link, 10000);
+   return true;
+}
+
+/* Add a path to the hash when we create a directory
+ * with the replace=NEVER option
+ */
+bool path_list_add(JCR *jcr, uint32_t len, char *fname)
+{
+   bool ret = true;
+   CurDir *item;
+
+   if (!jcr->path_list) {
+      path_list_init(jcr);
+   }
+
+   /* we store CurDir, fname in the same chunk */
+   item = (CurDir *)jcr->path_list->hash_malloc(sizeof(CurDir)+len+1);
+   
+   memset(item, 0, sizeof(CurDir));
+   memcpy(item->fname, fname, len+1);
+
+   jcr->path_list->insert(item->fname, item); 
+
+   Dmsg1(dbglvl, "add fname=<%s>\n", fname);
+   return ret;
+}
+
+void free_path_list(JCR *jcr)
+{
+   if (jcr->path_list) {
+      jcr->path_list->destroy();
+      free(jcr->path_list);
+      jcr->path_list = NULL;
+   }
+}
+
+bool path_list_lookup(JCR *jcr, char *fname)
+{
+   bool found=false;
+   char bkp;
+
+   if (!jcr->path_list) {
+      return false;
+   }
+
+   /* Strip trailing / */
+   int len = strlen(fname);
+   if (len == 0) {
+      return false;
+   }
+   len--;
+   bkp = fname[len];
+   if (fname[len] == '/') {       /* strip any trailing slash */
+      fname[len] = 0;
+   }
+
+   CurDir *temp = (CurDir *)jcr->path_list->lookup(fname);
+   if (temp) {
+      found=true;
+   }
+
+   Dmsg2(dbglvl, "lookup <%s> %s\n", fname, found?"ok":"not ok");
+
+   fname[len] = bkp;            /* restore last / */
+   return found;
+}
+
 static bool makedir(JCR *jcr, char *path, mode_t mode, int *created)
 {
    struct stat statp;
       }
       return true;                 /* directory exists */
    }
+
+   if (jcr->keep_path_list) {
+      /* When replace=NEVER, we keep track of all directories newly created */
+      path_list_add(jcr, strlen(path), path);
+   }
+
    *created = true;
    return true;
 }
       if (!makedir(jcr, path, tmode, &created)) {
          goto bail_out;
       }
-      Dmsg2(400, "makedir: created=%d %s\n", created, path);
       if (ndir < max_dirs) {
          new_dir[ndir++] = created;
       }
    if (!makedir(jcr, path, tmode, &created)) {
       goto bail_out;
    }
-   Dmsg2(400, "makedir: created=%d %s\n", created, path);
    if (ndir < max_dirs) {
       new_dir[ndir++] = created;
    }
 
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
+   Copyright (C) 2000-2011 Free Software Foundation Europe e.V.
 
    The main author of Bacula is Kern Sibbald, with contributions from
    many others, a complete list can be found in the file AUTHORS.
 /*
  * Prototypes for finlib directory of Bacula
  *
- *   Version $Id$
  */
 
 /* from attribs.c */
 bool makepath(ATTR *attr, const char *path, mode_t mode,
            mode_t parent_mode, uid_t owner, gid_t group,
            int keep_dir_modes);
+void free_path_list(JCR *jcr);
+bool path_list_lookup(JCR *jcr, char *fname);
+bool path_list_add(JCR *jcr, uint32_t len, char *fname);
+
 
 /* from fstype.c */
 bool fstype(const char *fname, char *fs, int fslen);