diff --git a/libs/middletier/CMakeLists.txt b/libs/middletier/CMakeLists.txt
index 8173d6ebae276c6420138f103d19ea946e1a47ba..4fae59d9a343842c729e22f7f482b6eb4086853f 100644
--- a/libs/middletier/CMakeLists.txt
+++ b/libs/middletier/CMakeLists.txt
@@ -43,7 +43,8 @@ set (MIDDLE_TIER_LIB_SRC_FILES
   Tape.cpp
   TapePool.cpp
   UserIdentity.cpp
-  Utils.cpp)
+  Utils.cpp
+  Vfs.cpp)
 
 add_library (ctamiddletier SHARED
   ${MIDDLE_TIER_LIB_SRC_FILES})
diff --git a/libs/middletier/SqliteDatabase.hpp b/libs/middletier/SqliteDatabase.hpp
index 765c55238f240577afdcc90b736e1a8b717ca441..3edca48a627f51c6d737d75eecf354ca3806e844 100644
--- a/libs/middletier/SqliteDatabase.hpp
+++ b/libs/middletier/SqliteDatabase.hpp
@@ -1,17 +1,19 @@
 #pragma once
 
+#include <list>
+
 #include <sqlite3.h>
 
+#include "AdminHost.hpp"
+#include "AdminUser.hpp"
 #include "ArchivalJob.hpp"
+#include "ArchiveRoute.hpp"
+#include "LogicalLibrary.hpp"
 #include "RetrievalJob.hpp"
