diff --git a/tools/CIndex/CIndex.cpp b/tools/CIndex/CIndex.cpp
index 3cb15f6..2b33a63 100644
--- a/tools/CIndex/CIndex.cpp
+++ b/tools/CIndex/CIndex.cpp
@@ -7,49 +7,23 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// This file implements the Clang-C Source Indexing library.
+// This file implements the main API hooks in the Clang-C Source Indexing
+// library.
 //
 //===----------------------------------------------------------------------===//
 
-#include "clang-c/Index.h"
-#include "clang/AST/Decl.h"
+#include "CIndexer.h"
+
 #include "clang/AST/DeclVisitor.h"
 #include "clang/AST/StmtVisitor.h"
-#include "clang/Basic/FileManager.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/Version.h"
-#include "clang/Frontend/ASTUnit.h"
-#include "clang/Frontend/CompilerInstance.h"
-#include "clang/Index/ASTLocation.h"
-#include "clang/Index/Indexer.h"
-#include "clang/Index/Program.h"
-#include "clang/Index/Utils.h"
-#include "clang/Sema/CodeCompleteConsumer.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/Config/config.h"
-#include "llvm/Support/Compiler.h"
 #include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Path.h"
 #include "llvm/System/Program.h"
 
-#include <cstdio>
-#include <vector>
-#include <sstream>
-
-#ifdef LLVM_ON_WIN32
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#else
-#include <dlfcn.h>
-#endif
-
 using namespace clang;
 using namespace idx;
 
 namespace {
-static enum CXCursorKind TranslateDeclRefExpr(DeclRefExpr *DRE)
-{
+static enum CXCursorKind TranslateDeclRefExpr(DeclRefExpr *DRE) {
   NamedDecl *D = DRE->getDecl();
   if (isa<VarDecl>(D))
     return CXCursor_VarRef;
@@ -97,14 +71,6 @@
 };
 #endif
 
-/// IgnoreDiagnosticsClient - A DiagnosticsClient that just ignores emitted
-/// warnings and errors.
-class VISIBILITY_HIDDEN IgnoreDiagnosticsClient : public DiagnosticClient {
-public:
-  virtual ~IgnoreDiagnosticsClient() {}
-  virtual void HandleDiagnostic(Diagnostic::Level, const DiagnosticInfo &) {}
-};
-
 // Translation Unit Visitor.
 class TUVisitor : public DeclVisitor<TUVisitor> {
   CXTranslationUnit TUnit;
@@ -291,113 +257,7 @@
                                   : CXCursor_ObjCClassMethodDecl, ND);
   }
 };
