diff --git a/libs/middletier/SqliteDatabase.cpp b/libs/middletier/SqliteDatabase.cpp
index d47ead86a1d19199876172d968da3b040a1b2e0e..116941bdfb853710eacb7aa5a878aab98fbe5f83 100644
--- a/libs/middletier/SqliteDatabase.cpp
+++ b/libs/middletier/SqliteDatabase.cpp
@@ -339,6 +339,7 @@ void cta::SqliteDatabase::insertArchivalJob(const SecurityIdentity &requester, c
       std::ostringstream message;
       message << "insertArchivalJob() - SQLite error: " << zErrMsg;
       sqlite3_free(zErrMsg);
+      std::cout << message.str() << std::endl;
       throw(Exception(message.str()));
   }
 }
@@ -959,7 +960,7 @@ std::list<cta::ArchiveRoute>  cta::SqliteDatabase::selectAllArchiveRoutes(const
 cta::ArchiveRoute cta::SqliteDatabase::getArchiveRouteOfStorageClass(const SecurityIdentity &requester, const std::string &storageClassName, const  uint16_t copyNb) {
   char *zErrMsg = 0;
   std::ostringstream query;
-  query << "SELECT TAPEPOOL_NAME FROM ARCHIVEROUTE WHERE STORAGECLASS_NAME='"<< storageClassName <<"' AND COPYNB="<< (int)copyNb <<";";
+  query << "SELECT * FROM ARCHIVEROUTE WHERE STORAGECLASS_NAME='"<< storageClassName <<"' AND COPYNB="<< (int)copyNb <<";";
   sqlite3_stmt *statement;
   int rc = sqlite3_prepare(m_dbHandle, query.str().c_str(), -1, &statement, 0 );
   if(rc!=SQLITE_OK){    
@@ -980,12 +981,12 @@ cta::ArchiveRoute cta::SqliteDatabase::getArchiveRouteOfStorageClass(const Secur
             std::string((char *)sqlite3_column_text(statement,6))
       );
   }
-  else if(res==SQLITE_DONE) {    
+  else if(res==SQLITE_DONE) {
     std::ostringstream message;
     message << "getArchiveRouteOfStorageClass() - No archive route found for storage class: " << storageClassName << " and copynb: "<< (int)copyNb;
     throw(Exception(message.str()));
   }
-  else {    
+  else {
     std::ostringstream message;
     message << "getArchiveRouteOfStorageClass() - SQLite error: " << zErrMsg;
     sqlite3_free(zErrMsg);
@@ -1156,6 +1157,49 @@ cta::TapePool cta::SqliteDatabase::getTapePoolByName(const SecurityIdentity &req
   return pool;
 }
 
+//------------------------------------------------------------------------------
+// getStorageClassByName
+//------------------------------------------------------------------------------
+cta::StorageClass cta::SqliteDatabase::getStorageClassByName(const SecurityIdentity &requester, const std::string &name) {
+  char *zErrMsg = 0;
+  std::ostringstream query;
+  cta::StorageClass stgClass;
+  query << "SELECT * FROM STORAGECLASS WHERE NAME='" << name << "';";
+  sqlite3_stmt *statement;
+  int rc = sqlite3_prepare(m_dbHandle, query.str().c_str(), -1, &statement, 0 );
+  if(rc!=SQLITE_OK){    
+      std::ostringstream message;
+      message << "getStorageClassByName() - SQLite error: " << zErrMsg;
+      sqlite3_free(zErrMsg);
+      throw(Exception(message.str()));
+  }
+  int res = sqlite3_step(statement);
+  if(res==SQLITE_ROW) {
+    stgClass = cta::StorageClass(
+            std::string((char *)sqlite3_column_text(statement,0)),
+            sqlite3_column_int(statement,1),
+            cta::UserIdentity(sqlite3_column_int(statement,2),sqlite3_column_int(statement,3)),
+            time_t(sqlite3_column_int(statement,4)),
+            std::string((char *)sqlite3_column_text(statement,5))
+      );
+  }
+  else if(res==SQLITE_DONE) {    
+    std::ostringstream message;
+    message << "getStorageClassByName() - No storage class found with name: " << name;
+    sqlite3_finalize(statement);
+    throw(Exception(message.str()));
+  }
+  else {    
+    std::ostringstream message;
+    message << "getStorageClassByName() - SQLite error: " << zErrMsg;
+    sqlite3_free(zErrMsg);
+    sqlite3_finalize(statement);
+    throw(Exception(message.str()));
+  }
+  sqlite3_finalize(statement);
+  return stgClass;
+}
+
 //------------------------------------------------------------------------------
 // getTapeByVid
 //------------------------------------------------------------------------------
diff --git a/libs/middletier/SqliteDatabase.hpp b/libs/middletier/SqliteDatabase.hpp
index 830e2f0dc4840a3de95f1f9e750d11630239435f..cc4ecf243ce46d8124e4ccc642b247c0acb5ea8c 100644
--- a/libs/middletier/SqliteDatabase.hpp
+++ b/libs/middletier/SqliteDatabase.hpp
@@ -93,7 +93,9 @@ public:
   
   cta::TapePool getTapePoolByName(const SecurityIdentity &requester, const std::string &name);
   
-  cta::Tape getTapeByVid(const SecurityIdentity &requester, const std::string &vid);  
+  cta::Tape getTapeByVid(const SecurityIdentity &requester, const std::string &vid);
+  
+  cta::StorageClass getStorageClassByName(const SecurityIdentity &requester, const std::string &name);
 
 private:
   
diff --git a/libs/middletier/SqliteMiddleTierUser.cpp b/libs/middletier/SqliteMiddleTierUser.cpp
index 4920592c89a9fe9737949dd5cc39d5efc3169ad7..bb3d186d15db787cb8821461d2d906faed00d08d 100644
--- a/libs/middletier/SqliteMiddleTierUser.cpp
+++ b/libs/middletier/SqliteMiddleTierUser.cpp
@@ -102,18 +102,39 @@ void cta::SqliteMiddleTierUser::archiveToDirectory(
   if(0 == srcUrls.size()) {
     throw Exception("At least one source file should be provided");
   }
-
   const std::list<std::string> dstFileNames = Utils::getEnclosedNames(srcUrls);
 
   for(std::list<std::string>::const_iterator itor = dstFileNames.begin(); itor != dstFileNames.end(); itor++) {
     const std::string &dstFileName = *itor;
-    m_vfs.createFile(requester, dstDir+dstFileName, 0666);
+    std::string dstPathname;
+    if(dstDir.at(dstDir.length()-1) == '/') {
+      dstPathname = dstDir+dstFileName;
+    }
+    else {
+      dstPathname = dstDir+"/"+dstFileName;
+    }
+    m_vfs.createFile(requester, dstPathname, 0666);
+  }
+  std::string storageClassName = m_vfs.getDirectoryStorageClass(requester, dstDir);
+  cta::StorageClass storageClass = m_sqlite_db.getStorageClassByName(requester, storageClassName);
+  if(storageClass.getNbCopies()==0) {       
+    std::ostringstream message;
+    message << "archiveToDirectory() - Storage class " << storageClassName << " has 0 copies";
+    throw(Exception(message.str()));
   }
-  std::string storageClass = m_vfs.getDirectoryStorageClass(requester, dstDir);
-  cta::ArchiveRoute route = m_sqlite_db.getArchiveRouteOfStorageClass(requester, storageClass, 1);
-  for(std::list<std::string>::const_iterator itor = srcUrls.begin(); itor != srcUrls.end(); itor++) {
-    const std::string &srcFileName = *itor;
-    m_sqlite_db.insertArchivalJob(requester, route.getTapePoolName(), srcFileName, dstDir);
+  for(int i=1; i<=storageClass.getNbCopies(); i++) {
+    cta::ArchiveRoute route = m_sqlite_db.getArchiveRouteOfStorageClass(requester, storageClassName, i);
+    for(std::list<std::string>::const_iterator itor = srcUrls.begin(); itor != srcUrls.end(); itor++) {
+      const std::string &srcFileName = *itor;
+      std::string dstPathname;
+      if(dstDir.at(dstDir.length()-1) == '/') {
+        dstPathname = dstDir+srcFileName;
+      }
+      else {
+        dstPathname = dstDir+"/"+srcFileName;
+      }
+      m_sqlite_db.insertArchivalJob(requester, route.getTapePoolName(), srcFileName, dstPathname);
+    }
   }
 }
 
@@ -132,9 +153,17 @@ void cta::SqliteMiddleTierUser::archiveToFile(
   const std::string &srcFileName = srcUrls.front();
   
   m_vfs.createFile(requester, dstFile, 0666);
-  std::string storageClass = m_vfs.getDirectoryStorageClass(requester, cta::Utils::getEnclosingDirPath(dstFile));
-  cta::ArchiveRoute route = m_sqlite_db.getArchiveRouteOfStorageClass(requester, storageClass, 1);
-  m_sqlite_db.insertArchivalJob(requester, route.getTapePoolName(), srcFileName, dstFile);
+  std::string storageClassName = m_vfs.getDirectoryStorageClass(requester, cta::Utils::getEnclosingDirPath(dstFile));
+  cta::StorageClass storageClass = m_sqlite_db.getStorageClassByName(requester, storageClassName);
+  if(storageClass.getNbCopies()==0) {       
+    std::ostringstream message;
+    message << "archiveToFile() - Storage class " << storageClassName << " has 0 copies";
+    throw(Exception(message.str()));
+  }
+  for(int i=1; i<=storageClass.getNbCopies(); i++) {
+    cta::ArchiveRoute route = m_sqlite_db.getArchiveRouteOfStorageClass(requester, storageClassName, i);
+    m_sqlite_db.insertArchivalJob(requester, route.getTapePoolName(), srcFileName, dstFile);
+  }
 }
 
 //------------------------------------------------------------------------------
diff --git a/libs/middletier/Vfs.cpp b/libs/middletier/Vfs.cpp
index 2211c757d87859d523031b066b8ff26a484c69e5..0c5acd92d598f05811104f87ed095646ef4c1b28 100644
--- a/libs/middletier/Vfs.cpp
+++ b/libs/middletier/Vfs.cpp
@@ -92,7 +92,13 @@ void cta::Vfs::checkStorageClassIsNotInUse(const SecurityIdentity &requester, co
    
   while((entry = readdir(dp))) {
     if(entry->d_type == DT_DIR && strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
-      const std::string dirEntryPathname = dirPath+(entry->d_name);
+      std::string dirEntryPathname;
+      if(dirPath.at(dirPath.length()-1) == '/') {
+        dirEntryPathname = dirPath+(entry->d_name);
+      }
+      else {
+        dirEntryPathname = dirPath+"/"+(entry->d_name);
+      }
       checkStorageClassIsNotInUse(requester, storageClass, dirEntryPathname);
     }
   }
@@ -249,7 +255,12 @@ void cta::Vfs::deleteFile(const SecurityIdentity &requester, const std::string &
 //------------------------------------------------------------------------------
 // deleteDirectory
 //------------------------------------------------------------------------------
-void cta::Vfs::deleteDirectory(const SecurityIdentity &requester, const std::string &pathname) {  
+void cta::Vfs::deleteDirectory(const SecurityIdentity &requester, const std::string &pathname) {
+  if(pathname=="/") {    
+    std::ostringstream message;
+    message << "deleteDirectory() - Cannot delete root directory";
+    throw(Exception(message.str()));
+  }
   cta::Utils::checkAbsolutePathSyntax(pathname);
   
   int rc = rmdir((m_fsDir+pathname).c_str());
@@ -317,7 +328,13 @@ std::list<cta::DirectoryEntry> cta::Vfs::getDirectoryEntries(const SecurityIdent
   
   while((entry = readdir(dp))) {
     if(strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
-      const std::string dirEntryPathname = dirPath+(entry->d_name);
+      std::string dirEntryPathname;
+      if(dirPath.at(dirPath.length()-1) == '/') {
+        dirEntryPathname = dirPath+(entry->d_name);
+      }
+      else {
+        dirEntryPathname = dirPath+"/"+(entry->d_name);
+      }
       entries.push_back(statDirectoryEntry(requester, dirEntryPathname));
     }
   }
@@ -331,8 +348,9 @@ std::list<cta::DirectoryEntry> cta::Vfs::getDirectoryEntries(const SecurityIdent
 //------------------------------------------------------------------------------
 cta::DirectoryIterator cta::Vfs::getDirectoryContents(const SecurityIdentity &requester, const std::string &dirPath) {
   cta::Utils::checkAbsolutePathSyntax(dirPath);
-  checkDirectoryExists(dirPath);
-  return cta::DirectoryIterator(getDirectoryEntries(requester, dirPath));
+  checkDirectoryExists(m_fsDir+dirPath);
+  cta::DirectoryIterator it = getDirectoryEntries(requester, dirPath);
+  return it;
 }
 
 //------------------------------------------------------------------------------