-#include "FileSystemNode.hpp"
-#include "FileSystemStorageClasses.hpp"
-#include "MockAdminHostTable.hpp"
-#include "MockAdminUserTable.hpp"
-#include "MockArchiveRouteTable.hpp"
-#include "MockLogicalLibraryTable.hpp"
-#include "MockTapeTable.hpp"
-#include "MockTapePoolTable.hpp"
+#include "SecurityIdentity.hpp"
+#include "StorageClass.hpp"
+#include "Tape.hpp"
+#include "TapePool.hpp"
 
 namespace cta {
 
diff --git a/libs/middletier/Vfs.cpp b/libs/middletier/Vfs.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ad95dcc7256078c7c4e651b655a4bf944fbf2b7f
--- /dev/null
+++ b/libs/middletier/Vfs.cpp
@@ -0,0 +1,214 @@
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <sstream>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <attr/xattr.h>
+#include <fcntl.h>
+
+#include "Exception.hpp"
+#include "Utils.hpp"
+#include "Vfs.hpp"
+
+//------------------------------------------------------------------------------
+// checkDirectoryExists
+//------------------------------------------------------------------------------
+void cta::Vfs::checkDirectoryExists(const std::string &dirPath) {
+  struct stat stat_result;
+  int rc;
+  
+  rc = stat(dirPath.c_str(), &stat_result);
+  if(rc != 0) {
+    char buf[256];
+    std::ostringstream message;
+    message << "checkDirectoryExists() - " << dirPath << " stat error. Reason: " << strerror_r(errno, buf, 256);
+    throw(Exception(message.str()));
+  }
+  
+  if(!S_ISDIR(stat_result.st_mode)) {
+    std::ostringstream message;
+    message << "checkDirectoryExists() - " << dirPath << " is not a directory";
+    throw(Exception(message.str()));
+  }
+}
+
+//------------------------------------------------------------------------------
+// checkPathnameDoesNotExist
+//------------------------------------------------------------------------------
+void cta::Vfs::checkPathnameDoesNotExist(const std::string &dirPath) {
+  struct stat stat_result;
+  int rc;
+  
+  rc = stat(dirPath.c_str(), &stat_result);
+  if(rc == 0) {
+    std::ostringstream message;
+    message << "checkPathnameDoesNotExist() - " << dirPath << " exists.";
+    throw(Exception(message.str()));
+  }
+}
+
+//------------------------------------------------------------------------------
+// constructor
+//------------------------------------------------------------------------------
+cta::Vfs::Vfs() {  
+  m_baseDir = "/tmp";  
+  m_fsDir = m_baseDir+"/CTATmpFs";
+  
+  checkDirectoryExists(m_baseDir);
+  checkPathnameDoesNotExist(m_fsDir);
+ 
+  int rc = mkdir(m_fsDir.c_str(), 0777);
+  if(rc != 0) {
+    char buf[256];
+    std::ostringstream message;
+    message << "Vfs() - mkdir " << m_fsDir << " error. Reason: \n" << strerror_r(errno, buf, 256);
+    throw(Exception(message.str()));
+  }  
+}
+
+//------------------------------------------------------------------------------
+// destructor
+//------------------------------------------------------------------------------
+cta::Vfs::~Vfs() throw() {
+  system("rm -rf /tmp/CTATmpFs");
+}  
+
+//------------------------------------------------------------------------------
+// setDirectoryStorageClass
+//------------------------------------------------------------------------------
+void cta::Vfs::setDirectoryStorageClass(const SecurityIdentity &requester, const std::string &path, const std::string &storageClassName) {
+  cta::Utils::checkAbsolutePathSyntax(path);
+  checkDirectoryExists(m_fsDir+path);
+  
+  int rc = setxattr((m_fsDir+path).c_str(), "CTAStorageClass", (void *)(storageClassName.c_str()), storageClassName.length(), XATTR_REPLACE);
+  if(rc != 0) {
+    char buf[256];
+    std::ostringstream message;
+    message << "setDirectoryStorageClass() - " << m_fsDir+path << " setxattr error. Reason: " << strerror_r(errno, buf, 256);
+    throw(Exception(message.str()));
+  }
+}  
+
+//------------------------------------------------------------------------------
+// clearDirectoryStorageClass
+//------------------------------------------------------------------------------
+void cta::Vfs::clearDirectoryStorageClass(const SecurityIdentity &requester, const std::string &path) {
+  cta::Utils::checkAbsolutePathSyntax(path);
+  checkDirectoryExists(m_fsDir+path);
+  
+  int rc = removexattr((m_fsDir+path).c_str(), "CTAStorageClass");
+  if(rc != 0) {
+    char buf[256];
+    std::ostringstream message;
+    message << "setDirectoryStorageClass() - " << m_fsDir+path << " setxattr error. Reason: " << strerror_r(errno, buf, 256);
+    throw(Exception(message.str()));
+  }
+}  
+
+//------------------------------------------------------------------------------
+// getDirectoryStorageClass
+//------------------------------------------------------------------------------
+std::string cta::Vfs::getDirectoryStorageClass(const SecurityIdentity &requester, const std::string &path) {
+  cta::Utils::checkAbsolutePathSyntax(path);
+  checkDirectoryExists(m_fsDir+path);
+  
+  char value[1024];
+  int rc = getxattr((m_fsDir+path).c_str(), "CTAStorageClass", (void *)value, 1024);
+  if(rc != 0) {
+    char buf[256];
+    std::ostringstream message;
+    message << "setDirectoryStorageClass() - " << m_fsDir+path << " setxattr error. Reason: " << strerror_r(errno, buf, 256);
+    throw(Exception(message.str()));
+  }
+  return std::string(value);
+}  
+
+//------------------------------------------------------------------------------
+// createFile
+//------------------------------------------------------------------------------
+void cta::Vfs::createFile(const SecurityIdentity &requester, const std::string &pathname, const uint16_t mode) {
+  cta::Utils::checkAbsolutePathSyntax(pathname);  
+  std::string path = cta::Utils::getEnclosingDirPath(pathname);
+  std::string name = cta::Utils::getEnclosedName(pathname);
+  checkDirectoryExists(m_fsDir+path);
+  
+  int fd = open((m_fsDir+pathname).c_str(), O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK, 0666);
+  if(fd<0) {
+    char buf[256];
+    std::ostringstream message;
+    message << "createFile() - " << m_fsDir+pathname << " open error. Reason: " << strerror_r(errno, buf, 256);
+    throw(Exception(message.str()));
+  }
+  int rc = utimensat(AT_FDCWD, (m_fsDir+pathname).c_str(), NULL, 0);
+  if(rc) {
+    char buf[256];
+    std::ostringstream message;
+    message << "createFile() - " << m_fsDir+pathname << " utimensat error. Reason: " << strerror_r(errno, buf, 256);
+    throw(Exception(message.str()));
+  }
+}  
+
+//------------------------------------------------------------------------------
+// createDirectory
+//------------------------------------------------------------------------------
+void cta::Vfs::createDirectory(const SecurityIdentity &requester, const std::string &pathname, const uint16_t mode) {  
+  cta::Utils::checkAbsolutePathSyntax(pathname);  
+  std::string path = cta::Utils::getEnclosingDirPath(pathname);
+  std::string name = cta::Utils::getEnclosedName(pathname);
+  checkDirectoryExists(m_fsDir+path);
+  
+  int rc = mkdir((m_fsDir+pathname).c_str(), 0777);
+  if(rc != 0) {
+    char buf[256];
+    std::ostringstream message;
+    message << "createDirectory() - mkdir " << m_fsDir+pathname << " error. Reason: \n" << strerror_r(errno, buf, 256);
+    throw(Exception(message.str()));
+  }
+}  
+
+//------------------------------------------------------------------------------
+// deleteFile
+//------------------------------------------------------------------------------
+void cta::Vfs::deleteFile(const SecurityIdentity &requester, const std::string &pathname) {  
+  cta::Utils::checkAbsolutePathSyntax(pathname);
+  
+  int rc = unlink((m_fsDir+pathname).c_str());
+  if(rc != 0) {
+    char buf[256];
+    std::ostringstream message;
+    message << "deleteFile() - unlink " << m_fsDir+pathname << " error. Reason: \n" << strerror_r(errno, buf, 256);
+    throw(Exception(message.str()));
+  }  
+}  
+
+//------------------------------------------------------------------------------
+// deleteDirectory
+//------------------------------------------------------------------------------
+void cta::Vfs::deleteDirectory(const SecurityIdentity &requester, const std::string &pathname) {  
+  cta::Utils::checkAbsolutePathSyntax(pathname);
+  
+  int rc = rmdir((m_fsDir+pathname).c_str());
+  if(rc != 0) {
+    char buf[256];
+    std::ostringstream message;
+    message << "deleteDirectory() - rmdir " << m_fsDir+pathname << " error. Reason: \n" << strerror_r(errno, buf, 256);
+    throw(Exception(message.str()));
+  }  
+}  
+
+//------------------------------------------------------------------------------
+// stat
+//------------------------------------------------------------------------------
+cta::DirectoryEntry cta::Vfs::statDirectoryEntry(const SecurityIdentity &requester, const std::string &pathname) {
+  throw(Exception("statDirectoryEntry() - Not implemented!"));
+}  
+
+//------------------------------------------------------------------------------
+// getDirectoryContents
+//------------------------------------------------------------------------------
+cta::DirectoryIterator cta::Vfs::getDirectoryContents(const SecurityIdentity &requester, const std::string &dirPath) {
+  throw(Exception("statDirectoryEntry() - Not implemented!"));
+}
\ No newline at end of file
diff --git a/libs/middletier/Vfs.hpp b/libs/middletier/Vfs.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..6f0eae0ad0a6949bc5e00846aee212b132088866
--- /dev/null
+++ b/libs/middletier/Vfs.hpp
@@ -0,0 +1,55 @@
+#pragma once
+
+#include "DirectoryIterator.hpp"
+#include "SecurityIdentity.hpp"
+
+namespace cta {
+
+/**
+ * Mock database.
+ */
+class Vfs {
+
+public:
+
+  /**
+   * Constructor.
+   */
+  Vfs();
+
+  /**
+   * Destructor.
+   */
+  ~Vfs() throw();  
+  
+  void setDirectoryStorageClass(const SecurityIdentity &requester, const std::string &path, const std::string &storageClassName);
+  
+  void clearDirectoryStorageClass(const SecurityIdentity &requester, const std::string &path);
+  
+  std::string getDirectoryStorageClass(const SecurityIdentity &requester, const std::string &path);
+  
+  void createFile(const SecurityIdentity &requester, const std::string &pathname, const uint16_t mode);
+  
+  void createDirectory(const SecurityIdentity &requester, const std::string &pathname, const uint16_t mode);
+  
+  void deleteFile(const SecurityIdentity &requester, const std::string &pathname);
+  
+  void deleteDirectory(const SecurityIdentity &requester, const std::string &pathname);
+  
+  cta::DirectoryEntry statDirectoryEntry(const SecurityIdentity &requester, const std::string &pathname);
+  
+  cta::DirectoryIterator getDirectoryContents(const SecurityIdentity &requester, const std::string &dirPath); 
+
+private:
+  
+  std::string m_baseDir;
+  
+  std::string m_fsDir;
+  
+  void checkDirectoryExists(const std::string &dirPath);
+  
+  void checkPathnameDoesNotExist(const std::string &dirPath);
+  
+}; // struct Vfs
+
+} // namespace cta