-
-class CIndexer : public Indexer {
-  DiagnosticOptions DiagOpts;
-  IgnoreDiagnosticsClient IgnoreDiagClient;
-  llvm::OwningPtr<Diagnostic> TextDiags;
-  Diagnostic IgnoreDiags;
-  bool UseExternalASTGeneration;
-  bool OnlyLocalDecls;
-  bool DisplayDiagnostics;
-
-  llvm::sys::Path ClangPath;
-
-public:
-  explicit CIndexer(Program *prog) : Indexer(*prog),
-                                     IgnoreDiags(&IgnoreDiagClient),
-                                     UseExternalASTGeneration(false),
-                                     OnlyLocalDecls(false),
-                                     DisplayDiagnostics(false) {
-    TextDiags.reset(
-      CompilerInstance::createDiagnostics(DiagOpts, 0, 0));
-  }
-
-  virtual ~CIndexer() { delete &getProgram(); }
-
-  /// \brief Whether we only want to see "local" declarations (that did not
-  /// come from a previous precompiled header). If false, we want to see all
-  /// declarations.
-  bool getOnlyLocalDecls() const { return OnlyLocalDecls; }
-  void setOnlyLocalDecls(bool Local = true) { OnlyLocalDecls = Local; }
-
-  bool getDisplayDiagnostics() const { return DisplayDiagnostics; }
-  void setDisplayDiagnostics(bool Display = true) {
-    DisplayDiagnostics = Display;
-  }
-
-  bool getUseExternalASTGeneration() const { return UseExternalASTGeneration; }
-  void setUseExternalASTGeneration(bool Value) {
-    UseExternalASTGeneration = Value;
-  }
-
-  Diagnostic &getDiags() {
-    return DisplayDiagnostics ? *TextDiags : IgnoreDiags;
-  }
-
-  /// \brief Get the path of the clang binary.
-  const llvm::sys::Path& getClangPath();
-
-  /// \brief Get the path of the clang resource files.
-  std::string getClangResourcesPath();
-};
-
-const llvm::sys::Path& CIndexer::getClangPath() {
-  // Did we already compute the path?
-  if (!ClangPath.empty())
-    return ClangPath;
-
-  // Find the location where this library lives (libCIndex.dylib).
-#ifdef LLVM_ON_WIN32
-  MEMORY_BASIC_INFORMATION mbi;
-  char path[MAX_PATH];
-  VirtualQuery((void *)(uintptr_t)clang_createTranslationUnit, &mbi,
-               sizeof(mbi));
-  GetModuleFileNameA((HINSTANCE)mbi.AllocationBase, path, MAX_PATH);
-
-  llvm::sys::Path CIndexPath(path);
-
-  CIndexPath.eraseComponent();
-  CIndexPath.appendComponent("clang");
-  CIndexPath.appendSuffix("exe");
-  CIndexPath.makeAbsolute();
-#else
-  // This silly cast below avoids a C++ warning.
-  Dl_info info;
-  if (dladdr((void *)(uintptr_t)clang_createTranslationUnit, &info) == 0)
-    assert(0 && "Call to dladdr() failed");
-
-  llvm::sys::Path CIndexPath(info.dli_fname);
-
-  // We now have the CIndex directory, locate clang relative to it.
-  CIndexPath.eraseComponent();
-  CIndexPath.eraseComponent();
-  CIndexPath.appendComponent("bin");
-  CIndexPath.appendComponent("clang");
-#endif
-
-  // Cache our result.
-  ClangPath = CIndexPath;
-  return ClangPath;
-}
-
-std::string CIndexer::getClangResourcesPath() {
-  llvm::sys::Path P = getClangPath();
-
-  if (!P.empty()) {
-    P.eraseComponent();  // Remove /clang from foo/bin/clang
-    P.eraseComponent();  // Remove /bin   from foo/bin
-
-    // Get foo/lib/clang/<version>/include
-    P.appendComponent("lib");
-    P.appendComponent("clang");
-    P.appendComponent(CLANG_VERSION_STRING);
-  }
-
-  return P.str();
-}
-
-}
+} // end anonymous namespace
 
 static SourceLocation getLocationFromCursor(CXCursor C,
                                             SourceManager &SourceMgr,
@@ -1096,330 +956,4 @@
   *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
 }
 
