diff --git a/middletier/CMakeLists.txt b/middletier/CMakeLists.txt
index bf665aff844110dc55ab21b04efb4177fa40e41a..06e6d8d0ce98d95565e98cb7a88ca521b2e7360e 100644
--- a/middletier/CMakeLists.txt
+++ b/middletier/CMakeLists.txt
@@ -32,8 +32,10 @@ set (MIDDLE_TIER_LIB_SRC_FILES
   cta/LogicalLibrary.cpp
   cta/MiddleTierAdmin.cpp
   cta/MiddleTierUser.cpp
+  cta/MockNameServer.cpp
   cta/Mount.cpp
   cta/MountCriteria.cpp
+  cta/NameServer.cpp
   cta/RemoteStorage.cpp
   cta/RetrievalFileTransfer.cpp
   cta/RetrievalJob.cpp
@@ -69,7 +71,7 @@ set (MIDDLE_TIER_UNIT_TESTS_LIB_SRC_FILES
   cta/SqliteMiddleTierAdminTest.cpp
   cta/SqliteMiddleTierUserTest.cpp
   cta/UtilsTest.cpp
-  cta/VfsTest.cpp)
+  cta/MockNameServerTest.cpp)
 
 add_library (ctamiddletierunittests SHARED
   ${MIDDLE_TIER_UNIT_TESTS_LIB_SRC_FILES})
