diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 5c9ee0ec9eda4c5f1459df8a9614e70a06d82ebf..7e4b4700b479f09f803ecb952af9f4b7c68fa1e4 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -70,7 +70,7 @@ void cmLocalGenerator::IssueMessage(cmake::MessageType t,
                                     std::string const& text) const
 {
   cmListFileContext lfc;
-  lfc.FilePath = this->StateSnapshot.GetCurrentSourceDirectory();
+  lfc.FilePath = this->StateSnapshot.GetDirectory().GetCurrentSource();
   lfc.FilePath += "/CMakeLists.txt";
 
   if(!this->GlobalGenerator->GetCMakeInstance()->GetIsInTryCompile())
@@ -161,7 +161,8 @@ void cmLocalGenerator::GenerateTestFiles()
   const std::string& config =
     this->Makefile->GetConfigurations(configurationTypes, false);
 
-  std::string file = this->StateSnapshot.GetCurrentBinaryDirectory();
+  std::string file =
+      this->StateSnapshot.GetDirectory().GetCurrentBinary();
   file += "/";
   file += "CTestTestfile.cmake";
 
@@ -170,9 +171,11 @@ void cmLocalGenerator::GenerateTestFiles()
 
   fout << "# CMake generated Testfile for " << std::endl
        << "# Source directory: "
-       << this->StateSnapshot.GetCurrentSourceDirectory() << std::endl
+       << this->StateSnapshot.GetDirectory().GetCurrentSource()
+       << std::endl
        << "# Build directory: "
-       << this->StateSnapshot.GetCurrentBinaryDirectory() << std::endl
+       << this->StateSnapshot.GetDirectory().GetCurrentBinary()
+       << std::endl
        << "# " << std::endl
        << "# This file includes the relevant testing commands "
        << "required for " << std::endl
@@ -286,7 +289,8 @@ void cmLocalGenerator::GenerateInstallRules()
     }
 
   // Create the install script file.
-  std::string file = this->StateSnapshot.GetCurrentBinaryDirectory();
+  std::string file =
+      this->StateSnapshot.GetDirectory().GetCurrentBinary();
   std::string homedir = this->GetState()->GetBinaryDirectory();
   int toplevel_install = 0;
   if (file == homedir)
@@ -299,7 +303,7 @@ void cmLocalGenerator::GenerateInstallRules()
 
   // Write the header.
   fout << "# Install script for directory: "
-       << this->StateSnapshot.GetCurrentSourceDirectory()
+       << this->StateSnapshot.GetDirectory().GetCurrentSource()
        << std::endl << std::endl;
   fout << "# Set the install prefix" << std::endl
        << "if(NOT DEFINED CMAKE_INSTALL_PREFIX)" << std::endl
@@ -518,7 +522,7 @@ void cmLocalGenerator::AddCustomCommandToCreateObject(const char* ofname,
     source.GetFullPath(),
     commandLines,
     comment.c_str(),
-    this->StateSnapshot.GetCurrentBinaryDirectory()
+    this->StateSnapshot.GetDirectory().GetCurrentBinary()
     );
 }
 
@@ -540,12 +544,13 @@ void cmLocalGenerator::AddBuildTargetRule(const std::string& llang,
        !sf->GetPropertyAsBool("EXTERNAL_OBJECT"))
       {
       std::string dir_max;
-      dir_max += this->StateSnapshot.GetCurrentBinaryDirectory();
+      dir_max += this->StateSnapshot.GetDirectory().GetCurrentBinary();
       dir_max += "/";
       std::string obj = this->GetObjectFileNameWithoutTarget(*sf, dir_max);
       if(!obj.empty())
         {
-        std::string ofname = this->StateSnapshot.GetCurrentBinaryDirectory();
+        std::string ofname =
+            this->StateSnapshot.GetDirectory().GetCurrentBinary();
         ofname += "/";
         ofname += obj;
         objVector.push_back(ofname);
@@ -615,7 +620,7 @@ void cmLocalGenerator::AddBuildTargetRule(const std::string& llang,
     "",
     commandLines,
     comment.c_str(),
-    this->StateSnapshot.GetCurrentBinaryDirectory()
+    this->StateSnapshot.GetDirectory().GetCurrentBinary()
     );
   this->Makefile->GetSource(targetFullPath);
   target.Target->AddSource(targetFullPath);
@@ -1369,20 +1374,20 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs,
   // Store the automatic include paths.
   if(includeBinaryDir)
     {
-    if(emitted.find(
-        this->StateSnapshot.GetCurrentBinaryDirectory()) == emitted.end())
+    std::string binDir = this->StateSnapshot.GetDirectory().GetCurrentBinary();
+    if(emitted.find(binDir) == emitted.end())
       {
-      dirs.push_back(this->StateSnapshot.GetCurrentBinaryDirectory());
-      emitted.insert(this->StateSnapshot.GetCurrentBinaryDirectory());
+      dirs.push_back(binDir);
+      emitted.insert(binDir);
       }
     }
   if(includeSourceDir)
     {
-    if(emitted.find(
-        this->StateSnapshot.GetCurrentSourceDirectory()) == emitted.end())
+    std::string srcDir = this->StateSnapshot.GetDirectory().GetCurrentSource();
+    if(emitted.find(srcDir) == emitted.end())
       {
-      dirs.push_back(this->StateSnapshot.GetCurrentSourceDirectory());
-      emitted.insert(this->StateSnapshot.GetCurrentSourceDirectory());
+      dirs.push_back(srcDir);
+      emitted.insert(srcDir);
       }
     }
 
@@ -1983,7 +1988,7 @@ bool cmLocalGenerator::GetRealDependency(const std::string& inName,
 
   // Treat the name as relative to the source directory in which it
   // was given.
-  dep = this->StateSnapshot.GetCurrentSourceDirectory();
+  dep = this->StateSnapshot.GetDirectory().GetCurrentSource();
   dep += "/";
   dep += inName;
   return true;
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index 5d17a404acc804e85e12d1da9776c3597f8b222b..fa80222910b7123d92806c7f865775e58d779228 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -530,10 +530,10 @@ void cmLocalUnixMakefileGenerator3::WriteDirectoryInformationFile()
   infoFileStream
     << "# Relative path conversion top directories.\n"
     << "set(CMAKE_RELATIVE_PATH_TOP_SOURCE \""
-    << this->StateSnapshot.GetRelativePathTopSource()
+    << this->StateSnapshot.GetDirectory().GetRelativePathTopSource()
     << "\")\n"
     << "set(CMAKE_RELATIVE_PATH_TOP_BINARY \""
-    << this->StateSnapshot.GetRelativePathTopBinary()
+    << this->StateSnapshot.GetDirectory().GetRelativePathTopBinary()
     << "\")\n"
     << "\n";
 
@@ -1602,12 +1602,14 @@ cmLocalUnixMakefileGenerator3
     if(const char* relativePathTopSource =
        mf->GetDefinition("CMAKE_RELATIVE_PATH_TOP_SOURCE"))
       {
-      this->StateSnapshot.SetRelativePathTopSource(relativePathTopSource);
+      this->StateSnapshot.GetDirectory()
+            .SetRelativePathTopSource(relativePathTopSource);
       }
     if(const char* relativePathTopBinary =
        mf->GetDefinition("CMAKE_RELATIVE_PATH_TOP_BINARY"))
       {
-      this->StateSnapshot.SetRelativePathTopBinary(relativePathTopBinary);
+      this->StateSnapshot.GetDirectory()
+            .SetRelativePathTopBinary(relativePathTopBinary);
       }
     }
   else
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 94c77e13eb0768a759322fb80a1d262b5b555b5a..0432002531d8519b78c1a25331e748a71c28c7e7 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -1704,7 +1704,7 @@ public:
     : Makefile(mf), ReportError(true)
   {
     std::string currentStart =
-        this->Makefile->StateSnapshot.GetCurrentSourceDirectory();
+        this->Makefile->StateSnapshot.GetDirectory().GetCurrentSource();
     currentStart += "/CMakeLists.txt";
     this->Makefile->StateSnapshot.SetListFile(currentStart);
     this->Makefile->ListFileStack.push_back(currentStart);
@@ -1748,11 +1748,12 @@ void cmMakefile::Configure()
   BuildsystemFileScope scope(this);
 
   // make sure the CMakeFiles dir is there
-  std::string filesDir = this->StateSnapshot.GetCurrentBinaryDirectory();
+  std::string filesDir = this->StateSnapshot.GetDirectory().GetCurrentBinary();
   filesDir += cmake::GetCMakeFilesDirectory();
   cmSystemTools::MakeDirectory(filesDir.c_str());
 
-  std::string currentStart = this->StateSnapshot.GetCurrentSourceDirectory();
+  std::string currentStart =
+      this->StateSnapshot.GetDirectory().GetCurrentSource();
   currentStart += "/CMakeLists.txt";
   assert(cmSystemTools::FileExists(currentStart.c_str(), true));
   this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentStart.c_str());
@@ -1884,27 +1885,27 @@ void cmMakefile::AddSubDirectory(const std::string& srcPath,
 
 void cmMakefile::SetCurrentSourceDirectory(const std::string& dir)
 {
-  this->StateSnapshot.SetCurrentSourceDirectory(dir);
+  this->StateSnapshot.GetDirectory().SetCurrentSource(dir);
   this->AddDefinition("CMAKE_CURRENT_SOURCE_DIR",
-                      this->StateSnapshot.GetCurrentSourceDirectory());
+                      this->StateSnapshot.GetDirectory().GetCurrentSource());
 }
 
 const char* cmMakefile::GetCurrentSourceDirectory() const
 {
-  return this->StateSnapshot.GetCurrentSourceDirectory();
+  return this->StateSnapshot.GetDirectory().GetCurrentSource();
 }
 
 void cmMakefile::SetCurrentBinaryDirectory(const std::string& dir)
 {
-  this->StateSnapshot.SetCurrentBinaryDirectory(dir);
-  const char* binDir = this->StateSnapshot.GetCurrentBinaryDirectory();
+  this->StateSnapshot.GetDirectory().SetCurrentBinary(dir);
+  const char* binDir = this->StateSnapshot.GetDirectory().GetCurrentBinary();
   cmSystemTools::MakeDirectory(binDir);
   this->AddDefinition("CMAKE_CURRENT_BINARY_DIR", binDir);
 }
 
 const char* cmMakefile::GetCurrentBinaryDirectory() const
 {
-  return this->StateSnapshot.GetCurrentBinaryDirectory();
+  return this->StateSnapshot.GetDirectory().GetCurrentBinary();
 }
 
 //----------------------------------------------------------------------------
@@ -4271,7 +4272,7 @@ const char *cmMakefile::GetProperty(const std::string& prop,
         this->StateSnapshot.GetBuildsystemDirectoryParent();
     if(parent.IsValid())
       {
-      return parent.GetCurrentSourceDirectory();
+      return parent.GetDirectory().GetCurrentSource();
       }
     return "";
     }
diff --git a/Source/cmOutputConverter.cxx b/Source/cmOutputConverter.cxx
index 7cd6a47b5f5a8288d68ddecc57165f5357098f4f..91f3c0ad54433246f00c809f13fea9628d2f7d8e 100644
--- a/Source/cmOutputConverter.cxx
+++ b/Source/cmOutputConverter.cxx
@@ -81,11 +81,15 @@ const char* cmOutputConverter::GetRelativeRootPath(RelativeRoot relroot) const
 {
   switch (relroot)
     {
-    case HOME:         return this->GetState()->GetSourceDirectory();
-    case START:        return this->StateSnapshot.GetCurrentSourceDirectory();
-    case HOME_OUTPUT:  return this->GetState()->GetBinaryDirectory();
-    case START_OUTPUT: return this->StateSnapshot.GetCurrentBinaryDirectory();
-    default: break;
+  case HOME:
+    return this->GetState()->GetSourceDirectory();
+  case START:
+    return this->StateSnapshot.GetDirectory().GetCurrentSource();
+  case HOME_OUTPUT:
+    return this->GetState()->GetBinaryDirectory();
+  case START_OUTPUT:
+    return this->StateSnapshot.GetDirectory().GetCurrentBinary();
+  default: break;
     }
   return 0;
 }
@@ -105,7 +109,8 @@ std::string cmOutputConverter::Convert(const std::string& source,
     break;
   case START:
     result = this->ConvertToRelativePath(
-          this->StateSnapshot.GetCurrentSourceDirectoryComponents(), result);
+          this->StateSnapshot.GetDirectory().GetCurrentSourceComponents(),
+          result);
     break;
   case HOME_OUTPUT:
     result = this->ConvertToRelativePath(
@@ -113,7 +118,8 @@ std::string cmOutputConverter::Convert(const std::string& source,
     break;
   case START_OUTPUT:
     result = this->ConvertToRelativePath(
-          this->StateSnapshot.GetCurrentBinaryDirectoryComponents(), result);
+          this->StateSnapshot.GetDirectory().GetCurrentBinaryComponents(),
+          result);
     break;
   case FULL:
     result = cmSystemTools::CollapseFullPath(result);
@@ -213,13 +219,13 @@ cmOutputConverter::ConvertToRelativePath(const std::vector<std::string>& local,
     // or both in the binary tree.
     std::string local_path = cmSystemTools::JoinPath(local);
     if(!((cmOutputConverterNotAbove(local_path.c_str(),
-              this->StateSnapshot.GetRelativePathTopBinary()) &&
-          cmOutputConverterNotAbove(in_remote.c_str(),
-              this->StateSnapshot.GetRelativePathTopBinary())) ||
-         (cmOutputConverterNotAbove(local_path.c_str(),
-              this->StateSnapshot.GetRelativePathTopSource()) &&
-          cmOutputConverterNotAbove(in_remote.c_str(),
-              this->StateSnapshot.GetRelativePathTopSource()))))
+              this->StateSnapshot.GetDirectory().GetRelativePathTopBinary())
+          && cmOutputConverterNotAbove(in_remote.c_str(),
+              this->StateSnapshot.GetDirectory().GetRelativePathTopBinary()))
+         || (cmOutputConverterNotAbove(local_path.c_str(),
+              this->StateSnapshot.GetDirectory().GetRelativePathTopSource())
+             && cmOutputConverterNotAbove(in_remote.c_str(),
+              this->StateSnapshot.GetDirectory().GetRelativePathTopSource()))))
       {
       return in_remote;
       }
diff --git a/Source/cmState.cxx b/Source/cmState.cxx
index 2d8b935309cb3876edd07b9c761a70314e5cad95..fdafd4c36976c51841455ea5849efcc9f7d965f1 100644
--- a/Source/cmState.cxx
+++ b/Source/cmState.cxx
@@ -611,13 +611,13 @@ std::vector<std::string> const& cmState::GetBinaryDirectoryComponents() const
   return this->BinaryDirectoryComponents;
 }
 
-void cmState::Snapshot::ComputeRelativePathTopSource()
+void cmState::Directory::ComputeRelativePathTopSource()
 {
   // Relative path conversion inside the source tree is not used to
   // construct relative paths passed to build tools so it is safe to use
   // even when the source is a network path.
 
-  cmState::Snapshot snapshot = *this;
+  cmState::Snapshot snapshot = this->Snapshot_;
   std::vector<cmState::Snapshot> snapshots;
   snapshots.push_back(snapshot);
   while (true)
@@ -633,23 +633,23 @@ void cmState::Snapshot::ComputeRelativePathTopSource()
       }
     }
 
-  std::string result = snapshots.front().GetCurrentSourceDirectory();
+  std::string result = snapshots.front().GetDirectory().GetCurrentSource();
 
   for (std::vector<cmState::Snapshot>::const_iterator it =
        snapshots.begin() + 1; it != snapshots.end(); ++it)
     {
-    std::string currentSource = it->GetCurrentSourceDirectory();
+    std::string currentSource = it->GetDirectory().GetCurrentSource();
     if(cmSystemTools::IsSubDirectory(result, currentSource))
       {
       result = currentSource;
       }
     }