-enum CXCompletionChunkKind
-clang_getCompletionChunkKind(CXCompletionString completion_string,
-                             unsigned chunk_number) {
-  CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
-  if (!CCStr || chunk_number >= CCStr->size())
-    return CXCompletionChunk_Text;
-
-  switch ((*CCStr)[chunk_number].Kind) {
-  case CodeCompletionString::CK_TypedText:
-    return CXCompletionChunk_TypedText;
-  case CodeCompletionString::CK_Text:
-    return CXCompletionChunk_Text;
-  case CodeCompletionString::CK_Optional:
-    return CXCompletionChunk_Optional;
-  case CodeCompletionString::CK_Placeholder:
-    return CXCompletionChunk_Placeholder;
-  case CodeCompletionString::CK_Informative:
-    return CXCompletionChunk_Informative;
-  case CodeCompletionString::CK_ResultType:
-    return CXCompletionChunk_ResultType;
-  case CodeCompletionString::CK_CurrentParameter:
-    return CXCompletionChunk_CurrentParameter;
-  case CodeCompletionString::CK_LeftParen:
-    return CXCompletionChunk_LeftParen;
-  case CodeCompletionString::CK_RightParen:
-    return CXCompletionChunk_RightParen;
-  case CodeCompletionString::CK_LeftBracket:
-    return CXCompletionChunk_LeftBracket;
-  case CodeCompletionString::CK_RightBracket:
-    return CXCompletionChunk_RightBracket;
-  case CodeCompletionString::CK_LeftBrace:
-    return CXCompletionChunk_LeftBrace;
-  case CodeCompletionString::CK_RightBrace:
-    return CXCompletionChunk_RightBrace;
-  case CodeCompletionString::CK_LeftAngle:
-    return CXCompletionChunk_LeftAngle;
-  case CodeCompletionString::CK_RightAngle:
-    return CXCompletionChunk_RightAngle;
-  case CodeCompletionString::CK_Comma:
-    return CXCompletionChunk_Comma;
-  }
-
-  // Should be unreachable, but let's be careful.
-  return CXCompletionChunk_Text;
-}
-
-const char *clang_getCompletionChunkText(CXCompletionString completion_string,
-                                         unsigned chunk_number) {
-  CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
-  if (!CCStr || chunk_number >= CCStr->size())
-    return 0;
-
-  switch ((*CCStr)[chunk_number].Kind) {
-  case CodeCompletionString::CK_TypedText:
-  case CodeCompletionString::CK_Text:
-  case CodeCompletionString::CK_Placeholder:
-  case CodeCompletionString::CK_CurrentParameter:
-  case CodeCompletionString::CK_Informative:
-  case CodeCompletionString::CK_LeftParen:
-  case CodeCompletionString::CK_RightParen:
-  case CodeCompletionString::CK_LeftBracket:
-  case CodeCompletionString::CK_RightBracket:
-  case CodeCompletionString::CK_LeftBrace:
-  case CodeCompletionString::CK_RightBrace:
-  case CodeCompletionString::CK_LeftAngle:
-  case CodeCompletionString::CK_RightAngle:
-  case CodeCompletionString::CK_Comma:
-  case CodeCompletionString::CK_ResultType:
-    return (*CCStr)[chunk_number].Text;
-
-  case CodeCompletionString::CK_Optional:
-    // Note: treated as an empty text block.
-    return "";
-  }
-
-  // Should be unreachable, but let's be careful.
-  return 0;
-}
-
-CXCompletionString
-clang_getCompletionChunkCompletionString(CXCompletionString completion_string,
-                                         unsigned chunk_number) {
-  CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
-  if (!CCStr || chunk_number >= CCStr->size())
-    return 0;
-
-  switch ((*CCStr)[chunk_number].Kind) {
-  case CodeCompletionString::CK_TypedText:
-  case CodeCompletionString::CK_Text:
-  case CodeCompletionString::CK_Placeholder:
-  case CodeCompletionString::CK_CurrentParameter:
-  case CodeCompletionString::CK_Informative:
-  case CodeCompletionString::CK_LeftParen:
-  case CodeCompletionString::CK_RightParen:
-  case CodeCompletionString::CK_LeftBracket:
-  case CodeCompletionString::CK_RightBracket:
-  case CodeCompletionString::CK_LeftBrace:
-  case CodeCompletionString::CK_RightBrace:
-  case CodeCompletionString::CK_LeftAngle:
-  case CodeCompletionString::CK_RightAngle:
-  case CodeCompletionString::CK_Comma:
-  case CodeCompletionString::CK_ResultType:
-    return 0;
-
-  case CodeCompletionString::CK_Optional:
-    // Note: treated as an empty text block.
-    return (*CCStr)[chunk_number].Optional;
-  }
-
-  // Should be unreachable, but let's be careful.
-  return 0;
-}
-
-unsigned clang_getNumCompletionChunks(CXCompletionString completion_string) {
-  CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
-  return CCStr? CCStr->size() : 0;
-}
-
-static bool ReadUnsigned(const char *&Memory, const char *MemoryEnd,
-                         unsigned &Value) {
-  if (Memory + sizeof(unsigned) > MemoryEnd)
-    return true;
-
-  memmove(&Value, Memory, sizeof(unsigned));
-  Memory += sizeof(unsigned);
-  return false;
-}
-
-/// \brief The CXCodeCompleteResults structure we allocate internally;
-/// the client only sees the initial CXCodeCompleteResults structure.
-struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {
-  /// \brief The memory buffer from which we parsed the results. We
-  /// retain this buffer because the completion strings point into it.
-  llvm::MemoryBuffer *Buffer;
-};
-
-CXCodeCompleteResults *clang_codeComplete(CXIndex CIdx,
-                                          const char *source_filename,
-                                          int num_command_line_args,
-                                          const char **command_line_args,
-                                          unsigned num_unsaved_files,
-                                          struct CXUnsavedFile *unsaved_files,
-                                          const char *complete_filename,
-                                          unsigned complete_line,
-                                          unsigned complete_column) {
-  // The indexer, which is mainly used to determine where diagnostics go.
-  CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
-
-  // The set of temporary files that we've built.
-  std::vector<llvm::sys::Path> TemporaryFiles;
-
-  // Build up the arguments for invoking 'clang'.
-  std::vector<const char *> argv;
-
-  // First add the complete path to the 'clang' executable.
-  llvm::sys::Path ClangPath = CXXIdx->getClangPath();
-  argv.push_back(ClangPath.c_str());
-
-  // Add the '-fsyntax-only' argument so that we only perform a basic
-  // syntax check of the code.
-  argv.push_back("-fsyntax-only");
-
-  // Add the appropriate '-code-completion-at=file:line:column' argument
-  // to perform code completion, with an "-Xclang" preceding it.
-  std::string code_complete_at;
-  code_complete_at += complete_filename;
-  code_complete_at += ":";
-  code_complete_at += llvm::utostr(complete_line);
-  code_complete_at += ":";
-  code_complete_at += llvm::utostr(complete_column);
-  argv.push_back("-Xclang");
-  argv.push_back("-code-completion-at");
-  argv.push_back("-Xclang");
-  argv.push_back(code_complete_at.c_str());
-  argv.push_back("-Xclang");
-  argv.push_back("-no-code-completion-debug-printer");
-  argv.push_back("-Xclang");
-  argv.push_back("-code-completion-macros");
-  
-  std::vector<std::string> RemapArgs;
-  for (unsigned i = 0; i != num_unsaved_files; ++i) {
-    char tmpFile[L_tmpnam];
-    char *tmpFileName = tmpnam(tmpFile);
-
-    // Write the contents of this unsaved file into the temporary file.
-    llvm::sys::Path SavedFile(tmpFileName);
-    std::string ErrorInfo;
-    llvm::raw_fd_ostream OS(SavedFile.c_str(), ErrorInfo);
-    if (!ErrorInfo.empty())
-      continue;
-    
-    OS.write(unsaved_files[i].Contents, unsaved_files[i].Length);
-    OS.close();
-    if (OS.has_error()) {
-      SavedFile.eraseFromDisk();
-      continue;
-    }
-
-    // Remap the file.
-    std::string RemapArg = unsaved_files[i].Filename;
-    RemapArg += ';';
-    RemapArg += tmpFileName;
-    RemapArgs.push_back("-Xclang");
-    RemapArgs.push_back("-remap-file");
-    RemapArgs.push_back("-Xclang");
-    RemapArgs.push_back(RemapArg);
-    TemporaryFiles.push_back(SavedFile);
-  }
-
-  // The pointers into the elements of RemapArgs are stable because we
-  // won't be adding anything to RemapArgs after this point.
-  for (unsigned i = 0, e = RemapArgs.size(); i != e; ++i)
-    argv.push_back(RemapArgs[i].c_str());
-
-  // Add the source file name (FIXME: later, we'll want to build temporary
-  // file from the buffer, or just feed the source text via standard input).
-  if (source_filename)
-    argv.push_back(source_filename);
-
-  // Process the compiler options, stripping off '-o', '-c', '-fsyntax-only'.
-  for (int i = 0; i < num_command_line_args; ++i)
-    if (const char *arg = command_line_args[i]) {
-      if (strcmp(arg, "-o") == 0) {
-        ++i; // Also skip the matching argument.
-        continue;
-      }
-      if (strcmp(arg, "-emit-ast") == 0 ||
-          strcmp(arg, "-c") == 0 ||
-          strcmp(arg, "-fsyntax-only") == 0) {
-        continue;
-      }
-
-      // Keep the argument.
-      argv.push_back(arg);
-    }
-
-  // Add the null terminator.
-  argv.push_back(NULL);
-
-  // Generate a temporary name for the AST file.
-  char tmpFile[L_tmpnam];
-  char *tmpFileName = tmpnam(tmpFile);
-  llvm::sys::Path ResultsFile(tmpFileName);
-  TemporaryFiles.push_back(ResultsFile);
-
-  // Invoke 'clang'.
-  llvm::sys::Path DevNull; // leave empty, causes redirection to /dev/null
-                           // on Unix or NUL (Windows).
-  std::string ErrMsg;
-  const llvm::sys::Path *Redirects[] = { &DevNull, &ResultsFile, &DevNull, 0 };
-  llvm::sys::Program::ExecuteAndWait(ClangPath, &argv[0], /* env */ NULL,
-                                     /* redirects */ &Redirects[0],
-                                     /* secondsToWait */ 0,
-                                     /* memoryLimits */ 0, &ErrMsg);
-
-  if (CXXIdx->getDisplayDiagnostics() && !ErrMsg.empty()) {
-    llvm::errs() << "clang_codeComplete: " << ErrMsg
-                 << '\n' << "Arguments: \n";
-    for (std::vector<const char*>::iterator I = argv.begin(), E = argv.end();
-         I!=E; ++I) {
-      if (*I)
-        llvm::errs() << ' ' << *I << '\n';
-    }
-    llvm::errs() << '\n';
-  }
-
-  // Parse the resulting source file to find code-completion results.
-  using llvm::MemoryBuffer;
-  using llvm::StringRef;
-  AllocatedCXCodeCompleteResults *Results = 0;
-  if (MemoryBuffer *F = MemoryBuffer::getFile(ResultsFile.c_str())) {
-    llvm::SmallVector<CXCompletionResult, 4> CompletionResults;
-    StringRef Buffer = F->getBuffer();
-    for (const char *Str = Buffer.data(), *StrEnd = Str + Buffer.size();
-         Str < StrEnd;) {
-      unsigned KindValue;
-      if (ReadUnsigned(Str, StrEnd, KindValue))
-        break;
-
-      CodeCompletionString *CCStr 
-        = CodeCompletionString::Deserialize(Str, StrEnd);
-      if (!CCStr)
-        continue;
-
-      if (!CCStr->empty()) {
-        // Vend the code-completion result to the caller.
-        CXCompletionResult Result;
-        Result.CursorKind = (CXCursorKind)KindValue;
-        Result.CompletionString = CCStr;
-        CompletionResults.push_back(Result);
-      }
-    };
-
-    // Allocate the results.
-    Results = new AllocatedCXCodeCompleteResults;
-    Results->Results = new CXCompletionResult [CompletionResults.size()];
-    Results->NumResults = CompletionResults.size();
-    memcpy(Results->Results, CompletionResults.data(),
-           CompletionResults.size() * sizeof(CXCompletionResult));
-    Results->Buffer = F;
-  }
-
-  for (unsigned i = 0, e = TemporaryFiles.size(); i != e; ++i)
-    TemporaryFiles[i].eraseFromDisk();
-
-  return Results;
-}
-
-void clang_disposeCodeCompleteResults(CXCodeCompleteResults *ResultsIn) {
-  if (!ResultsIn)
-    return;
-
-  AllocatedCXCodeCompleteResults *Results
-    = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn);
-
-  for (unsigned I = 0, N = Results->NumResults; I != N; ++I)
-    delete (CXCompletionString *)Results->Results[I].CompletionString;
-  delete [] Results->Results;
-
-  Results->Results = 0;
-  Results->NumResults = 0;
-  delete Results->Buffer;
-  Results->Buffer = 0;
-  delete Results;
-}
-
 } // end extern "C"