diff --git a/middletier/cta/MockNameServer.cpp b/middletier/cta/MockNameServer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..885543e88b2e155d314280574fdcf7e55a15f99e
--- /dev/null
+++ b/middletier/cta/MockNameServer.cpp
@@ -0,0 +1,402 @@
+/**
+ * The CERN Tape Archive (CTA) project
+ * Copyright (C) 2015  CERN
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <iostream>
+#include <sstream>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <attr/xattr.h>
+#include <fcntl.h>
+
+#include "cta/Exception.hpp"
+#include "cta/Utils.hpp"
+#include "cta/MockNameServer.hpp"
+
+//------------------------------------------------------------------------------
+// assertFsDirExists
+//------------------------------------------------------------------------------
+void cta::MockNameServer::assertFsDirExists(const std::string &path) const {
+  struct stat stat_result;
+  
+  if(::stat(path.c_str(), &stat_result)) {
+    char buf[256];
+    std::ostringstream message;
+    message << "assertFsDirExists() - " << path << " stat error. Reason: "
+      << strerror_r(errno, buf, sizeof(buf));
+    throw(Exception(message.str()));
+  }
+  
+  if(!S_ISDIR(stat_result.st_mode)) {
+    std::ostringstream message;
+    message << "assertFsDirExists() - " << path << " is not a directory";
+    throw(Exception(message.str()));
+  }
+}
+
+//------------------------------------------------------------------------------
+// assertFsPathDoesNotExist
+//------------------------------------------------------------------------------
+void cta::MockNameServer::assertFsPathDoesNotExist(const std::string &path)
+  const {
+  struct stat stat_result;
+
+  if(::stat(path.c_str(), &stat_result) == 0) {
+    std::ostringstream message;
+    message << "assertFsPathExist() - " << path << " exists.";
+    throw(Exception(message.str()));
+  }
+}
+
+//------------------------------------------------------------------------------
+// dirExists
+//------------------------------------------------------------------------------
+bool cta::MockNameServer::dirExists(const SecurityIdentity &requester,
+  const std::string &path) const {
+  Utils::checkAbsolutePathSyntax(path);
+  const std::string fsPath = m_fsDir + path;
+  struct stat stat_result;
+  
+  if(::stat(fsPath.c_str(), &stat_result)) {
+    return false;
+  }
+  
+  if(!S_ISDIR(stat_result.st_mode)) {
+    return false;
+  }
+  
+  return true;
+}
+
+//------------------------------------------------------------------------------
+// checkStorageClassIsNotInUse
+//------------------------------------------------------------------------------
+void cta::MockNameServer::checkStorageClassIsNotInUse(
+  const SecurityIdentity &requester,
+  const std::string &storageClass,
+  const std::string &path) const {
+
+  if(getDirStorageClass(requester, path) == storageClass) {
+    std::ostringstream message;
+    message << "checkStorageClassIsNotInUse() - " << path << " has the " <<
+      storageClass << " storage class.";
+    throw(Exception(message.str()));
+  }
+
+  const std::string fsPath = m_fsDir + path;
+  
+  struct dirent *entry;
+  DIR *const dp = opendir(fsPath.c_str());
+  if (dp == NULL) {
+    char buf[256];
+    std::ostringstream message;
+    message << "checkStorageClassIsNotInUse() - opendir " << fsPath <<
+      " error. Reason: \n" << strerror_r(errno, buf, sizeof(buf));
+    throw(Exception(message.str()));
+  }
+ 
+  const bool pathEndsWithASlash = path.at(path.length()-1) == '/';
+  while((entry = readdir(dp))) {
+    const std::string entryName(entry->d_name);
+    if(entry->d_type == DT_DIR && entryName != "." && entryName != "..") {
+      const std::string entryPath = pathEndsWithASlash ?
+        path + entryName : path + "/" + entryName;
+      try {
+        checkStorageClassIsNotInUse(requester, storageClass, entryPath);
+      } catch (...) {
+        closedir(dp);
+        throw;
+      }
+    }
+  }
+
+  closedir(dp);
+}
+
+//------------------------------------------------------------------------------
+// constructor
+//------------------------------------------------------------------------------
+cta::MockNameServer::MockNameServer() {  
+  m_baseDir = "/tmp";  
+  m_fsDir = m_baseDir + "/CTATmpFs";
+  
+  assertFsDirExists(m_baseDir);
+  assertFsPathDoesNotExist(m_fsDir);
+ 
+  if(mkdir(m_fsDir.c_str(), 0777)) {
+    char buf[256];
+    std::ostringstream message;
+    message << "MockNameServer() - mkdir " << m_fsDir << " error. Reason: \n" << strerror_r(errno, buf, sizeof(buf));
+    throw(Exception(message.str()));
+  }
+  
+  if(setxattr(m_fsDir.c_str(), "user.CTAStorageClass", "", 0, 0)) {
+    char buf[256];
+    std::ostringstream message;
+    message << "MockNameServer() - " << m_fsDir << " setxattr error. Reason: " << strerror_r(errno, buf, sizeof(buf));
+    throw(Exception(message.str()));
+  }
+}
+
+//------------------------------------------------------------------------------
+// destructor
+//------------------------------------------------------------------------------
+cta::MockNameServer::~MockNameServer() throw() {
+  system("rm -rf /tmp/CTATmpFs");
+}  
+
+//------------------------------------------------------------------------------
+// setDirStorageClass
+//------------------------------------------------------------------------------
+void cta::MockNameServer::setDirStorageClass(const SecurityIdentity &requester, const std::string &path, const std::string &storageClassName) {
+  Utils::checkAbsolutePathSyntax(path);
+  const std::string fsPath = m_fsDir + path;
+  assertFsDirExists(fsPath);
+  
+  if(setxattr(fsPath.c_str(), "user.CTAStorageClass", storageClassName.c_str(), storageClassName.length(), 0)) {
+    char buf[256];
+    std::ostringstream message;
+    message << "setDirStorageClass() - " << fsPath << " setxattr error. Reason: " << strerror_r(errno, buf, sizeof(buf));
+    throw(Exception(message.str()));
+  }
+}  
+
+//------------------------------------------------------------------------------
+// clearDirStorageClass
+//------------------------------------------------------------------------------
+void cta::MockNameServer::clearDirStorageClass(
+  const SecurityIdentity &requester,
+  const std::string &path) {
+  Utils::checkAbsolutePathSyntax(path);
+  const std::string fsPath = m_fsDir + path;
+  assertFsDirExists(fsPath);
+  
+  if(setxattr(fsPath.c_str(), "user.CTAStorageClass", "", 0, 0)) {
+    char buf[256];
+    std::ostringstream message;
+    message << "clearDirStorageClass() - " << fsPath << " setxattr error. Reason: " << strerror_r(errno, buf, sizeof(buf));
+    throw(Exception(message.str()));
+  }
+}  
+
+//------------------------------------------------------------------------------
+// getDirStorageClass
+//------------------------------------------------------------------------------
+std::string cta::MockNameServer::getDirStorageClass(
+  const SecurityIdentity &requester,
+  const std::string &path) const {
+  Utils::checkAbsolutePathSyntax(path);
+  const std::string fsPath = m_fsDir + path;
+  assertFsDirExists(fsPath);
+  
+  char value[1024];
+  bzero(value, sizeof(value));
+  if(0 > getxattr(fsPath.c_str(), "user.CTAStorageClass", value, sizeof(value))) {
+    char buf[256];
+    std::ostringstream message;
+    message << "getDirStorageClass() - " << fsPath << " getxattr error. Reason: " << strerror_r(errno, buf, sizeof(buf));
+    throw(Exception(message.str()));
+  }
+  return std::string(value);
+}  
+
+//------------------------------------------------------------------------------
+// createFile
+//------------------------------------------------------------------------------
+void cta::MockNameServer::createFile(
+  const SecurityIdentity &requester,
+  const std::string &path,
+  const uint16_t mode) {
+  Utils::checkAbsolutePathSyntax(path);  
+  assertFsDirExists(m_fsDir + Utils::getEnclosingDirPath(path));
+  const std::string fsPath = m_fsDir + path;
+  assertFsPathDoesNotExist(fsPath);
+
+  const int fd = open(fsPath.c_str(), O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK, mode);
+  if(fd<0) {
+    char buf[256];
+    std::ostringstream message;
+    message << "createFile() - " << fsPath << " open error. Reason: " << strerror_r(errno, buf, sizeof(buf));
+    throw(Exception(message.str()));
+  }
+  if(utimensat(AT_FDCWD, fsPath.c_str(), NULL, 0)) {
+    char buf[256];
+    std::ostringstream message;
+    message << "createFile() - " << fsPath << " utimensat error. Reason: " << strerror_r(errno, buf, sizeof(buf));
+    throw(Exception(message.str()));
+  }
+}  
+
+//------------------------------------------------------------------------------
+// createDir
+//------------------------------------------------------------------------------
+void cta::MockNameServer::createDir(const SecurityIdentity &requester,
+  const std::string &path, const uint16_t mode) {  
+  Utils::checkAbsolutePathSyntax(path);  
+  const std::string enclosingDirPath = Utils::getEnclosingDirPath(path);
+  assertFsDirExists(m_fsDir + enclosingDirPath);
+
+  const std::string inheritedStorageClass = getDirStorageClass(requester,
+    enclosingDirPath);
+  const std::string fsPath = m_fsDir + path;
+  
+  if(mkdir(fsPath.c_str(), mode)) {
+    char buf[256];
+    std::ostringstream message;
+    message << "createDir() - mkdir " << fsPath << " error. Reason: \n" << strerror_r(errno, buf, sizeof(buf));
+    throw(Exception(message.str()));
+  }
+  
+  setDirStorageClass(requester, path, inheritedStorageClass);
+}  
+
+//------------------------------------------------------------------------------
+// deleteFile
+//------------------------------------------------------------------------------
+void cta::MockNameServer::deleteFile(const SecurityIdentity &requester, const std::string &path) {  
+  Utils::checkAbsolutePathSyntax(path);
+  const std::string fsPath = m_fsDir + path;
+  
+  if(unlink(fsPath.c_str())) {
+    char buf[256];
+    std::ostringstream message;
+    message << "deleteFile() - unlink " << fsPath << " error. Reason: \n" <<
+      strerror_r(errno, buf, sizeof(buf));
+    throw(Exception(message.str()));
+  }  
+}  
+
+//------------------------------------------------------------------------------
+// deleteDir
+//------------------------------------------------------------------------------
+void cta::MockNameServer::deleteDir(const SecurityIdentity &requester, const std::string &path) {
+  if(path == "/") {    
+    std::ostringstream message;
+    message << "deleteDir() - Cannot delete root directory";
+    throw(Exception(message.str()));
+  }
+  Utils::checkAbsolutePathSyntax(path);
+  const std::string fsPath = m_fsDir + path;
+  
+  if(rmdir(fsPath.c_str())) {
+    char buf[256];
+    std::ostringstream message;
+    message << "deleteDir() - rmdir " << fsPath << " error. Reason: \n" <<
+      strerror_r(errno, buf, sizeof(buf));
+    throw(Exception(message.str()));
+  }  
+}  
+
+//------------------------------------------------------------------------------
+// statDirEntry
+//------------------------------------------------------------------------------
+cta::DirEntry cta::MockNameServer::statDirEntry(
+  const SecurityIdentity &requester,
+  const std::string &path) const {
+  Utils::checkAbsolutePathSyntax(path);
+  const std::string name = Utils::getEnclosedName(path);
+  const std::string enclosingPath = Utils::getEnclosingDirPath(path);
+  const std::string fsPath = m_fsDir + path;
+
+  struct stat stat_result;
+  if(::stat(fsPath.c_str(), &stat_result)) {
+    char buf[256];
+    std::ostringstream message;
+    message << "statDirEntry() - " << fsPath << " stat error. Reason: " <<
+      strerror_r(errno, buf, sizeof(buf));
+    throw(Exception(message.str()));
+  }
+
+  DirEntry::EntryType entryType;
+  std::string storageClassName;
+  
+  if(S_ISDIR(stat_result.st_mode)) {
+    entryType = DirEntry::ENTRYTYPE_DIRECTORY;
+    storageClassName = getDirStorageClass(requester, path);
+  }
+  else if(S_ISREG(stat_result.st_mode)) {
+    entryType = DirEntry::ENTRYTYPE_FILE;
+    storageClassName = getDirStorageClass(requester, enclosingPath);
+  }
+  else {
+    std::ostringstream message;
+    message << "statDirEntry() - " << m_fsDir+path <<
+      " is not a directory nor a regular file";
+    throw(Exception(message.str()));
+  } 
+  
+  return DirEntry(entryType, name, storageClassName);
+}
+
+//------------------------------------------------------------------------------
+// getDirEntries
+//------------------------------------------------------------------------------
+std::list<cta::DirEntry> cta::MockNameServer::getDirEntries(
+  const SecurityIdentity &requester,
+  const std::string &path) const {  
+  const std::string fsPath = m_fsDir + path;
+  DIR *const dp = opendir(fsPath.c_str());
+
+  if(dp == NULL) {
+    char buf[256];
+    std::ostringstream message;
+    message << "getDirEntries() - opendir " << fsPath << " error. Reason: \n" <<
+      strerror_r(errno, buf, sizeof(buf));
+    throw(Exception(message.str()));
+  }
+  
+  std::list<DirEntry> entries;
+  struct dirent *entry;
+  
+  const bool pathEndsWithASlash = path.at(path.length()-1) == '/';
+  while((entry = readdir(dp))) {
+    const std::string entryName(entry->d_name);
+    if(entryName != "." && entryName != "..") {
+      const std::string entryPath = pathEndsWithASlash ?
+        path + entryName : path + "/" + entryName;
+      entries.push_back(statDirEntry(requester, entryPath));
+    }
+  }
+  
+  closedir(dp);  
+  return entries;
+}
+
+//------------------------------------------------------------------------------
+// getDirContents
+//------------------------------------------------------------------------------
+cta::DirIterator cta::MockNameServer::getDirContents(
+  const SecurityIdentity &requester, const std::string &path) const {
+  Utils::checkAbsolutePathSyntax(path);
+  assertFsDirExists(m_fsDir+path);
+  return getDirEntries(requester, path);
+}
+
+//------------------------------------------------------------------------------
+// getVidOfFile
+//------------------------------------------------------------------------------
+std::string cta::MockNameServer::getVidOfFile(
+  const SecurityIdentity &requester,
+  const std::string &path,
+  uint16_t copyNb) const {
+  return "T00001"; //everything is on one tape for the moment:)
+}
diff --git a/middletier/cta/MockNameServer.hpp b/middletier/cta/MockNameServer.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..924dddbb8bfd393995607841024ec6a705f430e1
--- /dev/null
+++ b/middletier/cta/MockNameServer.hpp
@@ -0,0 +1,86 @@
+/**
+ * The CERN Tape Archive (CTA) project
+ * Copyright (C) 2015  CERN
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "cta/DirIterator.hpp"
+#include "cta/NameServer.hpp"
+#include "cta/SecurityIdentity.hpp"
+
+#include <list>
+#include <string>
+
+namespace cta {
+
+/**
+ * Local file system implementation of a name server to contain the archive
+ * namespace.
+ */
+class MockNameServer: public NameServer {
+
+public:
+
+  /**
+   * Constructor.
+   */
+  MockNameServer();
+
+  /**
+   * Destructor.
+   */
+  ~MockNameServer() throw();  
+  
+  void setDirStorageClass(const SecurityIdentity &requester, const std::string &path, const std::string &storageClassName);
+  
+  void clearDirStorageClass(const SecurityIdentity &requester, const std::string &path);
+  
+  std::string getDirStorageClass(const SecurityIdentity &requester, const std::string &path) const;
+  
+  void createFile(const SecurityIdentity &requester, const std::string &path, const uint16_t mode);
+  
+  void createDir(const SecurityIdentity &requester, const std::string &path, const uint16_t mode);
+  
+  void deleteFile(const SecurityIdentity &requester, const std::string &path);
+  
+  void deleteDir(const SecurityIdentity &requester, const std::string &path);
+  
+  cta::DirEntry statDirEntry(const SecurityIdentity &requester, const std::string &path) const;
+  
+  cta::DirIterator getDirContents(const SecurityIdentity &requester, const std::string &path) const;
+  
+  bool dirExists(const SecurityIdentity &requester, const std::string &path) const;
+  
+  std::string getVidOfFile(const SecurityIdentity &requester, const std::string &path, uint16_t copyNb) const;
+  
+  void checkStorageClassIsNotInUse(const SecurityIdentity &requester, const std::string &storageClass, const std::string &path) const;
+
+private:
+  
+  std::string m_baseDir;
+  
+  std::string m_fsDir;
+  
+  void assertFsDirExists(const std::string &path) const;
+  
+  void assertFsPathDoesNotExist(const std::string &path) const;
+  
+  std::list<cta::DirEntry> getDirEntries(const SecurityIdentity &requester, const std::string &path) const;
+  
+}; // class MockNameServer
+
+} // namespace cta
diff --git a/middletier/cta/MockNameServerTest.cpp b/middletier/cta/MockNameServerTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1a71a52515ebad582ba526e9fcbf2c249c8ed635
--- /dev/null
+++ b/middletier/cta/MockNameServerTest.cpp
@@ -0,0 +1,177 @@
+/**
+ * The CERN Tape Archive (CTA) project
+ * Copyright (C) 2015  CERN
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cta/MockNameServer.hpp"
+
+#include <gtest/gtest.h>
+#include <memory>
+
+namespace unitTests {
+
+class cta_MockNameServerTest: public ::testing::Test {
+protected:
+
+  virtual void SetUp() {
+  }
+
+  virtual void TearDown() {
+  }
+};
+
+TEST_F(cta_MockNameServerTest, constructor_consistency) {
+  using namespace cta;
+
+  std::auto_ptr<MockNameServer> ns;
+  ASSERT_NO_THROW(ns.reset(new MockNameServer()));
+
+  cta::SecurityIdentity requester;
+  DirIterator itor;
+  
+  ASSERT_NO_THROW(itor = ns->getDirContents(requester, "/"));
+  ASSERT_FALSE(itor.hasMore());
+  ASSERT_EQ(std::string(""), ns->getDirStorageClass(requester, "/"));
+}
+
+TEST_F(cta_MockNameServerTest, mkdir_functionality) {
+  using namespace cta;
+
+  std::auto_ptr<MockNameServer> ns;
+  ASSERT_NO_THROW(ns.reset(new MockNameServer()));
+
+  cta::SecurityIdentity requester;
+  DirIterator itor;
+  
+  ASSERT_NO_THROW(ns->createDir(requester, "/dir1", 0777));
+  ASSERT_THROW(ns->createDir(requester, "/dir1", 0777), std::exception);
+  ASSERT_NO_THROW(itor = ns->getDirContents(requester, "/"));
+  ASSERT_EQ(itor.hasMore(), true);
+  ASSERT_EQ(itor.next().getName(), "dir1");
+  ASSERT_EQ(itor.hasMore(), false);
+}
+
+TEST_F(cta_MockNameServerTest, createFile_functionality) {
+  using namespace cta;
+
+  std::auto_ptr<MockNameServer> ns;
+  ASSERT_NO_THROW(ns.reset(new MockNameServer()));
+
+  cta::SecurityIdentity requester;
+  DirIterator itor;
+  
+  ASSERT_NO_THROW(ns->createFile(requester, "/file1", 0666));
+  ASSERT_THROW(ns->createFile(requester, "/file1", 0666), std::exception);
+  ASSERT_NO_THROW(itor = ns->getDirContents(requester, "/"));
+  ASSERT_EQ(itor.hasMore(), true);
+  ASSERT_EQ(itor.next().getName(), "file1");
+  ASSERT_EQ(itor.hasMore(), false);
+}
+
+TEST_F(cta_MockNameServerTest, rmdir_functionality) {
+  using namespace cta;
+
+  std::auto_ptr<MockNameServer> ns;
+  ASSERT_NO_THROW(ns.reset(new MockNameServer()));
+
+  cta::SecurityIdentity requester;
+  DirIterator itor;
+  
+  ASSERT_NO_THROW(ns->createDir(requester, "/dir1", 0777));
+  ASSERT_NO_THROW(ns->deleteDir(requester, "/dir1"));
+  ASSERT_THROW(ns->deleteDir(requester, "/dir1"), std::exception);
+  ASSERT_NO_THROW(ns->createDir(requester, "/dir2", 0777));
+  ASSERT_NO_THROW(ns->createFile(requester, "/dir2/file1", 0666));
+  ASSERT_THROW(ns->deleteDir(requester, "/dir2"), std::exception);
+  ASSERT_NO_THROW(ns->deleteFile(requester, "/dir2/file1"));
+  ASSERT_NO_THROW(ns->deleteDir(requester, "/dir2"));
+  ASSERT_NO_THROW(itor = ns->getDirContents(requester, "/"));
+  ASSERT_FALSE(itor.hasMore());
+  ASSERT_EQ(std::string(""), ns->getDirStorageClass(requester, "/"));  
+}
+
+TEST_F(cta_MockNameServerTest, storageClass_functionality) {
+  using namespace cta;
+
+  std::auto_ptr<MockNameServer> ns;
+  ASSERT_NO_THROW(ns.reset(new MockNameServer()));
+
+  cta::SecurityIdentity requester;
+  DirIterator itor;
+  
+  ASSERT_NO_THROW(ns->createDir(requester, "/dir1", 0777));
+  ASSERT_EQ(std::string(""), ns->getDirStorageClass(requester, "/dir1"));
+  ASSERT_NO_THROW(ns->setDirStorageClass(requester, "/dir1", "cms"));
+  {
+    std::string storageClass;
+    ASSERT_NO_THROW(storageClass = ns->getDirStorageClass(requester, "/dir1"));
+    ASSERT_EQ(std::string("cms"), storageClass);
+  }
+  ASSERT_NO_THROW(ns->clearDirStorageClass(requester, "/dir1"));
+  {
+    std::string storageClass;
+    ASSERT_NO_THROW(storageClass = ns->getDirStorageClass(requester, "/dir1"));
+    ASSERT_EQ(std::string(""), storageClass);
+  }
+  ASSERT_NO_THROW(ns->setDirStorageClass(requester, "/dir1", "atlas"));
+  {
+    std::string storageClass;
+    ASSERT_NO_THROW(storageClass = ns->getDirStorageClass(requester, "/dir1"));
+    ASSERT_EQ(std::string("atlas"), storageClass);
+  }
+}
+
+TEST_F(cta_MockNameServerTest, storageClass_inheritance) {
+  using namespace cta;
+
+  std::auto_ptr<MockNameServer> ns;
+  ASSERT_NO_THROW(ns.reset(new MockNameServer()));
+
+  cta::SecurityIdentity requester;
+  DirIterator itor;
+  
+  ASSERT_NO_THROW(ns->createDir(requester, "/dir1", 0777));
+  {
+    std::string storageClass;
+    ASSERT_NO_THROW(storageClass = ns->getDirStorageClass(requester, "/dir1"));
+    ASSERT_EQ(std::string(""), storageClass);  
+  }
+  ASSERT_NO_THROW(ns->createDir(requester, "/dir1/dir1_1", 0777));
+  {
+    std::string storageClass;
+    ASSERT_NO_THROW(storageClass = ns->getDirStorageClass(requester, "/dir1/dir1_1"));
+    ASSERT_EQ(std::string(""), storageClass);  
+  }
+  ASSERT_NO_THROW(ns->setDirStorageClass(requester, "/dir1", "cms"));
+  {
+    std::string storageClass;
+    ASSERT_NO_THROW(storageClass = ns->getDirStorageClass(requester, "/dir1"));
+    ASSERT_EQ(std::string("cms"), storageClass);
+  }
+  ASSERT_NO_THROW(ns->createDir(requester, "/dir1/dir1_2", 0777));
+  {
+    std::string storageClass;
+    ASSERT_NO_THROW(storageClass = ns->getDirStorageClass(requester, "/dir1/dir1_2"));
+    ASSERT_EQ(std::string("cms"), storageClass);
+  }
+  {
+    std::string storageClass;
+    ASSERT_NO_THROW(storageClass = ns->getDirStorageClass(requester, "/dir1/dir1_1"));
+    ASSERT_EQ(std::string(""), storageClass);
+  }
+}
+
+}
diff --git a/middletier/cta/NameServer.cpp b/middletier/cta/NameServer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..947bbac42a0bbf99fcf70ab3873dfbe8d6f3d68f
--- /dev/null
+++ b/middletier/cta/NameServer.cpp
@@ -0,0 +1,25 @@
+/**
+ * The CERN Tape Archive (CTA) project
+ * Copyright (C) 2015  CERN
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cta/NameServer.hpp"
+
+//------------------------------------------------------------------------------
+// destructor
+//------------------------------------------------------------------------------
+cta::NameServer::~NameServer() throw() {
+}
diff --git a/middletier/cta/NameServer.hpp b/middletier/cta/NameServer.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..986ca3ce57dfaa73208c78c891bb05559218a6e0
--- /dev/null
+++ b/middletier/cta/NameServer.hpp
@@ -0,0 +1,156 @@
+/**
+ * The CERN Tape Archive (CTA) project
+ * Copyright (C) 2015  CERN
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "cta/DirIterator.hpp"
+#include "cta/SecurityIdentity.hpp"
+
+#include <string>
+
+namespace cta {
+
+/**
+ * Abstract class specifying the interface to the name server containing the
+ * archive namespace.
+ */
+class NameServer {
+public:
+
+  /**
+   * Destructor.
+   */
+  virtual ~NameServer() throw() = 0;
+
+  /**
+   * Creates the specified directory.
+   *
+   * @param requester The identity of the requester.
+   * @param path The absolute path of the directory.
+   * @param mode The mode bits of the directory entry.
+   */
+  virtual void createDir(
+    const SecurityIdentity &requester,
+    const std::string &path,
+    const uint16_t mode) = 0;
+
+  /**
+   * Deletes the specified directory.
+   *
+   * @param requester The identity of the requester.
+   * @param path The absolute path of the directory.
+   */
+  virtual void deleteDir(
+   const SecurityIdentity &requester,
+   const std::string &path) = 0;
+
+  /**
+   * Gets the contents of the specified directory.
+   *
+   * @param requester The identity of the requester.
+   * @param path The absolute path of the directory.
+   * @return An iterator over the contents of the directory.
+   */
+  virtual DirIterator getDirContents(
+    const SecurityIdentity &requester,
+    const std::string &path) const = 0;
+
+  /**
+   * Returns the directory entry information for the specified directory or file
+   * within the archive namespace.
+   *
+   * @param requester The identity of the requester.
+   * @param path The absolute path of the directory or file within the archive
+   * namespace.
+   * @return The directory entry information for the specified directory or file
+   * within the archive namespace.
+   */
+  virtual DirEntry statDirEntry(
+    const SecurityIdentity &requester,
+    const std::string &path) const = 0;
+
+  /**
+   * Sets the storage class of the specified directory to the specified value.
+   *
+   * @param requester The identity of the requester.
+   * @param path The absolute path of the directory.
+   * @param storageClassName The name of the storage class.
+   */
+  virtual void setDirStorageClass(
+    const SecurityIdentity &requester,
+    const std::string &path,
+    const std::string &storageClassName) = 0;
+
+  /**
+   * Clears the storage class of the specified directory.
+   *
+   * @param requester The identity of the requester.
+   * @param path The absolute path of the directory.
+   */
+  virtual void clearDirStorageClass(
+    const SecurityIdentity &requester,
+    const std::string &path) = 0;
+
+  /**
+   * Returns the name of the storage class of the specified directory.
+   *
+   * @param requester The identity of the requester.
+   * @param path The absolute path of the directory.
+   * @return The name of the storage class of the specified directory.
+   */
+  virtual std::string getDirStorageClass(
+    const SecurityIdentity &requester,
+    const std::string &path) const = 0;
+
+  /**
+   * Creates the specified file entry.
+   *
+   * @param requester The identity of the requester.
+   * @param path The absolute path of the directory.
+   * @param mode The mode bits of the file entry.
+   */
+  virtual void createFile(
+    const SecurityIdentity &requester,
+    const std::string &path,
+    const uint16_t mode) = 0;
+
+  /**
+   * Deletes the specified file entry.
+   *
+   * @param requester The identity of the requester.
+   * @param path The absolute path of the file.
+   */
+  virtual void deleteFile(
+    const SecurityIdentity &requester,
+    const std::string &path) = 0;
+
+  /**
+   * Returns true if the specified directory exists.
+   *
+   * @param requester The identity of the requester.
+   * @param path The absolute path of the file.
+
+   * @return True if the specified directory exists.
+   */
+  virtual bool dirExists(
+    const SecurityIdentity &requester,
+    const std::string &path) const = 0;
+
+}; // class NameServer
+
+} // namespace