-  this->Position->BuildSystemDirectory->RelativePathTopSource = result;
+  this->DirectoryState->RelativePathTopSource = result;
 }
 
-void cmState::Snapshot::ComputeRelativePathTopBinary()
+void cmState::Directory::ComputeRelativePathTopBinary()
 {
-  cmState::Snapshot snapshot = *this;
+  cmState::Snapshot snapshot = this->Snapshot_;
   std::vector<cmState::Snapshot> snapshots;
   snapshots.push_back(snapshot);
   while (true)
@@ -666,12 +666,12 @@ void cmState::Snapshot::ComputeRelativePathTopBinary()
     }
 
   std::string result =
-      snapshots.front().GetCurrentBinaryDirectory();
+      snapshots.front().GetDirectory().GetCurrentBinary();
 
   for (std::vector<cmState::Snapshot>::const_iterator it =
        snapshots.begin() + 1; it != snapshots.end(); ++it)
     {
-    std::string currentBinary = it->GetCurrentBinaryDirectory();
+    std::string currentBinary = it->GetDirectory().GetCurrentBinary();
     if(cmSystemTools::IsSubDirectory(result, currentBinary))
       {
       result = currentBinary;
@@ -683,11 +683,11 @@ void cmState::Snapshot::ComputeRelativePathTopBinary()
   // is a network path.
   if(result.size() < 2 || result.substr(0, 2) != "//")
     {
-    this->Position->BuildSystemDirectory->RelativePathTopBinary = result;
+    this->DirectoryState->RelativePathTopBinary = result;
     }
   else
     {
-    this->Position->BuildSystemDirectory->RelativePathTopBinary = "";
+    this->DirectoryState->RelativePathTopBinary = "";
     }
 }
 
@@ -812,40 +812,39 @@ cmState::Snapshot::Snapshot(cmState* state, PositionType position)
 
 }
 
