diff --git a/libs/middletier/SqliteMiddleTierAdminTest.cpp b/libs/middletier/SqliteMiddleTierAdminTest.cpp
index d2f204a152d5bc0845f82751234308d3e88df803..91d58ca3ebdc9cc4662b84c2c57eeff6c964ad13 100644
--- a/libs/middletier/SqliteMiddleTierAdminTest.cpp
+++ b/libs/middletier/SqliteMiddleTierAdminTest.cpp
@@ -185,8 +185,8 @@ TEST_F(cta_client_SqliteMiddleTierAdminTest,
     ASSERT_EQ(nbCopies, storageClass.getNbCopies());
   }
 
-  MockDatabase db;
-  SqliteMiddleTierUser userApi(db,sqlitedb);
+  Vfs vfs;
+  SqliteMiddleTierUser userApi(vfs,sqlitedb);
   ASSERT_NO_THROW(userApi.setDirectoryStorageClass(requester, "/",
     storageClassName));
 
diff --git a/libs/middletier/SqliteMiddleTierUser.cpp b/libs/middletier/SqliteMiddleTierUser.cpp
index a01d685ebe27ece07193b89447c124dddc896eac..1b3fae144b5517d3e93a90ee41ab9c280292f62e 100644
--- a/libs/middletier/SqliteMiddleTierUser.cpp
+++ b/libs/middletier/SqliteMiddleTierUser.cpp
@@ -9,8 +9,8 @@
 //------------------------------------------------------------------------------
 // constructor
 //------------------------------------------------------------------------------
