diff --git a/Driver/SerializationTest.cpp b/Driver/SerializationTest.cpp
index 813aa7e..7bd6cd1 100644
--- a/Driver/SerializationTest.cpp
+++ b/Driver/SerializationTest.cpp
@@ -14,72 +14,44 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "ASTConsumers.h"
-#include "clang/Basic/TargetInfo.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/AST/AST.h"
 #include "clang/AST/ASTConsumer.h"
-#include "clang/AST/ASTContext.h"
 #include "clang/AST/CFG.h"
 #include "clang.h"
-#include "llvm/System/Path.h"
-#include "llvm/Support/Streams.h"
+#include "ASTConsumers.h"
+#include "TranslationUnit.h"
 #include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Bitcode/Serialize.h"
-#include "llvm/Bitcode/Deserialize.h"
+#include "llvm/ADT/scoped_ptr.h"
+#include "llvm/Support/Streams.h"
 #include <fstream>
-#include <stdio.h>
-#include <list>
 
 using namespace clang;
 
 //===----------------------------------------------------------------------===//
-// Utility classes
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-template<typename T> class Janitor {
-  T* Obj;
-public:
-  explicit Janitor(T* obj) : Obj(obj) {}
-  ~Janitor() { delete Obj; }
-  operator T*() const { return Obj; }
-  T* operator->() { return Obj; }
-};
-  
-//===----------------------------------------------------------------------===//
 // Driver code.
 //===----------------------------------------------------------------------===//
 
-class SerializationTest : public ASTConsumer {
-  ASTContext* Context;
-  Diagnostic &Diags;
-  FileManager &FMgr;
-  const LangOptions& LangOpts;
-  std::list<Decl*> Decls;
+namespace {
   
-  enum { BasicMetadataBlock = 1,
-         ASTContextBlock = 2,
-         DeclsBlock = 3 };
-
+class SerializationTest : public ASTConsumer {
+  TranslationUnit TU;
+  Diagnostic &Diags;
+  FileManager &FMgr;  
 public:  
   SerializationTest(Diagnostic &d, FileManager& fmgr, const LangOptions& LOpts)
-    : Context(NULL), Diags(d), FMgr(fmgr), LangOpts(LOpts) {};
+                    : TU(LOpts), Diags(d), FMgr(fmgr) {}
   
   ~SerializationTest();
 
   virtual void Initialize(ASTContext& context, unsigned) {
-      Context = &context;
-  }
-  
-  virtual void HandleTopLevelDecl(Decl *D) {
-    Decls.push_back(D);
-  }
+    TU.setContext(&context);
+  }  
 
+  virtual void HandleTopLevelDecl(Decl *D) {
+    TU.AddTopLevelDecl(D);
+  }
 private:
-  void Serialize(llvm::sys::Path& Filename, llvm::sys::Path& FNameDeclPrint);
-  void Deserialize(llvm::sys::Path& Filename, llvm::sys::Path& FNameDeclPrint);
+  bool Serialize(llvm::sys::Path& Filename, llvm::sys::Path& FNameDeclPrint);
+  bool Deserialize(llvm::sys::Path& Filename, llvm::sys::Path& FNameDeclPrint);
 };
   
 } // end anonymous namespace
@@ -90,241 +62,43 @@
   return new SerializationTest(Diags,FMgr,LOpts);
 }
 
-static void WritePreamble(llvm::BitstreamWriter& Stream) {
-  Stream.Emit((unsigned)'B', 8);
-  Stream.Emit((unsigned)'C', 8);
-  Stream.Emit(0xC, 4);
-  Stream.Emit(0xF, 4);
-  Stream.Emit(0xE, 4);
-  Stream.Emit(0x0, 4);
-}
 
-static bool ReadPreamble(llvm::BitstreamReader& Stream) {
-  return Stream.Read(8) != 'B' ||
-         Stream.Read(8) != 'C' ||
-         Stream.Read(4) != 0xC ||
-         Stream.Read(4) != 0xF ||
-         Stream.Read(4) != 0xE ||
-         Stream.Read(4) != 0x0;
-}
-
-void SerializationTest::Serialize(llvm::sys::Path& Filename,
+bool SerializationTest::Serialize(llvm::sys::Path& Filename,
                                   llvm::sys::Path& FNameDeclPrint) {
-  
-  // Reserve 256K for bitstream buffer.
-  std::vector<unsigned char> Buffer;
-  Buffer.reserve(256*1024);
-  
-  // Create bitstream and write preamble.    
-  llvm::BitstreamWriter Stream(Buffer);
-  WritePreamble(Stream);
-  
-  // Create serializer.
-  llvm::Serializer Sezr(Stream);
-  
-  // ===---------------------------------------------------===/
-  //      Serialize the top-level decls.
-  // ===---------------------------------------------------===/  
-  
-  Sezr.EnterBlock(DeclsBlock);
-    
-  { // Create a printer to "consume" our deserialized ASTS.
-
-    Janitor<ASTConsumer> Printer(CreateASTPrinter());
+  { 
+    // Pretty-print the decls to a temp file.
     std::ofstream DeclPP(FNameDeclPrint.c_str());
     assert (DeclPP && "Could not open file for printing out decls.");
-    Janitor<ASTConsumer> FilePrinter(CreateASTPrinter(&DeclPP));
+    llvm::scoped_ptr<ASTConsumer> FilePrinter(CreateASTPrinter(&DeclPP));
     
-    for (std::list<Decl*>::iterator I=Decls.begin(), E=Decls.end(); I!=E; ++I) {
-      llvm::cerr << "Serializing: Decl.\n";   
-      
-      // Only serialize the head of a decl chain.  The ASTConsumer interfaces
-      // provides us with each top-level decl, including those nested in
-      // a decl chain, so we may be passed decls that are already serialized.
-      if (!Sezr.isRegistered(*I)) {
-        Printer->HandleTopLevelDecl(*I);
-        FilePrinter->HandleTopLevelDecl(*I);
-        
-        if (FunctionDecl* FD = dyn_cast<FunctionDecl>(*I))
-          if (FD->getBody()) {
-            // Construct and print a CFG.
-            Janitor<CFG> cfg(CFG::buildCFG(FD->getBody()));
-            cfg->print(DeclPP);
-          }
-        
-        // Serialize the decl.
-        Sezr.EmitOwnedPtr(*I);
-      }
-    }
+    for (TranslationUnit::iterator I=TU.begin(), E=TU.end(); I!=E; ++I)
+      FilePrinter->HandleTopLevelDecl(*I);
   }
   
-  Sezr.ExitBlock();
-  
-  // ===---------------------------------------------------===/
-  //      Serialize the "Translation Unit" metadata.
-  // ===---------------------------------------------------===/
-
-  // Emit ASTContext.
-  Sezr.EnterBlock(ASTContextBlock);  
-  llvm::cerr << "Serializing: ASTContext.\n";  
-  Sezr.EmitOwnedPtr(Context);  
-  Sezr.ExitBlock();  
-  
-  
-  Sezr.EnterBlock(BasicMetadataBlock);
-
-  // Block for SourceManager and Target.  Allows easy skipping around
-  // to the Selectors during deserialization.
-  Sezr.EnterBlock();
-
-  // "Fake" emit the SourceManager.
-  llvm::cerr << "Serializing: SourceManager.\n";
-  Sezr.Emit(Context->SourceMgr);
-  
-  // Emit the Target.
-  llvm::cerr << "Serializing: Target.\n";
-  Sezr.EmitPtr(&Context->Target);
-  Sezr.EmitCStr(Context->Target.getTargetTriple());
-
-  Sezr.ExitBlock();
-
-  // Emit the Selectors.
-  llvm::cerr << "Serializing: Selectors.\n";
-  Sezr.Emit(Context->Selectors);
-  
-  // Emit the Identifier Table.
-  llvm::cerr << "Serializing: IdentifierTable.\n";  
-  Sezr.Emit(Context->Idents);
-
-  Sezr.ExitBlock();  
-  
-  // ===---------------------------------------------------===/
-  // Finalize serialization: write the bits to disk.
-  if (FILE* fp = fopen(Filename.c_str(),"wb")) {
-    fwrite((char*)&Buffer.front(), sizeof(char), Buffer.size(), fp);
-    fclose(fp);
-  }
-  else { 
-    llvm::cerr << "Error: Cannot open " << Filename.c_str() << "\n";
-    return;
-  }
-  
-  llvm::cerr << "Commited bitstream to disk: " << Filename.c_str() << "\n";
+  // Serialize the translation unit.
+  return TU.EmitBitcodeFile(Filename);
 }
 
-
-void SerializationTest::Deserialize(llvm::sys::Path& Filename,
+bool SerializationTest::Deserialize(llvm::sys::Path& Filename,
                                     llvm::sys::Path& FNameDeclPrint) {
   
-  // Create the memory buffer that contains the contents of the file.
-  
-  using llvm::MemoryBuffer;
-  
-  Janitor<MemoryBuffer> MBuffer(MemoryBuffer::getFile(Filename.c_str(),
-                                              strlen(Filename.c_str())));
-  
-  if(!MBuffer) {
-    llvm::cerr << "ERROR: Cannot read file for deserialization.\n";
-    return;
-  }
-  
-  // Check if the file is of the proper length.
-  if (MBuffer->getBufferSize() & 0x3) {
-    llvm::cerr << "ERROR: AST file length should be a multiple of 4 bytes.\n";
-    return;
-  }
-  
-  // Create the bitstream reader.
-  unsigned char *BufPtr = (unsigned char *) MBuffer->getBufferStart();
-  llvm::BitstreamReader Stream(BufPtr,BufPtr+MBuffer->getBufferSize());
-  
-  // Sniff for the signature in the bitcode file.
-  if (ReadPreamble(Stream)) {
-    llvm::cerr << "ERROR: Invalid AST-bitcode signature.\n";
-    return;
-  }
-    
-  // Create the deserializer.
-  llvm::Deserializer Dezr(Stream);
-  
-  // ===---------------------------------------------------===/
-  //      Deserialize the "Translation Unit" metadata.
-  // ===---------------------------------------------------===/
-  
-  // Skip to the BasicMetaDataBlock.  First jump to ASTContextBlock
-  // (which will appear earlier) and record its location.
-  
-  bool FoundBlock = Dezr.SkipToBlock(ASTContextBlock);
-  assert (FoundBlock);
+  // Deserialize the translation unit.
+  TranslationUnit* NewTU = TranslationUnit::ReadBitcodeFile(Filename,FMgr);
 
-  llvm::Deserializer::Location ASTContextBlockLoc =
-    Dezr.getCurrentBlockLocation();
+  if (!NewTU)
+    return false;
   
-  FoundBlock = Dezr.SkipToBlock(BasicMetadataBlock);
-  assert (FoundBlock);
-  
-  // Read the SourceManager.
-  llvm::cerr << "Deserializing: SourceManager.\n";
-  SourceManager::CreateAndRegister(Dezr,FMgr);
-
-  { // Read the TargetInfo.
-    llvm::cerr << "Deserializing: Target.\n";
-    llvm::SerializedPtrID PtrID = Dezr.ReadPtrID();
-    char* triple = Dezr.ReadCStr(NULL,0,true);
-    std::vector<std::string> triples;
-    triples.push_back(triple);
-    delete [] triple;
-    Dezr.RegisterPtr(PtrID,CreateTargetInfo(triples,&Diags));
+  { 
+    // Pretty-print the deserialized decls to a temp file.
+    std::ofstream DeclPP(FNameDeclPrint.c_str());
+    assert (DeclPP && "Could not open file for printing out decls.");
+    llvm::scoped_ptr<ASTConsumer> FilePrinter(CreateASTPrinter(&DeclPP));
+    
+    for (TranslationUnit::iterator I=NewTU->begin(), E=NewTU->end(); I!=E; ++I)
+      FilePrinter->HandleTopLevelDecl(*I);
   }
-    
-  // For Selectors, we must read the identifier table first because the
-  //  SelectorTable depends on the identifiers being already deserialized.
-  llvm::Deserializer::Location SelectorBlockLoc =
-    Dezr.getCurrentBlockLocation();
-    
-  Dezr.SkipBlock();
   
-  // Read the identifier table.
-  llvm::cerr << "Deserializing: IdentifierTable\n";
-  IdentifierTable::CreateAndRegister(Dezr);
-  
-  // Now jump back and read the selectors.
-  llvm::cerr << "Deserializing: Selectors\n";
-  Dezr.JumpTo(SelectorBlockLoc);
-  SelectorTable::CreateAndRegister(Dezr);
-  
-  // Now jump back to ASTContextBlock and read the ASTContext.
-  llvm::cerr << "Deserializing: ASTContext.\n";
-  Dezr.JumpTo(ASTContextBlockLoc);
-  Dezr.ReadOwnedPtr<ASTContext>();
-    
-  // "Rewind" the stream.  Find the block with the serialized top-level decls.
-  Dezr.Rewind();
-  FoundBlock = Dezr.SkipToBlock(DeclsBlock);
-  assert (FoundBlock);
-  llvm::Deserializer::Location DeclBlockLoc = Dezr.getCurrentBlockLocation();
-  
-  // Create a printer to "consume" our deserialized ASTS.
-  ASTConsumer* Printer = CreateASTPrinter();
-  Janitor<ASTConsumer> PrinterJanitor(Printer);  
-  std::ofstream DeclPP(FNameDeclPrint.c_str());
-  assert (DeclPP && "Could not open file for printing out decls.");
-  Janitor<ASTConsumer> FilePrinter(CreateASTPrinter(&DeclPP));
-  
-  // The remaining objects in the file are top-level decls.
-  while (!Dezr.FinishedBlock(DeclBlockLoc)) {
-    llvm::cerr << "Deserializing: Decl.\n";
-    Decl* decl = Dezr.ReadOwnedPtr<Decl>();
-    Printer->HandleTopLevelDecl(decl);
-    FilePrinter->HandleTopLevelDecl(decl);
-    
-    if (FunctionDecl* FD = dyn_cast<FunctionDecl>(decl))
-      if (FD->getBody()) {
-        // Construct and print a CFG.
-        Janitor<CFG> cfg(CFG::buildCFG(FD->getBody()));
-        cfg->print(DeclPP);
-      }
-  }
+  return true;
 }
   
 namespace {
@@ -377,14 +151,16 @@
   }
   
   // Serialize and then deserialize the ASTs.
-  Serialize(ASTFilename, FNameDeclBefore);
-  Deserialize(ASTFilename, FNameDeclAfter);
+  bool status = Serialize(ASTFilename, FNameDeclBefore);
+  assert (status && "Serialization failed.");  
+  status = Deserialize(ASTFilename, FNameDeclAfter);
+  assert (status && "Deserialization failed.");
   
   // Read both pretty-printed files and compare them.
   
   using llvm::MemoryBuffer;
   
-  Janitor<MemoryBuffer>
+  llvm::scoped_ptr<MemoryBuffer>
     MBufferSer(MemoryBuffer::getFile(FNameDeclBefore.c_str(),
                                      strlen(FNameDeclBefore.c_str())));
   
@@ -393,7 +169,7 @@
     return;
   }
   
-  Janitor<MemoryBuffer>
+  llvm::scoped_ptr<MemoryBuffer>
     MBufferDSer(MemoryBuffer::getFile(FNameDeclAfter.c_str(),
                                       strlen(FNameDeclAfter.c_str())));
   