-const char* cmState::Snapshot::GetCurrentSourceDirectory() const
+const char* cmState::Directory::GetCurrentSource() const
 {
-  return this->Position->BuildSystemDirectory->Location.c_str();
+  return this->DirectoryState->Location.c_str();
 }
 
-void cmState::Snapshot::SetCurrentSourceDirectory(std::string const& dir)
+void cmState::Directory::SetCurrentSource(std::string const& dir)
 {
-  assert(this->State);
-  std::string& loc = this->Position->BuildSystemDirectory->Location;
+  std::string& loc = this->DirectoryState->Location;
   loc = dir;
   cmSystemTools::ConvertToUnixSlashes(loc);
   loc = cmSystemTools::CollapseFullPath(loc);
 
   cmSystemTools::SplitPath(
       loc,
-      this->Position->BuildSystemDirectory->CurrentSourceDirectoryComponents);
+      this->DirectoryState->CurrentSourceDirectoryComponents);
   this->ComputeRelativePathTopSource();
 }
 
-const char* cmState::Snapshot::GetCurrentBinaryDirectory() const
+const char* cmState::Directory::GetCurrentBinary() const
 {
-  return this->Position->BuildSystemDirectory->OutputLocation.c_str();
+  return this->DirectoryState->OutputLocation.c_str();
 }
 
-void cmState::Snapshot::SetCurrentBinaryDirectory(std::string const& dir)
+void cmState::Directory::SetCurrentBinary(std::string const& dir)
 {
-  std::string& loc = this->Position->BuildSystemDirectory->OutputLocation;
+  std::string& loc = this->DirectoryState->OutputLocation;
   loc = dir;
   cmSystemTools::ConvertToUnixSlashes(loc);
   loc = cmSystemTools::CollapseFullPath(loc);
 
   cmSystemTools::SplitPath(
       loc,
-      this->Position->BuildSystemDirectory->CurrentBinaryDirectoryComponents);
+      this->DirectoryState->CurrentBinaryDirectoryComponents);
   this->ComputeRelativePathTopBinary();
 }
 
@@ -855,37 +854,35 @@ void cmState::Snapshot::SetListFile(const std::string& listfile)
 }
 
 std::vector<std::string> const&
-cmState::Snapshot::GetCurrentSourceDirectoryComponents() const
+cmState::Directory::GetCurrentSourceComponents() const
 {
-  return this->Position->BuildSystemDirectory
-      ->CurrentSourceDirectoryComponents;
+  return this->DirectoryState->CurrentSourceDirectoryComponents;
 }
 
 std::vector<std::string> const&
-cmState::Snapshot::GetCurrentBinaryDirectoryComponents() const
+cmState::Directory::GetCurrentBinaryComponents() const
 {
-  return this->Position->BuildSystemDirectory
-      ->CurrentBinaryDirectoryComponents;
+  return this->DirectoryState->CurrentBinaryDirectoryComponents;
 }
 
-const char* cmState::Snapshot::GetRelativePathTopSource() const
+const char* cmState::Directory::GetRelativePathTopSource() const
 {
-  return this->Position->BuildSystemDirectory->RelativePathTopSource.c_str();
+  return this->DirectoryState->RelativePathTopSource.c_str();
 }
 