-cta::SqliteMiddleTierUser::SqliteMiddleTierUser(MockDatabase &db, SqliteDatabase &sqlite_db):
-  m_db(db), m_sqlite_db(sqlite_db) {
+cta::SqliteMiddleTierUser::SqliteMiddleTierUser(Vfs &vfs, SqliteDatabase &sqlite_db):
+  m_sqlite_db(sqlite_db), m_vfs(vfs) {
 }
 
 //------------------------------------------------------------------------------
@@ -24,77 +24,7 @@ cta::SqliteMiddleTierUser::~SqliteMiddleTierUser() throw() {
 //------------------------------------------------------------------------------
 void cta::SqliteMiddleTierUser::createDirectory(const SecurityIdentity &requester,
   const std::string &dirPath) {
-  Utils::checkAbsolutePathSyntax(dirPath);
-
-  if(dirPath == "/") {
-    throw Exception("Root directory already exists");
-  }
-
-  const std::string enclosingPath = Utils::getEnclosingDirPath(dirPath);
-
-  FileSystemNode &enclosingNode = getFileSystemNode(enclosingPath);
-  if(DirectoryEntry::ENTRYTYPE_DIRECTORY !=
-    enclosingNode.getFileSystemEntry().getEntry().getType()) {
-    std::ostringstream message;
-    message << enclosingPath << " is not a directory";
-    throw Exception(message.str());
-  }
-
-  const std::string dirName = Utils::getEnclosedName(dirPath);
-
-  if(enclosingNode.childExists(dirName)) {
-    throw Exception("A file or directory already exists with the same name");
-  }
-
-  const std::string inheritedStorageClassName =
-    enclosingNode.getFileSystemEntry().getEntry().getStorageClassName();
-  DirectoryEntry dirEntry(DirectoryEntry::ENTRYTYPE_DIRECTORY, dirName,
-    inheritedStorageClassName);
-  enclosingNode.addChild(new FileSystemNode(m_db.storageClasses, dirEntry));
-}
-
-//------------------------------------------------------------------------------
-// getFileSystemNode
-//------------------------------------------------------------------------------
-cta::FileSystemNode &cta::SqliteMiddleTierUser::getFileSystemNode(
-  const std::string &path) {
-  FileSystemNode *node = &m_db.fileSystemRoot;
-
-  if(path == "/") {
-    return *node;
-  }
-
-  const std::string trimmedDirPath = Utils::trimSlashes(path);
-  std::vector<std::string> pathComponents;
-  Utils::splitString(trimmedDirPath, '/', pathComponents);
-
-  for(std::vector<std::string>::const_iterator itor = pathComponents.begin();
-    itor != pathComponents.end(); itor++) {
-    node = &node->getChild(*itor);
-  }
-  return *node;
-}
-
-//------------------------------------------------------------------------------
-// getFileSystemNode
-//------------------------------------------------------------------------------
-const cta::FileSystemNode &cta::SqliteMiddleTierUser::getFileSystemNode(
-  const std::string &path) const {
-  const FileSystemNode *node = &m_db.fileSystemRoot;
-
-  if(path == "/") {
-    return *node;
-  }
-
-  const std::string trimmedDirPath = Utils::trimSlashes(path);
-  std::vector<std::string> pathComponents;
-  Utils::splitString(trimmedDirPath, '/', pathComponents);
-
-  for(std::vector<std::string>::const_iterator itor = pathComponents.begin();
-    itor != pathComponents.end(); itor++) {
-    node = &node->getChild(*itor);
-  }
-  return *node;
+  m_vfs.clearDirectoryStorageClass(requester, dirPath);
 }
 
 //------------------------------------------------------------------------------
@@ -102,27 +32,7 @@ const cta::FileSystemNode &cta::SqliteMiddleTierUser::getFileSystemNode(
 //------------------------------------------------------------------------------
 void cta::SqliteMiddleTierUser::deleteDirectory(const SecurityIdentity &requester,
   const std::string &dirPath) {
-  Utils::checkAbsolutePathSyntax(dirPath);
-
-  if(dirPath == "/") {
-    throw Exception("The root directory can never be deleted");
-  }
-
-  FileSystemNode &dirNode = getFileSystemNode(dirPath);
-
-  if(DirectoryEntry::ENTRYTYPE_DIRECTORY !=
-    dirNode.getFileSystemEntry().getEntry().getType()) {
-    std::ostringstream message;
-    message << "The absolute path " << dirPath << " is not a directory";
-    throw(message.str());
-  }
-
-  if(dirNode.hasAtLeastOneChild()) {
-    throw Exception("Directory is not empty");
-  }
-
-  FileSystemNode &parentNode = dirNode.getParent();
-  parentNode.deleteChild(dirNode.getFileSystemEntry().getEntry().getName());
+  m_vfs.deleteDirectory(requester, dirPath);
 }
 
 //------------------------------------------------------------------------------
@@ -130,22 +40,7 @@ void cta::SqliteMiddleTierUser::deleteDirectory(const SecurityIdentity &requeste
 //------------------------------------------------------------------------------
 cta::DirectoryIterator cta::SqliteMiddleTierUser::getDirectoryContents(
   const SecurityIdentity &requester, const std::string &dirPath) const {
-  Utils::checkAbsolutePathSyntax(dirPath);
-
-  if(dirPath == "/") {
-    return DirectoryIterator(m_db.fileSystemRoot.getDirectoryEntries());
-  }
-
-  const FileSystemNode &dirNode = getFileSystemNode(dirPath);
-
-  if(DirectoryEntry::ENTRYTYPE_DIRECTORY !=
-    dirNode.getFileSystemEntry().getEntry().getType()) {
-    std::ostringstream message;
-    message << "The absolute path " << dirPath << " is not a directory";
-    throw(message.str());
-  }
-
-  return DirectoryIterator(dirNode.getDirectoryEntries());
+  return m_vfs.getDirectoryContents(requester, dirPath);
 }
 
 //------------------------------------------------------------------------------
@@ -154,10 +49,7 @@ cta::DirectoryIterator cta::SqliteMiddleTierUser::getDirectoryContents(
 cta::DirectoryEntry cta::SqliteMiddleTierUser::stat(
   const SecurityIdentity &requester,
   const std::string path) const {
-  Utils::checkAbsolutePathSyntax(path);
-
-  const FileSystemNode &node = getFileSystemNode(path);
-  return node.getFileSystemEntry().getEntry();
+  return m_vfs.statDirectoryEntry(requester, path);
 }
 
 //------------------------------------------------------------------------------
@@ -167,7 +59,7 @@ void cta::SqliteMiddleTierUser::setDirectoryStorageClass(
   const SecurityIdentity &requester,
   const std::string &dirPath,
   const std::string &storageClassName) {
-  m_sqlite_db.setDirectoryStorageClass(requester, dirPath, storageClassName);
+  m_vfs.setDirectoryStorageClass(requester, dirPath, storageClassName);
 }
 
 //------------------------------------------------------------------------------
@@ -176,7 +68,7 @@ void cta::SqliteMiddleTierUser::setDirectoryStorageClass(
 void cta::SqliteMiddleTierUser::clearDirectoryStorageClass(
   const SecurityIdentity &requester,
   const std::string &dirPath) {
-  m_sqlite_db.clearDirectoryStorageClass(requester, dirPath);
+  m_vfs.clearDirectoryStorageClass(requester, dirPath);
 }
   
 //------------------------------------------------------------------------------
@@ -185,7 +77,7 @@ void cta::SqliteMiddleTierUser::clearDirectoryStorageClass(
 std::string cta::SqliteMiddleTierUser::getDirectoryStorageClass(
   const SecurityIdentity &requester,
   const std::string &dirPath) const {
-  return m_sqlite_db.getDirectoryStorageClass(requester, dirPath);
+  return m_vfs.getDirectoryStorageClass(requester, dirPath);
 }
 
 //------------------------------------------------------------------------------
@@ -193,30 +85,13 @@ std::string cta::SqliteMiddleTierUser::getDirectoryStorageClass(
 //------------------------------------------------------------------------------
 void cta::SqliteMiddleTierUser::archive(const SecurityIdentity &requester,
   const std::list<std::string> &srcUrls, const std::string &dstPath) {
-  Utils::checkAbsolutePathSyntax(dstPath);
-  if(isAnExistingDirectory(dstPath)) {
+  if(m_vfs.isExistingDirectory(requester, dstPath)) {
     return archiveToDirectory(requester, srcUrls, dstPath);
   } else {
     return archiveToFile(requester, srcUrls, dstPath);
   }
 }
 
-//------------------------------------------------------------------------------
-// isAnExistingDirectory
-//------------------------------------------------------------------------------
-bool cta::SqliteMiddleTierUser::isAnExistingDirectory(const std::string &path)
-  const throw() {
-  try {
-    const FileSystemNode &node = getFileSystemNode(path);
-    const DirectoryEntry &entry = node.getFileSystemEntry().getEntry();
-    if(DirectoryEntry::ENTRYTYPE_DIRECTORY == entry.getType()) {
-      return true;
-    }
-  } catch(...) {
-  }
-  return false;
-}
-
 //------------------------------------------------------------------------------
 // archiveToDirectory
 //------------------------------------------------------------------------------
@@ -228,38 +103,16 @@ void cta::SqliteMiddleTierUser::archiveToDirectory(
     throw Exception("At least one source file should be provided");
   }
 
-  FileSystemNode &dstDirNode = getFileSystemNode(dstDir);
-  checkUserIsAuthorisedToArchive(requester, dstDirNode);
-
-  const std::string inheritedStorageClassName = dstDirNode.getFileSystemEntry().
-    getEntry().getStorageClassName();
   const std::list<std::string> dstFileNames = Utils::getEnclosedNames(srcUrls);
-  checkDirNodeDoesNotContainFiles(dstDir, dstDirNode, dstFileNames);
 
-  for(std::list<std::string>::const_iterator itor = dstFileNames.begin();
-    itor != dstFileNames.end(); itor++) {
+  for(std::list<std::string>::const_iterator itor = dstFileNames.begin(); itor != dstFileNames.end(); itor++) {
     const std::string &dstFileName = *itor;
-    DirectoryEntry dirEntry(DirectoryEntry::ENTRYTYPE_FILE, dstFileName,
-      inheritedStorageClassName);
-    dstDirNode.addChild(new FileSystemNode(m_db.storageClasses, dirEntry));
+    m_vfs.createFile(requester, dstDir+dstFileName, 0666);
   }
-}
-
-//------------------------------------------------------------------------------
-// checkDirNodeDoesNotContainFiles
-//------------------------------------------------------------------------------
-void cta::SqliteMiddleTierUser::checkDirNodeDoesNotContainFiles(
-  const std::string &dirPath,
-  const FileSystemNode &dirNode,
-  const std::list<std::string> &fileNames) {
-  for(std::list<std::string>::const_iterator itor = fileNames.begin();
-    itor != fileNames.end(); itor++) {
-    const std::string &fileName = *itor;
-    if(dirNode.childExists(fileName)) {
-      std::ostringstream message;
-      message << dirPath << fileName << " already exists";
-      throw(Exception(message.str()));
-    }
+  
+  for(std::list<std::string>::const_iterator itor = srcUrls.begin(); itor != srcUrls.end(); itor++) {
+    const std::string &srcFileName = *itor;
+    m_sqlite_db.insertArchivalJob(requester, srcFileName, dstDir);
   }
 }
 
@@ -274,32 +127,11 @@ void cta::SqliteMiddleTierUser::archiveToFile(
     throw Exception("One and only one source file must be provided when "
       "archiving to a single destination file");
   }
-
-  const std::string enclosingDir = Utils::getEnclosingDirPath(dstFile);
-  const std::string enclosedName = Utils::getEnclosedName(dstFile);
-  FileSystemNode &enclosingNode = getFileSystemNode(enclosingDir);
-  checkUserIsAuthorisedToArchive(requester, enclosingNode);
-  if(enclosingNode.childExists(enclosedName)) {
-    std::ostringstream message;
-    message << "A file or directory with the name " << enclosedName <<
-      " already exists";
-    throw Exception(message.str());
-  }
-
-  const std::string inheritedStorageClassName =
-    enclosingNode.getFileSystemEntry().getEntry().getStorageClassName();
-  DirectoryEntry dirEntry(DirectoryEntry::ENTRYTYPE_FILE, enclosedName,
-    inheritedStorageClassName);
-  enclosingNode.addChild(new FileSystemNode(m_db.storageClasses, dirEntry));
-}
-
-//------------------------------------------------------------------------------
-// checkUserIsAuthorisedToArchive
-//------------------------------------------------------------------------------
-void cta::SqliteMiddleTierUser::checkUserIsAuthorisedToArchive(
-  const SecurityIdentity &user,
-  const FileSystemNode &dstDir) {
-  // TO BE DONE
+  
+  const std::string &srcFileName = srcUrls.front();
+  
+  m_vfs.createFile(requester, dstFile, 0666);
+  m_sqlite_db.insertArchivalJob(requester, srcFileName, dstFile);
 }
 
 //------------------------------------------------------------------------------
@@ -308,8 +140,7 @@ void cta::SqliteMiddleTierUser::checkUserIsAuthorisedToArchive(
 std::map<cta::TapePool, std::list<cta::ArchivalJob> >
   cta::SqliteMiddleTierUser::getArchivalJobs(
   const SecurityIdentity &requester) const {
-  std::map<cta::TapePool, std::list<cta::ArchivalJob> > jobs;
-  return jobs;
+  throw(Exception("Not Implemented!"));
 }
 
 //------------------------------------------------------------------------------
@@ -318,7 +149,8 @@ std::map<cta::TapePool, std::list<cta::ArchivalJob> >
 std::list<cta::ArchivalJob> cta::SqliteMiddleTierUser::getArchivalJobs(
   const SecurityIdentity &requester,
   const std::string &tapePoolName) const {
-  return m_db.archivalJobs.getArchivalJobs(requester, tapePoolName);
+  //TODO
+  return m_sqlite_db.selectAllArchivalJobs(requester);
 }
 
 //------------------------------------------------------------------------------
@@ -327,7 +159,7 @@ std::list<cta::ArchivalJob> cta::SqliteMiddleTierUser::getArchivalJobs(
 void cta::SqliteMiddleTierUser::deleteArchivalJob(
   const SecurityIdentity &requester,
   const std::string &dstPath) {
-  m_db.archivalJobs.deleteArchivalJob(requester, dstPath);
+  m_sqlite_db.deleteArchivalJob(requester, dstPath);
 }
 
 //------------------------------------------------------------------------------
@@ -337,6 +169,7 @@ void cta::SqliteMiddleTierUser::retrieve(
   const SecurityIdentity &requester,
   const std::list<std::string> &srcPaths,
   const std::string &dstUrl) {
+  //TODO
 }
 
 //------------------------------------------------------------------------------
@@ -345,7 +178,7 @@ void cta::SqliteMiddleTierUser::retrieve(
 std::map<cta::Tape, std::list<cta::RetrievalJob> >
   cta::SqliteMiddleTierUser::getRetrievalJobs(
   const SecurityIdentity &requester) const {
-  return m_db.retrievalJobs.getRetrievalJobs(requester);
+  throw(Exception("Not Implemented!"));
 }
 
 //------------------------------------------------------------------------------
@@ -354,7 +187,8 @@ std::map<cta::Tape, std::list<cta::RetrievalJob> >
 std::list<cta::RetrievalJob> cta::SqliteMiddleTierUser::getRetrievalJobs(
   const SecurityIdentity &requester,
   const std::string &vid) const {
-  return m_db.retrievalJobs.getRetrievalJobs(requester, vid);
+  //TODO
+  return m_sqlite_db.selectAllRetrievalJobs(requester);
 }
 
 //------------------------------------------------------------------------------
@@ -363,5 +197,5 @@ std::list<cta::RetrievalJob> cta::SqliteMiddleTierUser::getRetrievalJobs(
 void cta::SqliteMiddleTierUser::deleteRetrievalJob(
   const SecurityIdentity &requester,
   const std::string &dstUrl) {
-  m_db.retrievalJobs.deleteRetrievalJob(requester, dstUrl);
+  m_sqlite_db.deleteRetrievalJob(requester, dstUrl);
 }
diff --git a/libs/middletier/SqliteMiddleTierUser.hpp b/libs/middletier/SqliteMiddleTierUser.hpp
index ef02f3b0fc34beb60c596abdf69ba666806c89b4..456280c8d88e0997229daa6af2be653caba3e32b 100644
--- a/libs/middletier/SqliteMiddleTierUser.hpp
+++ b/libs/middletier/SqliteMiddleTierUser.hpp
@@ -6,6 +6,7 @@
 #include "MockDatabase.hpp"
 #include "SqliteDatabase.hpp"
 #include "StorageClass.hpp"
+#include "Vfs.hpp"
 
 namespace cta {
 
@@ -20,7 +21,7 @@ public:
    *
    * @param db The database of the mock middle-tier.
    */
-  SqliteMiddleTierUser(MockDatabase &db, SqliteDatabase &sqlite_db);
+  SqliteMiddleTierUser(Vfs &vfs, SqliteDatabase &sqlite_db);
 
   /**
    * Destructor.
@@ -227,13 +228,10 @@ public:
     const std::string &dstUrl);
 
 private:
-
-  /**
-   * The database of the mock middle-tier.
-   */
-  MockDatabase &m_db;
   
   SqliteDatabase &m_sqlite_db;
+  
+  Vfs &m_vfs;
 
   /**
    * Gets the file system node corresponding to the specified path.
@@ -308,19 +306,6 @@ private:
     const SecurityIdentity &user,
     const FileSystemNode &dstDir);
 
-  /**
-   * Throws an exception if at least one of the the specified file names are
-   * contained within the specified directory.
-   *
-   * @param dirPath The absolute path of the directory.
-   * @param dirNode The file-system node representing the directory.
-   * @param fileNames The file names to be searched for.
-   */
-void checkDirNodeDoesNotContainFiles(
-  const std::string &dirPath,
-  const FileSystemNode &dirNode, 
-  const std::list<std::string> &fileNames);
-
 }; // class SqliteMiddleTierUser
 
 } // namespace cta
diff --git a/libs/middletier/SqliteMiddleTierUserTest.cpp b/libs/middletier/SqliteMiddleTierUserTest.cpp
index 0ac864e68a164b34f6aa9d308379da83505fcb30..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644
--- a/libs/middletier/SqliteMiddleTierUserTest.cpp
+++ b/libs/middletier/SqliteMiddleTierUserTest.cpp
@@ -1,613 +0,0 @@
-#include "MockMiddleTierAdmin.hpp"
-#include "MockMiddleTierUser.hpp"
-
-#include <gtest/gtest.h>
-#include <set>
-
-namespace unitTests {
-
-class cta_client_SqliteMiddleTierUserTest: public ::testing::Test {
-protected:
-
-  virtual void SetUp() {
-  }
-
-  virtual void TearDown() {
-  }
-};
-
-TEST_F(cta_client_SqliteMiddleTierUserTest,
-  getDirectoryContents_root_dir_is_empty) {
-  using namespace cta;
-
-  MockDatabase db;
-  MockMiddleTierUser userApi(db);
-  const SecurityIdentity requester;
-  const std::string dirPath = "/";
-
-  DirectoryIterator itor;
-  ASSERT_NO_THROW(itor = userApi.getDirectoryContents(requester, "/"));
-  ASSERT_FALSE(itor.hasMore());
-}
-
-TEST_F(cta_client_SqliteMiddleTierUserTest, createDirectory_empty_string) {
-  using namespace cta;
-
-  MockDatabase db;
-  MockMiddleTierUser userApi(db);
-  const SecurityIdentity requester;
-  const std::string dirPath = "";
-
-  ASSERT_THROW(userApi.createDirectory(requester, dirPath), std::exception);
-}
-
-TEST_F(cta_client_SqliteMiddleTierUserTest,
-  createDirectory_consecutive_slashes) {
-  using namespace cta;
-
-  MockDatabase db;
-  MockMiddleTierUser userApi(db);
-  const SecurityIdentity requester;
-  const std::string dirPath = "//";
-
-  ASSERT_THROW(userApi.createDirectory(requester, dirPath), std::exception);
-}
-
-TEST_F(cta_client_SqliteMiddleTierUserTest, createDirectory_invalid_chars) {
-  using namespace cta;
-
-  MockDatabase db;
-  MockMiddleTierUser userApi(db);
-  const SecurityIdentity requester;
-  const std::string dirPath = "/grandparent/?parent";
-  
-  ASSERT_THROW(userApi.createDirectory(requester, dirPath), std::exception);
-}
-
-TEST_F(cta_client_SqliteMiddleTierUserTest, createDirectory_top_level) {
-  using namespace cta;
-
-  MockDatabase db;
-  MockMiddleTierUser userApi(db);
-  const SecurityIdentity requester;
-  const std::string dirPath = "/grandparent";
-  
-  ASSERT_NO_THROW(userApi.createDirectory(requester, dirPath));
-
-  DirectoryIterator itor;
-
-  ASSERT_NO_THROW(itor = userApi.getDirectoryContents(requester, "/"));
-
-  ASSERT_TRUE(itor.hasMore());
-
-  DirectoryEntry entry;
-
-  ASSERT_NO_THROW(entry = itor.next());
-
-  ASSERT_EQ(std::string("grandparent"), entry.getName());
-}
-
-TEST_F(cta_client_SqliteMiddleTierUserTest, createDirectory_second_level) {
-  using namespace cta;
-
-  MockDatabase db;
-  MockMiddleTierUser userApi(db);
-  const SecurityIdentity requester;
-
-  ASSERT_TRUE(userApi.getDirectoryStorageClass(requester, "/").empty());
-
-  {
-    const std::string topLevelDirPath = "/grandparent";
-
-    ASSERT_NO_THROW(userApi.createDirectory(requester, topLevelDirPath));
-  }
-
-  {
-    DirectoryIterator itor;
-
-    ASSERT_NO_THROW(itor = userApi.getDirectoryContents(requester, "/"));
-
-    ASSERT_TRUE(itor.hasMore());
-
-    DirectoryEntry entry;
-
-    ASSERT_NO_THROW(entry = itor.next());
-
-    ASSERT_EQ(std::string("grandparent"), entry.getName());
-  }
-
-  ASSERT_TRUE(userApi.getDirectoryStorageClass(requester, "/grandparent").empty());
-
-  {
-    const std::string secondLevelDirPath = "/grandparent/parent";
-
-    ASSERT_NO_THROW(userApi.createDirectory(requester, secondLevelDirPath));
-  }
-
-  {
-    DirectoryIterator itor;
-
-    ASSERT_NO_THROW(itor = userApi.getDirectoryContents(requester, "/"));
-
-    ASSERT_TRUE(itor.hasMore());
-
-    DirectoryEntry entry;
-
-    ASSERT_NO_THROW(entry = itor.next());
-
-    ASSERT_EQ(std::string("grandparent"), entry.getName());
-  }
-
-  {
-    DirectoryIterator itor;
-
-    ASSERT_NO_THROW(itor = userApi.getDirectoryContents(requester, "/grandparent"));
-
-    ASSERT_TRUE(itor.hasMore());
-
-    DirectoryEntry entry;
-
-    ASSERT_NO_THROW(entry = itor.next());
-
-    ASSERT_EQ(std::string("parent"), entry.getName());
-  }
-
-  ASSERT_TRUE(userApi.getDirectoryStorageClass(requester,
-    "/grandparent/parent").empty());
-}
-
-TEST_F(cta_client_SqliteMiddleTierUserTest,
-  createDirectory_inherit_storage_class) {
-  using namespace cta;
-
-  MockDatabase db;
-  MockMiddleTierUser userApi(db);
-  const SecurityIdentity requester;
-
-  ASSERT_TRUE(userApi.getDirectoryStorageClass(requester, "/").empty());
-
-  {
-    MockMiddleTierAdmin adminApi(db);
-    const std::string name = "TestStorageClass";
-    const uint16_t nbCopies = 2;
-    const std::string comment = "Comment";
-    ASSERT_NO_THROW(adminApi.createStorageClass(requester, name, nbCopies, comment));
-  }
-
-  {
-    const std::string topLevelDirPath = "/grandparent";
-
-    ASSERT_NO_THROW(userApi.createDirectory(requester, topLevelDirPath));
-  }
-
-  {
-    DirectoryIterator itor;
-
-    ASSERT_NO_THROW(itor = userApi.getDirectoryContents(requester, "/"));
-
-    ASSERT_TRUE(itor.hasMore());
-
-    DirectoryEntry entry;
-
-    ASSERT_NO_THROW(entry = itor.next());
-
-    ASSERT_EQ(std::string("grandparent"), entry.getName());
-
-    ASSERT_TRUE(userApi.getDirectoryStorageClass(requester, "/grandparent").empty());
-
-    ASSERT_NO_THROW(userApi.setDirectoryStorageClass(requester, "/grandparent",
-      "TestStorageClass"));
-  }
-
-  ASSERT_EQ(std::string("TestStorageClass"),
-    userApi.getDirectoryStorageClass(requester, "/grandparent"));
-
-  {
-    const std::string secondLevelDirPath = "/grandparent/parent";
-
-    ASSERT_NO_THROW(userApi.createDirectory(requester, secondLevelDirPath));
-  }
-
-  {
-    DirectoryIterator itor;
-
-    ASSERT_NO_THROW(itor = userApi.getDirectoryContents(requester, "/"));
-
-    ASSERT_TRUE(itor.hasMore());
-
-    DirectoryEntry entry;
-
-    ASSERT_NO_THROW(entry = itor.next());
-
-    ASSERT_EQ(std::string("grandparent"), entry.getName());
-  }
-
-  {
-    DirectoryIterator itor;
-
-    ASSERT_NO_THROW(itor = userApi.getDirectoryContents(requester, "/grandparent"));
-
-    ASSERT_TRUE(itor.hasMore());
-
-    DirectoryEntry entry;
-
-    ASSERT_NO_THROW(entry = itor.next());
-
-    ASSERT_EQ(std::string("parent"), entry.getName());
-  }
-
-  ASSERT_EQ(std::string("TestStorageClass"),
-    userApi.getDirectoryStorageClass(requester, "/grandparent/parent"));
-}
-
-TEST_F(cta_client_SqliteMiddleTierUserTest, deleteDirectory_root) {
-  using namespace cta;
-
-  MockDatabase db;
-  MockMiddleTierUser userApi(db);
-  const SecurityIdentity requester;
-  const std::string dirPath = "/";
-
-  ASSERT_THROW(userApi.deleteDirectory(requester, "/"), std::exception);
-}
-
-TEST_F(cta_client_SqliteMiddleTierUserTest, deleteDirectory_existing_top_level) {
-  using namespace cta;
-
-  MockDatabase db;
-  MockMiddleTierUser userApi(db);
-  const SecurityIdentity requester;
-  const std::string dirPath = "/grandparent";
-  
-  ASSERT_NO_THROW(userApi.createDirectory(requester, dirPath));
-
-  {
-    DirectoryIterator itor;
-
-    ASSERT_NO_THROW(itor = userApi.getDirectoryContents(requester, "/"));
-
-    ASSERT_TRUE(itor.hasMore());
-
-    DirectoryEntry entry;
-
-    ASSERT_NO_THROW(entry = itor.next());
-
-    ASSERT_EQ(std::string("grandparent"), entry.getName());
-  }
-
-  ASSERT_NO_THROW(userApi.deleteDirectory(requester, "/grandparent"));
-
-  {
-    DirectoryIterator itor;
-  
-    ASSERT_NO_THROW(itor = userApi.getDirectoryContents(requester, "/"));
-  
-    ASSERT_FALSE(itor.hasMore());
-  }
-}
-
-TEST_F(cta_client_SqliteMiddleTierUserTest,
-  deleteDirectory_non_empty_top_level) {
-  using namespace cta;
-
-  MockDatabase db;
-  MockMiddleTierUser userApi(db);
-  const SecurityIdentity requester;
-
-  {
-    const std::string topLevelDirPath = "/grandparent";
-
-    ASSERT_NO_THROW(userApi.createDirectory(requester, topLevelDirPath));
-
-    DirectoryIterator itor;
-
-    ASSERT_NO_THROW(itor = userApi.getDirectoryContents(requester, "/"));
-
-    ASSERT_TRUE(itor.hasMore());
-
-    DirectoryEntry entry;
-
-    ASSERT_NO_THROW(entry = itor.next());
-
-    ASSERT_EQ(std::string("grandparent"), entry.getName());
-  }
-
-  {
-    const std::string secondLevelDirPath = "/grandparent/parent";
-
-    ASSERT_NO_THROW(userApi.createDirectory(requester, secondLevelDirPath));
-
-    DirectoryIterator itor;
-
-    ASSERT_NO_THROW(itor = userApi.getDirectoryContents(requester, "/"));
-
-    ASSERT_TRUE(itor.hasMore());
-
-    DirectoryEntry entry;
-
-    ASSERT_NO_THROW(entry = itor.next());
-
-    ASSERT_EQ(std::string("grandparent"), entry.getName());
-  }
-
-  {
-    DirectoryIterator itor;
-
-    ASSERT_NO_THROW(itor = userApi.getDirectoryContents(requester, "/grandparent"));
-
-    ASSERT_TRUE(itor.hasMore());
-
-    DirectoryEntry entry;
-
-    ASSERT_NO_THROW(entry = itor.next());
-
-    ASSERT_EQ(std::string("parent"), entry.getName());
-  }
-
-  ASSERT_THROW(userApi.deleteDirectory(requester, "/grandparent"), std::exception);
-
-  {
-    DirectoryIterator itor;
-
-    ASSERT_NO_THROW(itor = userApi.getDirectoryContents(requester, "/grandparent"));
-
-    ASSERT_TRUE(itor.hasMore());
-
-    DirectoryEntry entry;
-
-    ASSERT_NO_THROW(entry = itor.next());
-
-    ASSERT_EQ(std::string("parent"), entry.getName());
-  }
-}
-
-TEST_F(cta_client_SqliteMiddleTierUserTest,
-  deleteDirectory_non_existing_top_level) {
-  using namespace cta;
-  
-  MockDatabase db;
-  MockMiddleTierUser userApi(db);
-  const SecurityIdentity requester;
-
-  ASSERT_THROW(userApi.deleteDirectory(requester, "/grandparent"), std::exception);
-}
-
-TEST_F(cta_client_SqliteMiddleTierUserTest, setDirectoryStorageClass_top_level) {
-  using namespace cta;
-
-  MockDatabase db;
-  MockMiddleTierUser userApi(db);
-  const SecurityIdentity requester;
-  const std::string dirPath = "/grandparent";
-
-  ASSERT_NO_THROW(userApi.createDirectory(requester, dirPath));
-
-  DirectoryIterator itor;
-
-  ASSERT_NO_THROW(itor = userApi.getDirectoryContents(requester, "/"));
-
-  ASSERT_TRUE(itor.hasMore());
-
-  DirectoryEntry entry;
-
-  ASSERT_NO_THROW(entry = itor.next());
-
-  ASSERT_EQ(std::string("grandparent"), entry.getName());
-
-  {
-    std::string name;
-    ASSERT_NO_THROW(name = userApi.getDirectoryStorageClass(requester, dirPath));
-    ASSERT_TRUE(name.empty());
-  }
-
-  const std::string storageClassName = "TestStorageClass";
-  const uint16_t nbCopies = 2;
-    const std::string comment = "Comment";
-  {
-    MockMiddleTierAdmin adminApi(db);
-    ASSERT_NO_THROW(adminApi.createStorageClass(requester, storageClassName,
-      nbCopies, comment));
-  }
-
-  ASSERT_NO_THROW(userApi.setDirectoryStorageClass(requester, dirPath,
-    storageClassName));
-
-  {
-    std::string name;
-    ASSERT_NO_THROW(name = userApi.getDirectoryStorageClass(requester, dirPath));
-    ASSERT_EQ(storageClassName, name);
-  }
-}
-
-TEST_F(cta_client_SqliteMiddleTierUserTest,
-  clearDirectoryStorageClass_top_level) {
-  using namespace cta;
-
-  MockDatabase db;
-  MockMiddleTierUser userApi(db);
-  const SecurityIdentity requester;
-  const std::string dirPath = "/grandparent";
-
-  ASSERT_NO_THROW(userApi.createDirectory(requester, dirPath));
-
-  DirectoryIterator itor;
-
-  ASSERT_NO_THROW(itor = userApi.getDirectoryContents(requester, "/"));
-
-  ASSERT_TRUE(itor.hasMore());
-
-  DirectoryEntry entry;
-
-  ASSERT_NO_THROW(entry = itor.next());
-
-  ASSERT_EQ(std::string("grandparent"), entry.getName());
-
-  {
-    std::string name;
-    ASSERT_NO_THROW(name = userApi.getDirectoryStorageClass(requester, dirPath));
-    ASSERT_TRUE(name.empty());
-  }
-
-  const std::string storageClassName = "TestStorageClass";
-  const uint16_t nbCopies = 2;
-  const std::string comment = "Comment";
-  MockMiddleTierAdmin adminApi(db);
-  ASSERT_NO_THROW(adminApi.createStorageClass(requester, storageClassName,
-    nbCopies, comment));
-
-  ASSERT_NO_THROW(userApi.setDirectoryStorageClass(requester, dirPath,
-    storageClassName));
-
-  {
-    std::string name;
-    ASSERT_NO_THROW(name = userApi.getDirectoryStorageClass(requester, dirPath));
-    ASSERT_EQ(storageClassName, name);
-  }
-
-  ASSERT_THROW(adminApi.deleteStorageClass(requester, storageClassName),
-    std::exception);
-
-  ASSERT_NO_THROW(userApi.clearDirectoryStorageClass(requester, dirPath));
-
-  {
-    std::string name;
-    ASSERT_NO_THROW(name = userApi.getDirectoryStorageClass(requester, dirPath));
-    ASSERT_TRUE(name.empty());
-  }
-
-  ASSERT_NO_THROW(adminApi.deleteStorageClass(requester, storageClassName));
-}
-
-TEST_F(cta_client_SqliteMiddleTierUserTest, archive_to_new_file) {
-  using namespace cta;
-
-  MockDatabase db;
-  MockMiddleTierAdmin adminApi(db);
-  MockMiddleTierUser userApi(db);
-  const SecurityIdentity requester;
-
-  const std::string storageClassName = "TestStorageClass";
-  const uint16_t nbCopies = 1;
-  const std::string storageClassComment = "Storage-class omment";
-  ASSERT_NO_THROW(adminApi.createStorageClass(requester, storageClassName,
-    nbCopies, storageClassComment));
-
-  const std::string dirPath = "/grandparent";
-  ASSERT_NO_THROW(userApi.createDirectory(requester, dirPath));
-  ASSERT_NO_THROW(userApi.setDirectoryStorageClass(requester, dirPath,
-    storageClassName));
-
-  const std::string tapePoolName = "TestTapePool";
-  const uint16_t nbDrives = 1;
-  const uint16_t nbPartialTapes = 1;
-  const std::string tapePoolComment = "Tape-pool comment";
-  ASSERT_NO_THROW(adminApi.createTapePool(requester, tapePoolName, nbDrives,
-    nbPartialTapes, tapePoolComment));
-
-  const uint16_t copyNb = 1;
-  const std::string archiveRouteComment = "Archive-route comment";
-  ASSERT_NO_THROW(adminApi.createArchiveRoute(requester, storageClassName,
-    copyNb, tapePoolName, archiveRouteComment));
-
-  std::list<std::string> srcUrls;
-  srcUrls.push_back("diskUrl");
-  const std::string dstPath  = "/grandparent/parent_file";
-  ASSERT_NO_THROW(userApi.archive(requester, srcUrls, dstPath));
-
-  {
-    DirectoryIterator itor;
-    ASSERT_NO_THROW(itor = userApi.getDirectoryContents(requester, "/"));
-    ASSERT_TRUE(itor.hasMore());
-    DirectoryEntry entry;
-    ASSERT_NO_THROW(entry = itor.next());
-    ASSERT_EQ(std::string("grandparent"), entry.getName());
-    ASSERT_EQ(DirectoryEntry::ENTRYTYPE_DIRECTORY, entry.getType());
-    ASSERT_EQ(storageClassName, entry.getStorageClassName());
-  }
-
-  {
-    DirectoryIterator itor;
-    ASSERT_NO_THROW(itor = userApi.getDirectoryContents(requester, "/grandparent"));
-    ASSERT_TRUE(itor.hasMore());
-    DirectoryEntry entry;
-    ASSERT_NO_THROW(entry = itor.next());
-    ASSERT_EQ(std::string("parent_file"), entry.getName());
-    ASSERT_EQ(DirectoryEntry::ENTRYTYPE_FILE, entry.getType());
-    ASSERT_EQ(storageClassName, entry.getStorageClassName());
-  }
-
-  {
-    DirectoryEntry entry;
-    ASSERT_NO_THROW(entry = userApi.stat(requester, dstPath));
-    ASSERT_EQ(DirectoryEntry::ENTRYTYPE_FILE, entry.getType());
-    ASSERT_EQ(storageClassName, entry.getStorageClassName());
-  }
-}
-
-TEST_F(cta_client_SqliteMiddleTierUserTest, archive_to_directory) {
-  using namespace cta;
-
-  MockDatabase db;
-  MockMiddleTierAdmin adminApi(db);
-  MockMiddleTierUser userApi(db);
-  const SecurityIdentity requester;
-
-  const std::string storageClassName = "TestStorageClass";
-  const uint16_t nbCopies = 1;
-  const std::string storageClassComment = "Storage-class omment";
-  ASSERT_NO_THROW(adminApi.createStorageClass(requester, storageClassName,
-    nbCopies, storageClassComment));
-
-  const std::string dirPath = "/grandparent";
-  ASSERT_NO_THROW(userApi.createDirectory(requester, dirPath));
-  ASSERT_NO_THROW(userApi.setDirectoryStorageClass(requester, dirPath,
-    storageClassName));
-
-  const std::string tapePoolName = "TestTapePool";
-  const uint16_t nbDrives = 1;
-  const uint16_t nbPartialTapes = 1;
-  const std::string tapePoolComment = "Tape-pool comment";
-  ASSERT_NO_THROW(adminApi.createTapePool(requester, tapePoolName, nbDrives,
-    nbPartialTapes, tapePoolComment));
-
-  const uint16_t copyNb = 1;
-  const std::string archiveRouteComment = "Archive-route comment";
-  ASSERT_NO_THROW(adminApi.createArchiveRoute(requester, storageClassName,
-    copyNb, tapePoolName, archiveRouteComment));
-
-  std::list<std::string> srcUrls;
-  srcUrls.push_back("diskUrl1");
-  srcUrls.push_back("diskUrl2");
-  srcUrls.push_back("diskUrl3");
-  srcUrls.push_back("diskUrl4");
-  const std::string dstPath  = "/grandparent";
-  ASSERT_NO_THROW(userApi.archive(requester, srcUrls, dstPath));
-
-  {
-    DirectoryIterator itor;
-    ASSERT_NO_THROW(itor = userApi.getDirectoryContents(requester, "/"));
-    ASSERT_TRUE(itor.hasMore());
-    DirectoryEntry entry;
-    ASSERT_NO_THROW(entry = itor.next());
-    ASSERT_EQ(std::string("grandparent"), entry.getName());
-    ASSERT_EQ(DirectoryEntry::ENTRYTYPE_DIRECTORY, entry.getType());
-    ASSERT_EQ(storageClassName, entry.getStorageClassName());
-  }
-
-  {
-    std::set<std::string> archiveFileNames;
-    DirectoryIterator itor;
-    ASSERT_NO_THROW(itor = userApi.getDirectoryContents(requester, "/grandparent"));
-    while(itor.hasMore()) {
-      const DirectoryEntry entry = itor.next();
-      archiveFileNames.insert(entry.getName());
-    }
-    ASSERT_EQ(4, archiveFileNames.size());
-    ASSERT_TRUE(archiveFileNames.find("diskUrl1") != archiveFileNames.end());
-    ASSERT_TRUE(archiveFileNames.find("diskUrl2") != archiveFileNames.end());
-    ASSERT_TRUE(archiveFileNames.find("diskUrl3") != archiveFileNames.end());
-    ASSERT_TRUE(archiveFileNames.find("diskUrl4") != archiveFileNames.end());
-  }
-}
-
-} // namespace unitTests
diff --git a/libs/middletier/Vfs.cpp b/libs/middletier/Vfs.cpp
index 0e479e6dc36ec58daaefa6c2b1e739a98e5b7b9c..29e731c229b9d886b1f0a3bc20900e53f11cc778 100644
--- a/libs/middletier/Vfs.cpp
+++ b/libs/middletier/Vfs.cpp
@@ -36,6 +36,26 @@ void cta::Vfs::checkDirectoryExists(const std::string &dirPath) {
   }
 }
 
+//------------------------------------------------------------------------------
+// isExistingDirectory
+//------------------------------------------------------------------------------
+bool cta::Vfs::isExistingDirectory(const SecurityIdentity &requester, const std::string &dirPath) {
+  cta::Utils::checkAbsolutePathSyntax(dirPath);
+  struct stat stat_result;
+  int rc;
+  
+  rc = stat((m_fsDir+dirPath).c_str(), &stat_result);
+  if(rc != 0) {
+    return false;
+  }
+  
+  if(!S_ISDIR(stat_result.st_mode)) {
+    return false;
+  }
+  
+  return true;
+}
+
 //------------------------------------------------------------------------------
 // checkPathnameDoesNotExist
 //------------------------------------------------------------------------------
diff --git a/libs/middletier/Vfs.hpp b/libs/middletier/Vfs.hpp
index 1dc97be4525d9c98e8e986471cec38e0710cc608..21dcf020a357a9d2c032caeeed46677839d48ccf 100644
--- a/libs/middletier/Vfs.hpp
+++ b/libs/middletier/Vfs.hpp
@@ -38,7 +38,9 @@ public:
   
   cta::DirectoryEntry statDirectoryEntry(const SecurityIdentity &requester, const std::string &pathname);
   
-  cta::DirectoryIterator getDirectoryContents(const SecurityIdentity &requester, const std::string &dirPath); 
+  cta::DirectoryIterator getDirectoryContents(const SecurityIdentity &requester, const std::string &dirPath);
+  
+  bool isExistingDirectory(const SecurityIdentity &requester, const std::string &dirPath);
 
 private: