diff --git a/clang/lib/StaticAnalyzer/HTMLDiagnostics.cpp b/clang/lib/StaticAnalyzer/HTMLDiagnostics.cpp
new file mode 100644
index 0000000..659c32d
--- /dev/null
+++ b/clang/lib/StaticAnalyzer/HTMLDiagnostics.cpp
@@ -0,0 +1,578 @@
+//===--- HTMLDiagnostics.cpp - HTML Diagnostics for Paths ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the HTMLDiagnostics object.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/StaticAnalyzer/PathDiagnosticClients.h"
+#include "clang/StaticAnalyzer/BugReporter/PathDiagnostic.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Rewrite/Rewriter.h"
+#include "clang/Rewrite/HTMLRewrite.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Lex/Preprocessor.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/Path.h"
+
+using namespace clang;
+using namespace ento;
+
+//===----------------------------------------------------------------------===//
+// Boilerplate.
+//===----------------------------------------------------------------------===//
+
+namespace {
+
+class HTMLDiagnostics : public PathDiagnosticClient {
+  llvm::sys::Path Directory, FilePrefix;
+  bool createdDir, noDir;
+  const Preprocessor &PP;
+  std::vector<const PathDiagnostic*> BatchedDiags;
+public:
+  HTMLDiagnostics(const std::string& prefix, const Preprocessor &pp);
+
+  virtual ~HTMLDiagnostics() { FlushDiagnostics(NULL); }
+
+  virtual void FlushDiagnostics(llvm::SmallVectorImpl<std::string> *FilesMade);
+
+  virtual void HandlePathDiagnostic(const PathDiagnostic* D);
+
+  virtual llvm::StringRef getName() const {
+    return "HTMLDiagnostics";
+  }
+
+  unsigned ProcessMacroPiece(llvm::raw_ostream& os,
+                             const PathDiagnosticMacroPiece& P,
+                             unsigned num);
+
+  void HandlePiece(Rewriter& R, FileID BugFileID,
+                   const PathDiagnosticPiece& P, unsigned num, unsigned max);
+
+  void HighlightRange(Rewriter& R, FileID BugFileID, SourceRange Range,
+                      const char *HighlightStart = "<span class=\"mrange\">",
+                      const char *HighlightEnd = "</span>");
+
+  void ReportDiag(const PathDiagnostic& D,
+                  llvm::SmallVectorImpl<std::string> *FilesMade);
+};
+
+} // end anonymous namespace
+
+HTMLDiagnostics::HTMLDiagnostics(const std::string& prefix,
+                                 const Preprocessor &pp)
+  : Directory(prefix), FilePrefix(prefix), createdDir(false), noDir(false),
+    PP(pp) {
+  // All html files begin with "report"
+  FilePrefix.appendComponent("report");
+}
+
+PathDiagnosticClient*
+ento::createHTMLDiagnosticClient(const std::string& prefix,
+                                 const Preprocessor &PP) {
+  return new HTMLDiagnostics(prefix, PP);
+}
+
+//===----------------------------------------------------------------------===//
+// Report processing.
+//===----------------------------------------------------------------------===//
+
+void HTMLDiagnostics::HandlePathDiagnostic(const PathDiagnostic* D) {
+  if (!D)
+    return;
+
+  if (D->empty()) {
+    delete D;
+    return;
+  }
+
+  const_cast<PathDiagnostic*>(D)->flattenLocations();
+  BatchedDiags.push_back(D);
+}
+
+void
+HTMLDiagnostics::FlushDiagnostics(llvm::SmallVectorImpl<std::string> *FilesMade)
+{
+  while (!BatchedDiags.empty()) {
+    const PathDiagnostic* D = BatchedDiags.back();
+    BatchedDiags.pop_back();
+    ReportDiag(*D, FilesMade);
+    delete D;
+  }
+
+  BatchedDiags.clear();
+}
+
+void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D,
+                                 llvm::SmallVectorImpl<std::string> *FilesMade){
+  // Create the HTML directory if it is missing.
+  if (!createdDir) {
+    createdDir = true;
+    std::string ErrorMsg;
+    Directory.createDirectoryOnDisk(true, &ErrorMsg);
+
+    if (!Directory.isDirectory()) {
+      llvm::errs() << "warning: could not create directory '"
+                   << Directory.str() << "'\n"
+                   << "reason: " << ErrorMsg << '\n';
+
+      noDir = true;
+
+      return;
+    }
+  }
+
+  if (noDir)
+    return;
+
+  const SourceManager &SMgr = D.begin()->getLocation().getManager();
+  FileID FID;
+
+  // Verify that the entire path is from the same FileID.
+  for (PathDiagnostic::const_iterator I = D.begin(), E = D.end(); I != E; ++I) {
+    FullSourceLoc L = I->getLocation().asLocation().getInstantiationLoc();
+
+    if (FID.isInvalid()) {
+      FID = SMgr.getFileID(L);
+    } else if (SMgr.getFileID(L) != FID)
+      return; // FIXME: Emit a warning?
+
+    // Check the source ranges.
+    for (PathDiagnosticPiece::range_iterator RI=I->ranges_begin(),
+                                             RE=I->ranges_end(); RI!=RE; ++RI) {
+
+      SourceLocation L = SMgr.getInstantiationLoc(RI->getBegin());
+
+      if (!L.isFileID() || SMgr.getFileID(L) != FID)
+        return; // FIXME: Emit a warning?
+
+      L = SMgr.getInstantiationLoc(RI->getEnd());
+
+      if (!L.isFileID() || SMgr.getFileID(L) != FID)
+        return; // FIXME: Emit a warning?
+    }
+  }
+
+  if (FID.isInvalid())
+    return; // FIXME: Emit a warning?
+
+  // Create a new rewriter to generate HTML.
+  Rewriter R(const_cast<SourceManager&>(SMgr), PP.getLangOptions());
+
+  // Process the path.
+  unsigned n = D.size();
+  unsigned max = n;
+
+  for (PathDiagnostic::const_reverse_iterator I=D.rbegin(), E=D.rend();
+        I!=E; ++I, --n)
+    HandlePiece(R, FID, *I, n, max);
+
+  // Add line numbers, header, footer, etc.
+
+  // unsigned FID = R.getSourceMgr().getMainFileID();
+  html::EscapeText(R, FID);
+  html::AddLineNumbers(R, FID);
+
+  // If we have a preprocessor, relex the file and syntax highlight.
+  // We might not have a preprocessor if we come from a deserialized AST file,
+  // for example.
+
+  html::SyntaxHighlight(R, FID, PP);
+  html::HighlightMacros(R, FID, PP);
+
+  // Get the full directory name of the analyzed file.
+
+  const FileEntry* Entry = SMgr.getFileEntryForID(FID);
+
+  // This is a cludge; basically we want to append either the full
+  // working directory if we have no directory information.  This is
+  // a work in progress.
+
+  std::string DirName = "";
+
+  if (llvm::sys::path::is_relative(Entry->getName())) {
+    llvm::sys::Path P = llvm::sys::Path::GetCurrentDirectory();
+    DirName = P.str() + "/";
+  }
+
+  // Add the name of the file as an <h1> tag.
+
+  {
+    std::string s;
+    llvm::raw_string_ostream os(s);
+
+    os << "<!-- REPORTHEADER -->\n"
+      << "<h3>Bug Summary</h3>\n<table class=\"simpletable\">\n"
+          "<tr><td class=\"rowname\">File:</td><td>"
+      << html::EscapeText(DirName)
+      << html::EscapeText(Entry->getName())
+      << "</td></tr>\n<tr><td class=\"rowname\">Location:</td><td>"
+         "<a href=\"#EndPath\">line "
+      << (*D.rbegin()).getLocation().asLocation().getInstantiationLineNumber()
+      << ", column "
+      << (*D.rbegin()).getLocation().asLocation().getInstantiationColumnNumber()
+      << "</a></td></tr>\n"
+         "<tr><td class=\"rowname\">Description:</td><td>"
+      << D.getDescription() << "</td></tr>\n";
+
+    // Output any other meta data.
+
+    for (PathDiagnostic::meta_iterator I=D.meta_begin(), E=D.meta_end();
+         I!=E; ++I) {
+      os << "<tr><td></td><td>" << html::EscapeText(*I) << "</td></tr>\n";
+    }
+
+    os << "</table>\n<!-- REPORTSUMMARYEXTRA -->\n"
+          "<h3>Annotated Source Code</h3>\n";
+
+    R.InsertTextBefore(SMgr.getLocForStartOfFile(FID), os.str());
+  }
+
+  // Embed meta-data tags.
+  {
+    std::string s;
+    llvm::raw_string_ostream os(s);
+
+    const std::string& BugDesc = D.getDescription();
+    if (!BugDesc.empty())
+      os << "\n<!-- BUGDESC " << BugDesc << " -->\n";
+
+    const std::string& BugType = D.getBugType();
+    if (!BugType.empty())
+      os << "\n<!-- BUGTYPE " << BugType << " -->\n";
+
+    const std::string& BugCategory = D.getCategory();
+    if (!BugCategory.empty())
+      os << "\n<!-- BUGCATEGORY " << BugCategory << " -->\n";
+
+    os << "\n<!-- BUGFILE " << DirName << Entry->getName() << " -->\n";
+
+    os << "\n<!-- BUGLINE "
+       << D.back()->getLocation().asLocation().getInstantiationLineNumber()
+       << " -->\n";
+
+    os << "\n<!-- BUGPATHLENGTH " << D.size() << " -->\n";
+
+    // Mark the end of the tags.
+    os << "\n<!-- BUGMETAEND -->\n";
+
+    // Insert the text.
+    R.InsertTextBefore(SMgr.getLocForStartOfFile(FID), os.str());
+  }
+
+  // Add CSS, header, and footer.
+
+  html::AddHeaderFooterInternalBuiltinCSS(R, FID, Entry->getName());
+
+  // Get the rewrite buffer.
+  const RewriteBuffer *Buf = R.getRewriteBufferFor(FID);
+
+  if (!Buf) {
+    llvm::errs() << "warning: no diagnostics generated for main file.\n";
+    return;
+  }
+
+  // Create a path for the target HTML file.
+  llvm::sys::Path F(FilePrefix);
+  F.makeUnique(false, NULL);
+
+  // Rename the file with an HTML extension.
+  llvm::sys::Path H(F);
+  H.appendSuffix("html");
+  F.renamePathOnDisk(H, NULL);
+
+  std::string ErrorMsg;
+  llvm::raw_fd_ostream os(H.c_str(), ErrorMsg);
+
+  if (!ErrorMsg.empty()) {
+    llvm::errs() << "warning: could not create file '" << F.str()
+                 << "'\n";
+    return;
+  }
+
+  if (FilesMade)
+    FilesMade->push_back(llvm::sys::path::filename(H.str()));
+
+  // Emit the HTML to disk.
+  for (RewriteBuffer::iterator I = Buf->begin(), E = Buf->end(); I!=E; ++I)
+      os << *I;
+}
+
+void HTMLDiagnostics::HandlePiece(Rewriter& R, FileID BugFileID,
+                                  const PathDiagnosticPiece& P,
+                                  unsigned num, unsigned max) {
+
+  // For now, just draw a box above the line in question, and emit the
+  // warning.
+  FullSourceLoc Pos = P.getLocation().asLocation();
+
+  if (!Pos.isValid())
+    return;
+
+  SourceManager &SM = R.getSourceMgr();
+  assert(&Pos.getManager() == &SM && "SourceManagers are different!");
+  std::pair<FileID, unsigned> LPosInfo = SM.getDecomposedInstantiationLoc(Pos);
+
+  if (LPosInfo.first != BugFileID)
+    return;
+
+  const llvm::MemoryBuffer *Buf = SM.getBuffer(LPosInfo.first);
+  const char* FileStart = Buf->getBufferStart();
+
+  // Compute the column number.  Rewind from the current position to the start
+  // of the line.
+  unsigned ColNo = SM.getColumnNumber(LPosInfo.first, LPosInfo.second);
+  const char *TokInstantiationPtr =Pos.getInstantiationLoc().getCharacterData();
+  const char *LineStart = TokInstantiationPtr-ColNo;
+
+  // Compute LineEnd.
+  const char *LineEnd = TokInstantiationPtr;
+  const char* FileEnd = Buf->getBufferEnd();
+  while (*LineEnd != '\n' && LineEnd != FileEnd)
+    ++LineEnd;
+
+  // Compute the margin offset by counting tabs and non-tabs.
+  unsigned PosNo = 0;
+  for (const char* c = LineStart; c != TokInstantiationPtr; ++c)
+    PosNo += *c == '\t' ? 8 : 1;
+
+  // Create the html for the message.
+
+  const char *Kind = 0;
+  switch (P.getKind()) {
+  case PathDiagnosticPiece::Event:  Kind = "Event"; break;
+  case PathDiagnosticPiece::ControlFlow: Kind = "Control"; break;
+    // Setting Kind to "Control" is intentional.
+  case PathDiagnosticPiece::Macro: Kind = "Control"; break;
+  }
+
+  std::string sbuf;
+  llvm::raw_string_ostream os(sbuf);
+
+  os << "\n<tr><td class=\"num\"></td><td class=\"line\"><div id=\"";
+
+  if (num == max)
+    os << "EndPath";
+  else
+    os << "Path" << num;
+
+  os << "\" class=\"msg";
+  if (Kind)
+    os << " msg" << Kind;
+  os << "\" style=\"margin-left:" << PosNo << "ex";
+
+  // Output a maximum size.
+  if (!isa<PathDiagnosticMacroPiece>(P)) {
+    // Get the string and determining its maximum substring.
+    const std::string& Msg = P.getString();
+    unsigned max_token = 0;
+    unsigned cnt = 0;
+    unsigned len = Msg.size();
+
+    for (std::string::const_iterator I=Msg.begin(), E=Msg.end(); I!=E; ++I)
+      switch (*I) {
+      default:
+        ++cnt;
+        continue;
+      case ' ':
+      case '\t':
+      case '\n':
+        if (cnt > max_token) max_token = cnt;
+        cnt = 0;
+      }
+
+    if (cnt > max_token)
+      max_token = cnt;
+
+    // Determine the approximate size of the message bubble in em.
+    unsigned em;
+    const unsigned max_line = 120;
+
+    if (max_token >= max_line)
+      em = max_token / 2;
+    else {
+      unsigned characters = max_line;
+      unsigned lines = len / max_line;
+
+      if (lines > 0) {
+        for (; characters > max_token; --characters)
+          if (len / characters > lines) {
+            ++characters;
+            break;
+          }
+      }
+
+      em = characters / 2;
+    }
+
+    if (em < max_line/2)
+      os << "; max-width:" << em << "em";
+  }
+  else
+    os << "; max-width:100em";
+
+  os << "\">";
+
+  if (max > 1) {
+    os << "<table class=\"msgT\"><tr><td valign=\"top\">";
+    os << "<div class=\"PathIndex";
+    if (Kind) os << " PathIndex" << Kind;
+    os << "\">" << num << "</div>";
+    os << "</td><td>";
+  }
+
+  if (const PathDiagnosticMacroPiece *MP =
+        dyn_cast<PathDiagnosticMacroPiece>(&P)) {
+
+    os << "Within the expansion of the macro '";
+
+    // Get the name of the macro by relexing it.
+    {
+      FullSourceLoc L = MP->getLocation().asLocation().getInstantiationLoc();
+      assert(L.isFileID());
+      llvm::StringRef BufferInfo = L.getBufferData();
+      const char* MacroName = L.getDecomposedLoc().second + BufferInfo.data();
+      Lexer rawLexer(L, PP.getLangOptions(), BufferInfo.begin(),
+                     MacroName, BufferInfo.end());
+
+      Token TheTok;
+      rawLexer.LexFromRawLexer(TheTok);
+      for (unsigned i = 0, n = TheTok.getLength(); i < n; ++i)
+        os << MacroName[i];
+    }
+
+    os << "':\n";
+
+    if (max > 1)
+      os << "</td></tr></table>";
+
+    // Within a macro piece.  Write out each event.
+    ProcessMacroPiece(os, *MP, 0);
+  }
+  else {
+    os << html::EscapeText(P.getString());
+
+    if (max > 1)
+      os << "</td></tr></table>";
+  }
+
+  os << "</div></td></tr>";
+
+  // Insert the new html.
+  unsigned DisplayPos = LineEnd - FileStart;
+  SourceLocation Loc =
+    SM.getLocForStartOfFile(LPosInfo.first).getFileLocWithOffset(DisplayPos);
+
+  R.InsertTextBefore(Loc, os.str());
+
+  // Now highlight the ranges.
+  for (const SourceRange *I = P.ranges_begin(), *E = P.ranges_end();
+        I != E; ++I)
+    HighlightRange(R, LPosInfo.first, *I);
+
+#if 0
+  // If there is a code insertion hint, insert that code.
+  // FIXME: This code is disabled because it seems to mangle the HTML
+  // output. I'm leaving it here because it's generally the right idea,
+  // but needs some help from someone more familiar with the rewriter.
+  for (const FixItHint *Hint = P.fixit_begin(), *HintEnd = P.fixit_end();
+       Hint != HintEnd; ++Hint) {
+    if (Hint->RemoveRange.isValid()) {
+      HighlightRange(R, LPosInfo.first, Hint->RemoveRange,
+                     "<span class=\"CodeRemovalHint\">", "</span>");
+    }
+    if (Hint->InsertionLoc.isValid()) {
+      std::string EscapedCode = html::EscapeText(Hint->CodeToInsert, true);
+      EscapedCode = "<span class=\"CodeInsertionHint\">" + EscapedCode
+        + "</span>";
+      R.InsertTextBefore(Hint->InsertionLoc, EscapedCode);
+    }
+  }
+#endif
+}
+
+static void EmitAlphaCounter(llvm::raw_ostream& os, unsigned n) {
+  unsigned x = n % ('z' - 'a');
+  n /= 'z' - 'a';
+
+  if (n > 0)
+    EmitAlphaCounter(os, n);
+
+  os << char('a' + x);
+}
+
+unsigned HTMLDiagnostics::ProcessMacroPiece(llvm::raw_ostream& os,
+                                            const PathDiagnosticMacroPiece& P,
+                                            unsigned num) {
+
+  for (PathDiagnosticMacroPiece::const_iterator I=P.begin(), E=P.end();
+        I!=E; ++I) {
+
+    if (const PathDiagnosticMacroPiece *MP =
+          dyn_cast<PathDiagnosticMacroPiece>(*I)) {
+      num = ProcessMacroPiece(os, *MP, num);
+      continue;
+    }
+
+    if (PathDiagnosticEventPiece *EP = dyn_cast<PathDiagnosticEventPiece>(*I)) {
+      os << "<div class=\"msg msgEvent\" style=\"width:94%; "
+            "margin-left:5px\">"
+            "<table class=\"msgT\"><tr>"
+            "<td valign=\"top\"><div class=\"PathIndex PathIndexEvent\">";
+      EmitAlphaCounter(os, num++);
+      os << "</div></td><td valign=\"top\">"
+         << html::EscapeText(EP->getString())
+         << "</td></tr></table></div>\n";
+    }
+  }
+
+  return num;
+}
+
+void HTMLDiagnostics::HighlightRange(Rewriter& R, FileID BugFileID,
+                                     SourceRange Range,
+                                     const char *HighlightStart,
+                                     const char *HighlightEnd) {
+  SourceManager &SM = R.getSourceMgr();
+  const LangOptions &LangOpts = R.getLangOpts();
+
+  SourceLocation InstantiationStart = SM.getInstantiationLoc(Range.getBegin());
+  unsigned StartLineNo = SM.getInstantiationLineNumber(InstantiationStart);
+
+  SourceLocation InstantiationEnd = SM.getInstantiationLoc(Range.getEnd());
+  unsigned EndLineNo = SM.getInstantiationLineNumber(InstantiationEnd);
+
+  if (EndLineNo < StartLineNo)
+    return;
+
+  if (SM.getFileID(InstantiationStart) != BugFileID ||
+      SM.getFileID(InstantiationEnd) != BugFileID)
+    return;
+
+  // Compute the column number of the end.
+  unsigned EndColNo = SM.getInstantiationColumnNumber(InstantiationEnd);
+  unsigned OldEndColNo = EndColNo;
+
+  if (EndColNo) {
+    // Add in the length of the token, so that we cover multi-char tokens.
+    EndColNo += Lexer::MeasureTokenLength(Range.getEnd(), SM, LangOpts)-1;
+  }
+
+  // Highlight the range.  Make the span tag the outermost tag for the
+  // selected range.
+
+  SourceLocation E =
+    InstantiationEnd.getFileLocWithOffset(EndColNo - OldEndColNo);
+
+  html::HighlightRange(R, InstantiationStart, E, HighlightStart, HighlightEnd);
+}
