diff --git a/tools/clang/rewrite_scoped_refptr/Makefile b/tools/clang/rewrite_scoped_refptr/Makefile
new file mode 100644
index 0000000000000..84a204b13e237
--- /dev/null
+++ b/tools/clang/rewrite_scoped_refptr/Makefile
@@ -0,0 +1,25 @@
+# Copyright (c) 2013 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+#
+# This Makefile requires the LLVM build system. In order to build this tool,
+# please run tools/clang/scripts/build_tool.py.
+
+CLANG_LEVEL := ../..
+
+TOOLNAME = rewrite_scoped_refptr
+
+NO_INSTALL = 1
+
+include $(CLANG_LEVEL)/../../Makefile.config
+
+LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc option
+USEDLIBS = clangFrontend.a clangSerialization.a clangDriver.a \
+           clangTooling.a clangParse.a clangSema.a \
+           clangStaticAnalyzerFrontend.a clangStaticAnalyzerCheckers.a \
+           clangStaticAnalyzerCore.a clangAnalysis.a clangRewriteFrontend.a \
+           clangRewrite.a clangEdit.a clangAST.a clangLex.a clangBasic.a \
+           clangASTMatchers.a
+
+include $(CLANG_LEVEL)/Makefile
+
diff --git a/tools/clang/rewrite_scoped_refptr/RewriteScopedRefptr.cpp b/tools/clang/rewrite_scoped_refptr/RewriteScopedRefptr.cpp
new file mode 100644
index 0000000000000..3f83cec2fc556
--- /dev/null
+++ b/tools/clang/rewrite_scoped_refptr/RewriteScopedRefptr.cpp
@@ -0,0 +1,237 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// This implements a Clang tool to rewrite all instances of
+// scoped_refptr<T>'s implicit cast to T (operator T*) to an explicit call to
+// the .get() method.
+
+#include <algorithm>
+#include <memory>
+#include <string>
+
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/ASTMatchers/ASTMatchersMacros.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Frontend/FrontendActions.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Tooling/CommonOptionsParser.h"
+#include "clang/Tooling/Refactoring.h"
+#include "clang/Tooling/Tooling.h"
+#include "llvm/Support/CommandLine.h"
+
+using namespace clang::ast_matchers;
+using clang::tooling::CommonOptionsParser;
+using clang::tooling::Replacement;
+using clang::tooling::Replacements;
+using llvm::StringRef;
+
+namespace clang {
+namespace ast_matchers {
+
+const internal::VariadicDynCastAllOfMatcher<Decl, CXXConversionDecl>
+    conversionDecl;
+
+AST_MATCHER(QualType, isBoolean) {
+  return Node->isBooleanType();
+}
+
+}  // namespace ast_matchers
+}  // namespace clang
+
+namespace {
+
+// Returns true if expr needs to be put in parens (eg: when it is an operator
+// syntactically).
+bool NeedsParens(const clang::Expr* expr) {
+  if (llvm::dyn_cast<clang::UnaryOperator>(expr) ||
+      llvm::dyn_cast<clang::BinaryOperator>(expr) ||
+      llvm::dyn_cast<clang::ConditionalOperator>(expr)) {
+    return true;
+  }
+  // Calls to an overloaded operator also need parens, except for foo(...) and
+  // foo[...] expressions.
+  if (const clang::CXXOperatorCallExpr* op =
+          llvm::dyn_cast<clang::CXXOperatorCallExpr>(expr)) {
+    return op->getOperator() != clang::OO_Call &&
+           op->getOperator() != clang::OO_Subscript;
+  }
+  return false;
+}
+
+class GetRewriterCallback : public MatchFinder::MatchCallback {
+ public:
+  explicit GetRewriterCallback(Replacements* replacements)
+      : replacements_(replacements) {}
+  virtual void run(const MatchFinder::MatchResult& result) override;
+
+ private:
+  Replacements* const replacements_;
+};
+
+void GetRewriterCallback::run(const MatchFinder::MatchResult& result) {
+  const clang::CXXMemberCallExpr* const implicit_call =
+      result.Nodes.getNodeAs<clang::CXXMemberCallExpr>("call");
+  const clang::Expr* arg = result.Nodes.getNodeAs<clang::Expr>("arg");
+
+  if (!implicit_call || !arg)
+    return;
+
+  clang::CharSourceRange range = clang::CharSourceRange::getTokenRange(
+      result.SourceManager->getSpellingLoc(arg->getLocStart()),
+      result.SourceManager->getSpellingLoc(arg->getLocEnd()));
+  if (!range.isValid())
+    return;  // TODO(rsleevi): Log an error?
+
+  // Handle cases where an implicit cast is being done by dereferencing a
+  // pointer to a scoped_refptr<> (sadly, it happens...)
+  //
+  // This rewrites both "*foo" and "*(foo)" as "foo->get()".
+  if (const clang::UnaryOperator* op =
+          llvm::dyn_cast<clang::UnaryOperator>(arg)) {
+    if (op->getOpcode() == clang::UO_Deref) {
+      const clang::Expr* const sub_expr =
+          op->getSubExpr()->IgnoreParenImpCasts();
+      clang::CharSourceRange sub_expr_range =
+          clang::CharSourceRange::getTokenRange(
+              result.SourceManager->getSpellingLoc(sub_expr->getLocStart()),
+              result.SourceManager->getSpellingLoc(sub_expr->getLocEnd()));
+      if (!sub_expr_range.isValid())
+        return;  // TODO(rsleevi): Log an error?
+      std::string inner_text = clang::Lexer::getSourceText(
+          sub_expr_range, *result.SourceManager, result.Context->getLangOpts());
+      if (inner_text.empty())
+        return;  // TODO(rsleevi): Log an error?
+
+      if (NeedsParens(sub_expr)) {
+        inner_text.insert(0, "(");
+        inner_text.append(")");
+      }
+      inner_text.append("->get()");
+      replacements_->insert(
+          Replacement(*result.SourceManager, range, inner_text));
+      return;
+    }
+  }
+
+  std::string text = clang::Lexer::getSourceText(
+      range, *result.SourceManager, result.Context->getLangOpts());
+  if (text.empty())
+    return;  // TODO(rsleevi): Log an error?
+
+  // Unwrap any temporaries - for example, custom iterators that return
+  // scoped_refptr<T> as part of operator*. Any such iterators should also
+  // be declaring a scoped_refptr<T>* operator->, per C++03 24.4.1.1 (Table 72)
+  if (const clang::CXXBindTemporaryExpr* op =
+          llvm::dyn_cast<clang::CXXBindTemporaryExpr>(arg)) {
+    arg = op->getSubExpr();
+  }
+
+  // Handle iterators (which are operator* calls, followed by implicit
+  // conversions) by rewriting *it as it->get()
+  if (const clang::CXXOperatorCallExpr* op =
+          llvm::dyn_cast<clang::CXXOperatorCallExpr>(arg)) {
+    if (op->getOperator() == clang::OO_Star) {
+      // Note that this doesn't rewrite **it correctly, since it should be
+      // rewritten using parens, e.g. (*it)->get(). However, this shouldn't
+      // happen frequently, if at all, since it would likely indicate code is
+      // storing pointers to a scoped_refptr in a container.
+      text.erase(0, 1);
+      text.append("->get()");
+      replacements_->insert(Replacement(*result.SourceManager, range, text));
+      return;
+    }
+  }
+
+  // The only remaining calls should be non-dereferencing calls (eg: member
+  // calls), so a simple ".get()" appending should suffice.
+  if (NeedsParens(arg)) {
+    text.insert(0, "(");
+    text.append(")");
+  }
+  text.append(".get()");
+  replacements_->insert(Replacement(*result.SourceManager, range, text));
+}
+
+}  // namespace
+
+static llvm::cl::extrahelp common_help(CommonOptionsParser::HelpMessage);
+
+int main(int argc, const char* argv[]) {
+  llvm::cl::OptionCategory category("Remove scoped_refptr conversions");
+  CommonOptionsParser options(argc, argv, category);
+  clang::tooling::ClangTool tool(options.getCompilations(),
+                                 options.getSourcePathList());
+
+  MatchFinder match_finder;
+
+  // Finds all calls to conversion operator member function. This catches calls
+  // to "operator T*", "operator Testable", and "operator bool" equally.
+  StatementMatcher overloaded_call_matcher = memberCallExpr(
+      thisPointerType(recordDecl(isSameOrDerivedFrom("::scoped_refptr"),
+                                 isTemplateInstantiation())),
+      callee(conversionDecl()),
+      on(id("arg", expr())));
+
+  // This catches both user-defined conversions (eg: "operator bool") and
+  // standard conversion sequence (C++03 13.3.3.1.1), such as converting a
+  // pointer to a bool.
+  StatementMatcher implicit_to_bool =
+      implicitCastExpr(hasImplicitDestinationType(isBoolean()));
+
+  // Avoid converting calls to of "operator Testable" -> "bool" and calls of
+  // "operator T*" -> "bool".
+  StatementMatcher bool_conversion_matcher = hasParent(expr(
+      anyOf(expr(implicit_to_bool), expr(hasParent(expr(implicit_to_bool))))));
+
+  // Find all calls to an operator overload that do NOT (ultimately) result in
+  // being cast to a bool - eg: where it's being converted to T* and rewrite
+  // them to add a call to get().
+  //
+  // All bool conversions will be handled with the Testable trick, but that
+  // can only be used once "operator T*" is removed, since otherwise it leaves
+  // the call ambiguous.
+  Replacements get_replacements;
+  GetRewriterCallback get_callback(&get_replacements);
+  match_finder.addMatcher(id("call", expr(overloaded_call_matcher)),
+                          &get_callback);
+
+#if 0
+  // Finds all temporary scoped_refptr<T>'s being assigned to a T*. Note that
+  // this will result in two callbacks--both the above callback to append get()
+  // and this callback will match.
+  match_finder.addMatcher(
+      id("var",
+         varDecl(hasInitializer(ignoringImpCasts(
+                     id("call", expr(overloaded_call_matcher)))),
+                 hasType(pointerType()))),
+      &callback);
+  match_finder.addMatcher(
+      binaryOperator(
+          hasOperatorName("="),
+          hasLHS(declRefExpr(to(id("var", varDecl(hasType(pointerType())))))),
+          hasRHS(ignoringParenImpCasts(
+              id("call", expr(overloaded_call_matcher))))),
+      &callback);
+#endif
+
+  std::unique_ptr<clang::tooling::FrontendActionFactory> factory =
+      clang::tooling::newFrontendActionFactory(&match_finder);
+  int result = tool.run(factory.get());
+  if (result != 0)
+    return result;
+
+  // Serialization format is documented in tools/clang/scripts/run_tool.py
+  llvm::outs() << "==== BEGIN EDITS ====\n";
+  for (const auto& r : get_replacements) {
+    std::string replacement_text = r.getReplacementText().str();
+    std::replace(replacement_text.begin(), replacement_text.end(), '\n', '\0');
+    llvm::outs() << "r:" << r.getFilePath() << ":" << r.getOffset() << ":"
+                 << r.getLength() << ":" << replacement_text << "\n";
+  }
+  llvm::outs() << "==== END EDITS ====\n";
+
+  return 0;
+}
diff --git a/tools/clang/rewrite_scoped_refptr/tests/scoped_refptr.h b/tools/clang/rewrite_scoped_refptr/tests/scoped_refptr.h
new file mode 100644
index 0000000000000..1ebd323358b65
--- /dev/null
+++ b/tools/clang/rewrite_scoped_refptr/tests/scoped_refptr.h
@@ -0,0 +1,43 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SCOPED_REFPTR_H_
+#define SCOPED_REFPTR_H_
+
+// Stub scoped_refptr<T> class that supports an implicit cast to T*.
+template <class T>
+class scoped_refptr {
+ public:
+  typedef T element_type;
+  scoped_refptr() : ptr_(0) {}
+  scoped_refptr(T* p) : ptr_(p) {}
+  scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) {}
+
+  template <typename U>
+  scoped_refptr(const scoped_refptr<U>& r)
+      : ptr_(r.get()) {}
+
+  ~scoped_refptr() {}
+
+  T* get() const { return ptr_; }
+  operator T*() const { return ptr_; }
+  T* operator->() const { return ptr_; }
+
+  scoped_refptr<T>& operator=(T* p) {
+    ptr_ = p;
+    return *this;
+  }
+  scoped_refptr<T>& operator=(const scoped_refptr<T>& r) {
+    return *this = r.ptr_;
+  }
+  template <typename U>
+  scoped_refptr<T>& operator=(const scoped_refptr<U>& r) {
+    return *this = r.get();
+  }
+
+ protected:
+  T* ptr_;
+};
+
+#endif  // SCOPED_REFPTR_H_
diff --git a/tools/clang/rewrite_scoped_refptr/tests/test1-expected.cc b/tools/clang/rewrite_scoped_refptr/tests/test1-expected.cc
new file mode 100644
index 0000000000000..a704d393324bc
--- /dev/null
+++ b/tools/clang/rewrite_scoped_refptr/tests/test1-expected.cc
@@ -0,0 +1,16 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "scoped_refptr.h"
+
+struct Foo {
+  int dummy;
+};
+
+// Case 1: An example of an unsafe conversion, where the object is freed by
+// the time the function returns.
+Foo* GetBuggyFoo() {
+  scoped_refptr<Foo> unsafe(new Foo);
+  return unsafe.get();
+}
diff --git a/tools/clang/rewrite_scoped_refptr/tests/test1-original.cc b/tools/clang/rewrite_scoped_refptr/tests/test1-original.cc
new file mode 100644
index 0000000000000..cafcfcc03550c
--- /dev/null
+++ b/tools/clang/rewrite_scoped_refptr/tests/test1-original.cc
@@ -0,0 +1,16 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "scoped_refptr.h"
+
+struct Foo {
+  int dummy;
+};
+
+// Case 1: An example of an unsafe conversion, where the object is freed by
+// the time the function returns.
+Foo* GetBuggyFoo() {
+  scoped_refptr<Foo> unsafe(new Foo);
+  return unsafe;
+}
diff --git a/tools/clang/rewrite_scoped_refptr/tests/test10-expected.cc b/tools/clang/rewrite_scoped_refptr/tests/test10-expected.cc
new file mode 100644
index 0000000000000..a74cd7df9336d
--- /dev/null
+++ b/tools/clang/rewrite_scoped_refptr/tests/test10-expected.cc
@@ -0,0 +1,16 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "scoped_refptr.h"
+
+struct Foo {
+  int dummy;
+};
+
+int TestsAScopedRefptr() {
+  scoped_refptr<Foo> foo(new Foo);
+  if (foo.get())
+    return 1;
+  return 0;
+}
diff --git a/tools/clang/rewrite_scoped_refptr/tests/test10-original.cc b/tools/clang/rewrite_scoped_refptr/tests/test10-original.cc
new file mode 100644
index 0000000000000..24ecd744be401
--- /dev/null
+++ b/tools/clang/rewrite_scoped_refptr/tests/test10-original.cc
@@ -0,0 +1,16 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "scoped_refptr.h"
+
+struct Foo {
+  int dummy;
+};
+
+int TestsAScopedRefptr() {
+  scoped_refptr<Foo> foo(new Foo);
+  if (foo)
+    return 1;
+  return 0;
+}
diff --git a/tools/clang/rewrite_scoped_refptr/tests/test11-expected.cc b/tools/clang/rewrite_scoped_refptr/tests/test11-expected.cc
new file mode 100644
index 0000000000000..de4c01cacba0b
--- /dev/null
+++ b/tools/clang/rewrite_scoped_refptr/tests/test11-expected.cc
@@ -0,0 +1,22 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <vector>
+
+#include "scoped_refptr.h"
+
+struct Foo {
+  int dummy;
+};
+
+typedef std::vector<scoped_refptr<Foo> > FooList;
+
+void TestsAScopedRefptr() {
+  FooList list;
+  list.push_back(new Foo);
+  list.push_back(new Foo);
+  for (FooList::const_iterator it = list.begin(); it != list.end(); ++it) {
+    Foo* item = it->get();
+  }
+}
diff --git a/tools/clang/rewrite_scoped_refptr/tests/test11-original.cc b/tools/clang/rewrite_scoped_refptr/tests/test11-original.cc
new file mode 100644
index 0000000000000..48cf41b2799c3
--- /dev/null
+++ b/tools/clang/rewrite_scoped_refptr/tests/test11-original.cc
@@ -0,0 +1,22 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <vector>
+
+#include "scoped_refptr.h"
+
+struct Foo {
+  int dummy;
+};
+
+typedef std::vector<scoped_refptr<Foo> > FooList;
+
+void TestsAScopedRefptr() {
+  FooList list;
+  list.push_back(new Foo);
+  list.push_back(new Foo);
+  for (FooList::const_iterator it = list.begin(); it != list.end(); ++it) {
+    Foo* item = *it;
+  }
+}
diff --git a/tools/clang/rewrite_scoped_refptr/tests/test12-expected.cc b/tools/clang/rewrite_scoped_refptr/tests/test12-expected.cc
new file mode 100644
index 0000000000000..37f350c947b27
--- /dev/null
+++ b/tools/clang/rewrite_scoped_refptr/tests/test12-expected.cc
@@ -0,0 +1,45 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <iterator>
+#include <map>
+#include <string>
+
+#include "scoped_refptr.h"
+
+struct Foo {
+  int dummy;
+};
+
+typedef std::map<std::string, scoped_refptr<const Foo> > MyMap;
+
+class MyIter
+    : public std::iterator<std::input_iterator_tag, scoped_refptr<const Foo> > {
+ public:
+  MyIter() {}
+  MyIter(const MyIter& other) : it_(other.it_) {}
+  explicit MyIter(MyMap::const_iterator it) : it_(it) {}
+  MyIter& operator++() {
+    ++it_;
+    return *this;
+  }
+  const scoped_refptr<const Foo> operator*() { return it_->second; }
+  bool operator!=(const MyIter& other) { return it_ != other.it_; }
+  bool operator==(const MyIter& other) { return it_ == other.it_; }
+
+ private:
+  MyMap::const_iterator it_;
+};
+
+void TestsAScopedRefptr() {
+  MyMap map;
+  map["foo"] = new Foo;
+  map["bar"] = new Foo;
+  MyIter my_begin(map.begin());
+  MyIter my_end(map.end());
+  for (MyIter it = my_begin; it != my_end; ++it) {
+    const Foo* item = NULL;
+    item = it->get();
+  }
+}
diff --git a/tools/clang/rewrite_scoped_refptr/tests/test12-original.cc b/tools/clang/rewrite_scoped_refptr/tests/test12-original.cc
new file mode 100644
index 0000000000000..de4dd67258024
--- /dev/null
+++ b/tools/clang/rewrite_scoped_refptr/tests/test12-original.cc
@@ -0,0 +1,45 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <iterator>
+#include <map>
+#include <string>
+
+#include "scoped_refptr.h"
+
+struct Foo {
+  int dummy;
+};
+
+typedef std::map<std::string, scoped_refptr<const Foo> > MyMap;
+
+class MyIter
+    : public std::iterator<std::input_iterator_tag, scoped_refptr<const Foo> > {
+ public:
+  MyIter() {}
+  MyIter(const MyIter& other) : it_(other.it_) {}
+  explicit MyIter(MyMap::const_iterator it) : it_(it) {}
+  MyIter& operator++() {
+    ++it_;
+    return *this;
+  }
+  const scoped_refptr<const Foo> operator*() { return it_->second; }
+  bool operator!=(const MyIter& other) { return it_ != other.it_; }
+  bool operator==(const MyIter& other) { return it_ == other.it_; }
+
+ private:
+  MyMap::const_iterator it_;
+};
+
+void TestsAScopedRefptr() {
+  MyMap map;
+  map["foo"] = new Foo;
+  map["bar"] = new Foo;
+  MyIter my_begin(map.begin());
+  MyIter my_end(map.end());
+  for (MyIter it = my_begin; it != my_end; ++it) {
+    const Foo* item = NULL;
+    item = *it;
+  }
+}
diff --git a/tools/clang/rewrite_scoped_refptr/tests/test2-expected.cc b/tools/clang/rewrite_scoped_refptr/tests/test2-expected.cc
new file mode 100644
index 0000000000000..dd6e0ee9ba67d
--- /dev/null
+++ b/tools/clang/rewrite_scoped_refptr/tests/test2-expected.cc
@@ -0,0 +1,19 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "scoped_refptr.h"
+
+struct Foo {
+  int dummy;
+};
+
+// Case 2: An example of an unsafe conversion, where the scoped_refptr<> is
+// returned as a temporary, and as such both it and its object are only valid
+// for the duration of the full expression.
+scoped_refptr<Foo> GetBuggyFoo() {
+  return new Foo;
+}
+void UseBuggyFoo() {
+  Foo* unsafe = GetBuggyFoo();
+}
diff --git a/tools/clang/rewrite_scoped_refptr/tests/test2-original.cc b/tools/clang/rewrite_scoped_refptr/tests/test2-original.cc
new file mode 100644
index 0000000000000..dd6e0ee9ba67d
--- /dev/null
+++ b/tools/clang/rewrite_scoped_refptr/tests/test2-original.cc
@@ -0,0 +1,19 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "scoped_refptr.h"
+
+struct Foo {
+  int dummy;
+};
+
+// Case 2: An example of an unsafe conversion, where the scoped_refptr<> is
+// returned as a temporary, and as such both it and its object are only valid
+// for the duration of the full expression.
+scoped_refptr<Foo> GetBuggyFoo() {
+  return new Foo;
+}
+void UseBuggyFoo() {
+  Foo* unsafe = GetBuggyFoo();
+}
diff --git a/tools/clang/rewrite_scoped_refptr/tests/test3-expected.cc b/tools/clang/rewrite_scoped_refptr/tests/test3-expected.cc
new file mode 100644
index 0000000000000..9a0bf605eb775
--- /dev/null
+++ b/tools/clang/rewrite_scoped_refptr/tests/test3-expected.cc
@@ -0,0 +1,22 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "scoped_refptr.h"
+
+struct Foo {
+  int dummy;
+};
+
+void ExpectsScopedRefptr(const scoped_refptr<Foo>& param) {
+  Foo* foo = param.get();
+}
+
+void CallExpectsScopedRefptr() {
+  scoped_refptr<Foo> temp(new Foo);
+  ExpectsScopedRefptr(temp);
+}
+
+void CallExpectsScopedRefptrWithRawPtr() {
+  ExpectsScopedRefptr(new Foo);
+}
diff --git a/tools/clang/rewrite_scoped_refptr/tests/test3-original.cc b/tools/clang/rewrite_scoped_refptr/tests/test3-original.cc
new file mode 100644
index 0000000000000..eb40952cf890f
--- /dev/null
+++ b/tools/clang/rewrite_scoped_refptr/tests/test3-original.cc
@@ -0,0 +1,22 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "scoped_refptr.h"
+
+struct Foo {
+  int dummy;
+};
+
+void ExpectsScopedRefptr(const scoped_refptr<Foo>& param) {
+  Foo* foo = param;
+}
+
+void CallExpectsScopedRefptr() {
+  scoped_refptr<Foo> temp(new Foo);
+  ExpectsScopedRefptr(temp);
+}
+
+void CallExpectsScopedRefptrWithRawPtr() {
+  ExpectsScopedRefptr(new Foo);
+}
diff --git a/tools/clang/rewrite_scoped_refptr/tests/test4-expected.cc b/tools/clang/rewrite_scoped_refptr/tests/test4-expected.cc
new file mode 100644
index 0000000000000..1fc61bc4166c9
--- /dev/null
+++ b/tools/clang/rewrite_scoped_refptr/tests/test4-expected.cc
@@ -0,0 +1,22 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "scoped_refptr.h"
+
+struct Foo {
+  int dummy;
+};
+
+void ExpectsRawPtr(Foo* foo) {
+  Foo* temp = foo;
+}
+
+void CallExpectsRawPtrWithScopedRefptr() {
+  scoped_refptr<Foo> ok(new Foo);
+  ExpectsRawPtr(ok.get());
+}
+
+void CallExpectsRawPtrWithRawPtr() {
+  ExpectsRawPtr(new Foo);
+}
diff --git a/tools/clang/rewrite_scoped_refptr/tests/test4-original.cc b/tools/clang/rewrite_scoped_refptr/tests/test4-original.cc
new file mode 100644
index 0000000000000..3395b10c2e5ef
--- /dev/null
+++ b/tools/clang/rewrite_scoped_refptr/tests/test4-original.cc
@@ -0,0 +1,22 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "scoped_refptr.h"
+
+struct Foo {
+  int dummy;
+};
+
+void ExpectsRawPtr(Foo* foo) {
+  Foo* temp = foo;
+}
+
+void CallExpectsRawPtrWithScopedRefptr() {
+  scoped_refptr<Foo> ok(new Foo);
+  ExpectsRawPtr(ok);
+}
+
+void CallExpectsRawPtrWithRawPtr() {
+  ExpectsRawPtr(new Foo);
+}
diff --git a/tools/clang/rewrite_scoped_refptr/tests/test5-expected.cc b/tools/clang/rewrite_scoped_refptr/tests/test5-expected.cc
new file mode 100644
index 0000000000000..d9d3924dd3cf6
--- /dev/null
+++ b/tools/clang/rewrite_scoped_refptr/tests/test5-expected.cc
@@ -0,0 +1,23 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "scoped_refptr.h"
+
+struct Foo {
+  int dummy;
+};
+
+struct Bar : public Foo {
+  int another_dummy;
+};
+
+// Ensure that the correct cast (the user-defined cast) is converted.
+void ExpectsRawFooPtr(Foo* foo) {
+  Foo* temp = foo;
+}
+
+void CallExpectsRawFooPtrWithBar() {
+  scoped_refptr<Bar> temp(new Bar);
+  ExpectsRawFooPtr(temp.get());
+}
diff --git a/tools/clang/rewrite_scoped_refptr/tests/test5-original.cc b/tools/clang/rewrite_scoped_refptr/tests/test5-original.cc
new file mode 100644
index 0000000000000..eb87a0744b8d1
--- /dev/null
+++ b/tools/clang/rewrite_scoped_refptr/tests/test5-original.cc
@@ -0,0 +1,23 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "scoped_refptr.h"
+
+struct Foo {
+  int dummy;
+};
+
+struct Bar : public Foo {
+  int another_dummy;
+};
+
+// Ensure that the correct cast (the user-defined cast) is converted.
+void ExpectsRawFooPtr(Foo* foo) {
+  Foo* temp = foo;
+}
+
+void CallExpectsRawFooPtrWithBar() {
+  scoped_refptr<Bar> temp(new Bar);
+  ExpectsRawFooPtr(temp);
+}
diff --git a/tools/clang/rewrite_scoped_refptr/tests/test6-expected.cc b/tools/clang/rewrite_scoped_refptr/tests/test6-expected.cc
new file mode 100644
index 0000000000000..00bbcda1e5803
--- /dev/null
+++ b/tools/clang/rewrite_scoped_refptr/tests/test6-expected.cc
@@ -0,0 +1,24 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "scoped_refptr.h"
+
+struct Foo {
+  int dummy;
+};
+
+struct Bar : public Foo {
+  int another_dummy;
+};
+
+// Ensure that scoped_refptr<A> -> scoped_refptr<B> conversions are not
+// converted.
+void ExpectsScopedPtr(const scoped_refptr<Foo>& foo) {
+  scoped_refptr<Foo> temp(foo);
+}
+
+void CallExpectsScopedPtrWithBar() {
+  scoped_refptr<Bar> temp(new Bar);
+  ExpectsScopedPtr(temp);
+}
diff --git a/tools/clang/rewrite_scoped_refptr/tests/test6-original.cc b/tools/clang/rewrite_scoped_refptr/tests/test6-original.cc
new file mode 100644
index 0000000000000..00bbcda1e5803
--- /dev/null
+++ b/tools/clang/rewrite_scoped_refptr/tests/test6-original.cc
@@ -0,0 +1,24 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "scoped_refptr.h"
+
+struct Foo {
+  int dummy;
+};
+
+struct Bar : public Foo {
+  int another_dummy;
+};
+
+// Ensure that scoped_refptr<A> -> scoped_refptr<B> conversions are not
+// converted.
+void ExpectsScopedPtr(const scoped_refptr<Foo>& foo) {
+  scoped_refptr<Foo> temp(foo);
+}
+
+void CallExpectsScopedPtrWithBar() {
+  scoped_refptr<Bar> temp(new Bar);
+  ExpectsScopedPtr(temp);
+}
diff --git a/tools/clang/rewrite_scoped_refptr/tests/test7-expected.cc b/tools/clang/rewrite_scoped_refptr/tests/test7-expected.cc
new file mode 100644
index 0000000000000..31b15caafa07c
--- /dev/null
+++ b/tools/clang/rewrite_scoped_refptr/tests/test7-expected.cc
@@ -0,0 +1,21 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "scoped_refptr.h"
+
+struct Foo {
+  int dummy;
+};
+
+void ExpectsRawPtr(Foo* foo) {
+  Foo* temp = foo;
+}
+
+// Ensure that de-referencing scoped_refptr<>'s are properly rewritten as
+// ->get() calls.
+Foo* GetHeapFoo() {
+  scoped_refptr<Foo>* heap_allocated = new scoped_refptr<Foo>();
+  *heap_allocated = new Foo;
+  return heap_allocated->get();
+}
diff --git a/tools/clang/rewrite_scoped_refptr/tests/test7-original.cc b/tools/clang/rewrite_scoped_refptr/tests/test7-original.cc
new file mode 100644
index 0000000000000..faad6d69b78a4
--- /dev/null
+++ b/tools/clang/rewrite_scoped_refptr/tests/test7-original.cc
@@ -0,0 +1,21 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "scoped_refptr.h"
+
+struct Foo {
+  int dummy;
+};
+
+void ExpectsRawPtr(Foo* foo) {
+  Foo* temp = foo;
+}
+
+// Ensure that de-referencing scoped_refptr<>'s are properly rewritten as
+// ->get() calls.
+Foo* GetHeapFoo() {
+  scoped_refptr<Foo>* heap_allocated = new scoped_refptr<Foo>();
+  *heap_allocated = new Foo;
+  return *heap_allocated;
+}
diff --git a/tools/clang/rewrite_scoped_refptr/tests/test8-expected.cc b/tools/clang/rewrite_scoped_refptr/tests/test8-expected.cc
new file mode 100644
index 0000000000000..a7a211939f26e
--- /dev/null
+++ b/tools/clang/rewrite_scoped_refptr/tests/test8-expected.cc
@@ -0,0 +1,26 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "scoped_refptr.h"
+
+struct Foo {
+  int dummy;
+};
+
+struct Bar : public Foo {
+  int another_dummy;
+};
+
+void ExpectsRawPtr(Foo* foo) {
+  Foo* temp = foo;
+}
+
+// Ensure that de-referencing scoped_refptr<>'s are properly rewritten as
+// ->get() calls, and that the correct conversion is rewritten (eg: not the
+// Bar* -> Foo* conversion).
+Foo* GetHeapFoo() {
+  scoped_refptr<Bar>* heap_allocated = new scoped_refptr<Bar>();
+  *heap_allocated = new Bar;
+  return heap_allocated->get();
+}
diff --git a/tools/clang/rewrite_scoped_refptr/tests/test8-original.cc b/tools/clang/rewrite_scoped_refptr/tests/test8-original.cc
new file mode 100644
index 0000000000000..e485ff04ac5cb
--- /dev/null
+++ b/tools/clang/rewrite_scoped_refptr/tests/test8-original.cc
@@ -0,0 +1,26 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "scoped_refptr.h"
+
+struct Foo {
+  int dummy;
+};
+
+struct Bar : public Foo {
+  int another_dummy;
+};
+
+void ExpectsRawPtr(Foo* foo) {
+  Foo* temp = foo;
+}
+
+// Ensure that de-referencing scoped_refptr<>'s are properly rewritten as
+// ->get() calls, and that the correct conversion is rewritten (eg: not the
+// Bar* -> Foo* conversion).
+Foo* GetHeapFoo() {
+  scoped_refptr<Bar>* heap_allocated = new scoped_refptr<Bar>();
+  *heap_allocated = new Bar;
+  return *heap_allocated;
+}
diff --git a/tools/clang/rewrite_scoped_refptr/tests/test9-expected.cc b/tools/clang/rewrite_scoped_refptr/tests/test9-expected.cc
new file mode 100644
index 0000000000000..614aff9a77731
--- /dev/null
+++ b/tools/clang/rewrite_scoped_refptr/tests/test9-expected.cc
@@ -0,0 +1,45 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "scoped_refptr.h"
+
+struct Foo {
+  int dummy;
+};
+
+struct HasAScopedRefptr {
+  scoped_refptr<Foo> member;
+
+  const scoped_refptr<Foo>& GetMemberAsScopedRefptr() const { return member; }
+
+  Foo* GetMemberAsRawPtr() const { return member.get(); }
+};
+
+void ExpectsRawPtr(Foo* param) {
+  Foo* temp = param;
+}
+
+void ExpectsScopedRefptr(const scoped_refptr<Foo>& param) {
+  Foo* temp = param.get();
+}
+
+void CallsRawWithMemberScopedRefptr() {
+  HasAScopedRefptr object;
+  ExpectsRawPtr(object.GetMemberAsScopedRefptr().get());
+}
+
+void CallsRawWithMemberRawPtr() {
+  HasAScopedRefptr object;
+  ExpectsRawPtr(object.GetMemberAsRawPtr());
+}
+
+void CallsScopedWithMemberScopedRefptr() {
+  HasAScopedRefptr object;
+  ExpectsScopedRefptr(object.GetMemberAsScopedRefptr());
+}
+
+void CallsScopedWithMemberRawPtr() {
+  HasAScopedRefptr object;
+  ExpectsScopedRefptr(object.GetMemberAsScopedRefptr());
+}
diff --git a/tools/clang/rewrite_scoped_refptr/tests/test9-original.cc b/tools/clang/rewrite_scoped_refptr/tests/test9-original.cc
new file mode 100644
index 0000000000000..e59ed6e9e10a8
--- /dev/null
+++ b/tools/clang/rewrite_scoped_refptr/tests/test9-original.cc
@@ -0,0 +1,45 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "scoped_refptr.h"
+
+struct Foo {
+  int dummy;
+};
+
+struct HasAScopedRefptr {
+  scoped_refptr<Foo> member;
+
+  const scoped_refptr<Foo>& GetMemberAsScopedRefptr() const { return member; }
+
+  Foo* GetMemberAsRawPtr() const { return member; }
+};
+
+void ExpectsRawPtr(Foo* param) {
+  Foo* temp = param;
+}
+
+void ExpectsScopedRefptr(const scoped_refptr<Foo>& param) {
+  Foo* temp = param.get();
+}
+
+void CallsRawWithMemberScopedRefptr() {
+  HasAScopedRefptr object;
+  ExpectsRawPtr(object.GetMemberAsScopedRefptr());
+}
+
+void CallsRawWithMemberRawPtr() {
+  HasAScopedRefptr object;
+  ExpectsRawPtr(object.GetMemberAsRawPtr());
+}
+
+void CallsScopedWithMemberScopedRefptr() {
+  HasAScopedRefptr object;
+  ExpectsScopedRefptr(object.GetMemberAsScopedRefptr());
+}
+
+void CallsScopedWithMemberRawPtr() {
+  HasAScopedRefptr object;
+  ExpectsScopedRefptr(object.GetMemberAsScopedRefptr());
+}
diff --git a/tools/clang/scripts/run_tool.py b/tools/clang/scripts/run_tool.py
index 03b4100a2f8da..3c4f44f83e27c 100755
--- a/tools/clang/scripts/run_tool.py
+++ b/tools/clang/scripts/run_tool.py
@@ -81,6 +81,7 @@ def _ExtractEditsFromStdout(build_directory, stdout):
   for line in lines[start_index + 1:end_index]:
     try:
       edit_type, path, offset, length, replacement = line.split(':', 4)
+      replacement = replacement.replace("\0", "\n");
       # Normalize the file path emitted by the clang tool to be relative to the
       # current working directory.
       path = os.path.relpath(os.path.join(build_directory, path))
diff --git a/tools/clang/scripts/test_tool.py b/tools/clang/scripts/test_tool.py
index a99e9f48ae3bc..09ff46033d56d 100755
--- a/tools/clang/scripts/test_tool.py
+++ b/tools/clang/scripts/test_tool.py
@@ -87,12 +87,12 @@ def main(argv):
       with open(actual, 'r') as f:
         actual_output = f.readlines()
       if actual_output != expected_output:
-        print '[  FAILED  ] %s' % os.path.relpath(actual)
         failed += 1
         for line in difflib.unified_diff(expected_output, actual_output,
                                          fromfile=os.path.relpath(expected),
                                          tofile=os.path.relpath(actual)):
           sys.stdout.write(line)
+        print '[  FAILED  ] %s' % os.path.relpath(actual)
         # Don't clean up the file on failure, so the results can be referenced
         # more easily.
         continue