-const char* cmState::Snapshot::GetRelativePathTopBinary() const
+const char* cmState::Directory::GetRelativePathTopBinary() const
 {
-  return this->Position->BuildSystemDirectory->RelativePathTopBinary.c_str();
+  return this->DirectoryState->RelativePathTopBinary.c_str();
 }
 
-void cmState::Snapshot::SetRelativePathTopSource(const char* dir)
+void cmState::Directory::SetRelativePathTopSource(const char* dir)
 {
-  this->Position->BuildSystemDirectory->RelativePathTopSource = dir;
+  this->DirectoryState->RelativePathTopSource = dir;
 }
 
-void cmState::Snapshot::SetRelativePathTopBinary(const char* dir)
+void cmState::Directory::SetRelativePathTopBinary(const char* dir)
 {
-  this->Position->BuildSystemDirectory->RelativePathTopBinary = dir;
+  this->DirectoryState->RelativePathTopBinary = dir;
 }
 
 std::string cmState::Snapshot::GetExecutionListFile() const
@@ -952,3 +949,16 @@ cmState* cmState::Snapshot::GetState() const
 {
   return this->State;
 }
+
+cmState::Directory cmState::Snapshot::GetDirectory() const
+{
+  return Directory(this->Position->BuildSystemDirectory, *this);
+}
+
+cmState::Directory::Directory(
+    cmLinkedTree<BuildsystemDirectoryStateType>::iterator iter,
+    const cmState::Snapshot& snapshot)
+  : DirectoryState(iter), Snapshot_(snapshot)
+{
+
+}
diff --git a/Source/cmState.h b/Source/cmState.h
index 15a619221b0e5d10926b1651a4276382bebfc306..acd23a529c4e223341dd0b84763387cb86158ce6 100644
--- a/Source/cmState.h
+++ b/Source/cmState.h
@@ -39,27 +39,14 @@ public:
     InlineListFileType
   };
 
+  class Directory;
+
   class Snapshot {
   public:
     Snapshot(cmState* state = 0, PositionType position = PositionType());
 
-    const char* GetCurrentSourceDirectory() const;
-    void SetCurrentSourceDirectory(std::string const& dir);
-    const char* GetCurrentBinaryDirectory() const;
-    void SetCurrentBinaryDirectory(std::string const& dir);
-
     void SetListFile(std::string const& listfile);
 
-    std::vector<std::string> const&
-    GetCurrentSourceDirectoryComponents() const;
-    std::vector<std::string> const&
-    GetCurrentBinaryDirectoryComponents() const;
-
-    const char* GetRelativePathTopSource() const;
-    const char* GetRelativePathTopBinary() const;
-    void SetRelativePathTopSource(const char* dir);
-    void SetRelativePathTopBinary(const char* dir);
-
     std::string GetExecutionListFile() const;
     std::string GetEntryPointCommand() const;
     long GetEntryPointLine() const;
@@ -70,16 +57,45 @@ public:
 
     cmState* GetState() const;
 
-  private:
-    void ComputeRelativePathTopSource();
-    void ComputeRelativePathTopBinary();
+    Directory GetDirectory() const;
 
   private:
     friend class cmState;
+    friend class Directory;
     cmState* State;
     cmState::PositionType Position;
   };
 
+  class Directory
+  {
+    Directory(cmLinkedTree<BuildsystemDirectoryStateType>::iterator iter,
+              Snapshot const& snapshot);
+  public:
+    const char* GetCurrentSource() const;
+    void SetCurrentSource(std::string const& dir);
+    const char* GetCurrentBinary() const;
+    void SetCurrentBinary(std::string const& dir);
+
+    std::vector<std::string> const&
+    GetCurrentSourceComponents() const;
+    std::vector<std::string> const&
+    GetCurrentBinaryComponents() const;
+
+    const char* GetRelativePathTopSource() const;
+    const char* GetRelativePathTopBinary() const;
+    void SetRelativePathTopSource(const char* dir);
+    void SetRelativePathTopBinary(const char* dir);
+
+  private:
+    void ComputeRelativePathTopSource();
+    void ComputeRelativePathTopBinary();
+
+  private:
+    cmLinkedTree<BuildsystemDirectoryStateType>::iterator DirectoryState;
+    Snapshot Snapshot_;
+    friend class Snapshot;
+  };
+
   Snapshot CreateBaseSnapshot();
   Snapshot
   CreateBuildsystemDirectorySnapshot(Snapshot originSnapshot,