diff --git a/lib/ARCMigrate/CMakeLists.txt b/lib/ARCMigrate/CMakeLists.txt
index 0049d2f..56db384 100644
--- a/lib/ARCMigrate/CMakeLists.txt
+++ b/lib/ARCMigrate/CMakeLists.txt
@@ -4,8 +4,19 @@
   ARCMT.cpp
   ARCMTActions.cpp
   FileRemapper.cpp
+  TransAllocCopyWithZone.cpp
+  TransARCAssign.cpp
+  TransAutoreleasePool.cpp
+  TransBlockObjCVariable.cpp
+  TransDeallocMethod.cpp
+  TransEmptyStatements.cpp
   TransformActions.cpp
   Transforms.cpp
+  TransProperties.cpp
+  TransRetainReleaseDealloc.cpp
+  TransUnbridgedCasts.cpp
+  TransUnusedInitDelegate.cpp
+  TransZeroOutPropsInDealloc.cpp
   )
 
 add_dependencies(clangARCMigrate
diff --git a/lib/ARCMigrate/TransARCAssign.cpp b/lib/ARCMigrate/TransARCAssign.cpp
new file mode 100644
index 0000000..8c00df5
--- /dev/null
+++ b/lib/ARCMigrate/TransARCAssign.cpp
@@ -0,0 +1,75 @@
+//===--- TransARCAssign.cpp - Tranformations to ARC mode ------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// makeAssignARCSafe:
+//
+// Add '__strong' where appropriate.
+//
+//  for (id x in collection) {
+//    x = 0;
+//  }
+// ---->
+//  for (__strong id x in collection) {
+//    x = 0;
+//  }
+//
+//===----------------------------------------------------------------------===//
+
+#include "Transforms.h"
+#include "Internals.h"
+#include "clang/Sema/SemaDiagnostic.h"
+
+using namespace clang;
+using namespace arcmt;
+using namespace trans;
+using llvm::StringRef;
+
+namespace {
+
+class ARCAssignChecker : public RecursiveASTVisitor<ARCAssignChecker> {
+  MigrationPass &Pass;
+  llvm::DenseSet<VarDecl *> ModifiedVars;
+
+public:
+  ARCAssignChecker(MigrationPass &pass) : Pass(pass) { }
+
+  bool VisitBinaryOperator(BinaryOperator *Exp) {
+    Expr *E = Exp->getLHS();
+    SourceLocation OrigLoc = E->getExprLoc();
+    SourceLocation Loc = OrigLoc;
+    DeclRefExpr *declRef = dyn_cast<DeclRefExpr>(E->IgnoreParenCasts());
+    if (declRef && isa<VarDecl>(declRef->getDecl())) {
+      ASTContext &Ctx = Pass.Ctx;
+      Expr::isModifiableLvalueResult IsLV = E->isModifiableLvalue(Ctx, &Loc);
+      if (IsLV != Expr::MLV_ConstQualified)
+        return true;
+      VarDecl *var = cast<VarDecl>(declRef->getDecl());
+      if (var->isARCPseudoStrong()) {
+        Transaction Trans(Pass.TA);
+        if (Pass.TA.clearDiagnostic(diag::err_typecheck_arr_assign_enumeration,
+                                    Exp->getOperatorLoc())) {
+          if (!ModifiedVars.count(var)) {
+            TypeLoc TLoc = var->getTypeSourceInfo()->getTypeLoc();
+            Pass.TA.insert(TLoc.getBeginLoc(), "__strong ");
+            ModifiedVars.insert(var);
+          }
+        }
+      }
+    }
+    
+    return true;
+  }
+};
+
+} // anonymous namespace
+
+void trans::makeAssignARCSafe(MigrationPass &pass) {
+  ARCAssignChecker assignCheck(pass);
+  assignCheck.TraverseDecl(pass.Ctx.getTranslationUnitDecl());
+}
diff --git a/lib/ARCMigrate/TransAllocCopyWithZone.cpp b/lib/ARCMigrate/TransAllocCopyWithZone.cpp
new file mode 100644
index 0000000..da7f25d
--- /dev/null
+++ b/lib/ARCMigrate/TransAllocCopyWithZone.cpp
@@ -0,0 +1,223 @@
+//===--- TransAllocCopyWithZone.cpp - Tranformations to ARC mode ----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// rewriteAllocCopyWithZone:
+//
+// Calls to +allocWithZone/-copyWithZone/-mutableCopyWithZone are changed to
+// +alloc/-copy/-mutableCopy if we can safely remove the given parameter.
+//
+//  Foo *foo1 = [[Foo allocWithZone:[self zone]] init];
+// ---->
+//  Foo *foo1 = [[Foo alloc] init];
+//
+//===----------------------------------------------------------------------===//
+
+#include "Transforms.h"
+#include "Internals.h"
+#include "clang/Sema/SemaDiagnostic.h"
+
+using namespace clang;
+using namespace arcmt;
+using namespace trans;
+using llvm::StringRef;
+
+namespace {
+
+class AllocCopyWithZoneRewriter :
+                         public RecursiveASTVisitor<AllocCopyWithZoneRewriter> {
+  Decl *Dcl;
+  Stmt *Body;
+  MigrationPass &Pass;
+
+  Selector allocWithZoneSel;
+  Selector copyWithZoneSel;
+  Selector mutableCopyWithZoneSel;
+  Selector zoneSel;
+  IdentifierInfo *NSZoneII;
+
+  std::vector<DeclStmt *> NSZoneVars;
+  std::vector<Expr *> Removals;
+
+public:
+  AllocCopyWithZoneRewriter(Decl *D, MigrationPass &pass)
+    : Dcl(D), Body(0), Pass(pass) {
+    SelectorTable &sels = pass.Ctx.Selectors;
+    IdentifierTable &ids = pass.Ctx.Idents; 
+    allocWithZoneSel = sels.getUnarySelector(&ids.get("allocWithZone"));
+    copyWithZoneSel = sels.getUnarySelector(&ids.get("copyWithZone"));
+    mutableCopyWithZoneSel = sels.getUnarySelector(
+                                               &ids.get("mutableCopyWithZone"));
+    zoneSel = sels.getNullarySelector(&ids.get("zone"));
+    NSZoneII = &ids.get("_NSZone");
+  }
+
+  void transformBody(Stmt *body) {
+    Body = body;
+    // Don't change allocWithZone/copyWithZone messages inside
+    // custom implementations of such methods, it can lead to infinite loops.
+    if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(Dcl)) {
+      Selector sel = MD->getSelector();
+      if (sel == allocWithZoneSel ||
+          sel == copyWithZoneSel ||
+          sel == mutableCopyWithZoneSel ||
+          sel == zoneSel)
+        return;
+    }
+
+    TraverseStmt(body);
+  }
+
+  ~AllocCopyWithZoneRewriter() {
+    for (std::vector<DeclStmt *>::reverse_iterator
+           I = NSZoneVars.rbegin(), E = NSZoneVars.rend(); I != E; ++I) {
+      DeclStmt *DS = *I;
+      DeclGroupRef group = DS->getDeclGroup();
+      std::vector<Expr *> varRemovals = Removals;
+
+      bool areAllVarsUnused = true;
+      for (std::reverse_iterator<DeclGroupRef::iterator>
+             DI(group.end()), DE(group.begin()); DI != DE; ++DI) {
+        VarDecl *VD = cast<VarDecl>(*DI);
+        if (isNSZoneVarUsed(VD, varRemovals)) {
+          areAllVarsUnused = false;
+          break;
+        }
+        varRemovals.push_back(VD->getInit());
+      }
+
+      if (areAllVarsUnused) {
+        Transaction Trans(Pass.TA);
+        clearUnavailableDiags(DS);
+        Pass.TA.removeStmt(DS);
+        Removals.swap(varRemovals);
+      }
+    }
+  }
+
+  bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
+    if (!isAllocCopyWithZoneCall(E))
+      return true;
+    Expr *arg = E->getArg(0);
+    if (paramToAllocWithZoneHasSideEffects(arg))
+      return true;
+
+    Pass.TA.startTransaction();
+
+    clearUnavailableDiags(arg);
+    Pass.TA.clearDiagnostic(diag::err_unavailable_message,
+                            E->getReceiverRange().getBegin());
+
+    Pass.TA.remove(SourceRange(E->getSelectorLoc(), arg->getLocEnd()));
+    StringRef rewrite;
+    if (E->getSelector() == allocWithZoneSel)
+      rewrite = "alloc";
+    else if (E->getSelector() == copyWithZoneSel)
+      rewrite = "copy";
+    else {
+      assert(E->getSelector() == mutableCopyWithZoneSel);
+      rewrite = "mutableCopy";
+    }
+    Pass.TA.insert(E->getSelectorLoc(), rewrite);
+
+    bool failed = Pass.TA.commitTransaction();
+    if (!failed)
+      Removals.push_back(arg);
+
+    return true;
+  }
+
+  bool VisitDeclStmt(DeclStmt *DS) {
+    DeclGroupRef group = DS->getDeclGroup();
+    if (group.begin() == group.end())
+      return true;
+    for (DeclGroupRef::iterator
+           DI = group.begin(), DE = group.end(); DI != DE; ++DI)
+      if (!isRemovableNSZoneVar(*DI))
+        return true;
+
+    NSZoneVars.push_back(DS);
+    return true;
+  }
+
+private:
+  bool isRemovableNSZoneVar(Decl *D) {
+    if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
+      if (isNSZone(VD->getType()))
+        return !paramToAllocWithZoneHasSideEffects(VD->getInit());
+    }
+    return false;
+  }
+
+  bool isNSZone(RecordDecl *RD) {
+    return RD && RD->getIdentifier() == NSZoneII;
+  }
+
+  bool isNSZone(QualType Ty) {
+    QualType pointee = Ty->getPointeeType();
+    if (pointee.isNull())
+      return false;
+    if (const RecordType *recT = pointee->getAsStructureType())
+      return isNSZone(recT->getDecl());
+    return false;
+  }
+
+  bool isNSZoneVarUsed(VarDecl *D, std::vector<Expr *> &removals) {
+    ExprSet refs;
+    collectRefs(D, Body, refs);
+    clearRefsIn(removals.begin(), removals.end(), refs);
+
+    return !refs.empty();
+  }
+
+  bool isAllocCopyWithZoneCall(ObjCMessageExpr *E) {
+    if (E->getNumArgs() == 1 &&
+        E->getSelector() == allocWithZoneSel &&
+        (E->isClassMessage() ||
+         Pass.TA.hasDiagnostic(diag::err_unavailable_message,
+                               E->getReceiverRange().getBegin())))
+      return true;
+
+    return E->isInstanceMessage() &&
+           E->getNumArgs() == 1   &&
+           (E->getSelector() == copyWithZoneSel ||
+            E->getSelector() == mutableCopyWithZoneSel);
+  }
+
+  bool isZoneCall(ObjCMessageExpr *E) {
+    return E->isInstanceMessage() &&
+           E->getNumArgs() == 0   &&
+           E->getSelector() == zoneSel;
+  }
+
+  bool paramToAllocWithZoneHasSideEffects(Expr *E) {
+    if (!hasSideEffects(E, Pass.Ctx))
+      return false;
+    E = E->IgnoreParenCasts();
+    ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E);
+    if (!ME)
+      return true;
+    if (!isZoneCall(ME))
+      return true;
+    return hasSideEffects(ME->getInstanceReceiver(), Pass.Ctx);
+  }
+
+  void clearUnavailableDiags(Stmt *S) {
+    if (S)
+      Pass.TA.clearDiagnostic(diag::err_unavailable,
+                              diag::err_unavailable_message,
+                              S->getSourceRange());
+  }
+};
+
+} // end anonymous namespace
+
+void trans::rewriteAllocCopyWithZone(MigrationPass &pass) {
+  BodyTransform<AllocCopyWithZoneRewriter> trans(pass);
+  trans.TraverseDecl(pass.Ctx.getTranslationUnitDecl());
+}
diff --git a/lib/ARCMigrate/TransAutoreleasePool.cpp b/lib/ARCMigrate/TransAutoreleasePool.cpp
new file mode 100644
index 0000000..602ac0c
--- /dev/null
+++ b/lib/ARCMigrate/TransAutoreleasePool.cpp
@@ -0,0 +1,437 @@
+//===--- TransAutoreleasePool.cpp - Tranformations to ARC mode ------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// rewriteAutoreleasePool:
+//
+// Calls to NSAutoreleasePools will be rewritten as an @autorelease scope.
+//
+//  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+//  ...
+//  [pool release];
+// ---->
+//  @autorelease {
+//  ...
+//  }
+//
+// An NSAutoreleasePool will not be touched if:
+// - There is not a corresponding -release/-drain in the same scope
+// - Not all references of the NSAutoreleasePool variable can be removed
+// - There is a variable that is declared inside the intended @autorelease scope
+//   which is also used outside it.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Transforms.h"
+#include "Internals.h"
+#include "clang/Sema/SemaDiagnostic.h"
+#include "clang/Basic/SourceManager.h"
+#include <map>
+
+using namespace clang;
+using namespace arcmt;
+using namespace trans;
+using llvm::StringRef;
+
+namespace {
+
+class ReleaseCollector : public RecursiveASTVisitor<ReleaseCollector> {
+  Decl *Dcl;
+  llvm::SmallVectorImpl<ObjCMessageExpr *> &Releases;
+
+public:
+  ReleaseCollector(Decl *D, llvm::SmallVectorImpl<ObjCMessageExpr *> &releases)
+    : Dcl(D), Releases(releases) { }
+
+  bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
+    if (!E->isInstanceMessage())
+      return true;
+    if (E->getMethodFamily() != OMF_release)
+      return true;
+    Expr *instance = E->getInstanceReceiver()->IgnoreParenCasts();
+    if (DeclRefExpr *DE = dyn_cast<DeclRefExpr>(instance)) {
+      if (DE->getDecl() == Dcl)
+        Releases.push_back(E);
+    }
+    return true;
+  }
+};
+
+}
+
+namespace {
+
+class AutoreleasePoolRewriter
+                         : public RecursiveASTVisitor<AutoreleasePoolRewriter> {
+public:
+  AutoreleasePoolRewriter(Decl *D, MigrationPass &pass)
+    : Dcl(D), Body(0), Pass(pass) {
+    PoolII = &pass.Ctx.Idents.get("NSAutoreleasePool");
+    DrainSel = pass.Ctx.Selectors.getNullarySelector(
+                                                 &pass.Ctx.Idents.get("drain"));
+  }
+
+  void transformBody(Stmt *body) {
+    Body = body;
+    TraverseStmt(body);
+  }
+  
+  ~AutoreleasePoolRewriter() {
+    llvm::SmallVector<VarDecl *, 8> VarsToHandle;
+
+    for (std::map<VarDecl *, PoolVarInfo>::iterator
+           I = PoolVars.begin(), E = PoolVars.end(); I != E; ++I) {
+      VarDecl *var = I->first;
+      PoolVarInfo &info = I->second;
+
+      // Check that we can handle/rewrite all references of the pool.
+
+      clearRefsIn(info.Dcl, info.Refs);
+      for (llvm::SmallVectorImpl<PoolScope>::iterator
+             scpI = info.Scopes.begin(),
+             scpE = info.Scopes.end(); scpI != scpE; ++scpI) {
+        PoolScope &scope = *scpI;
+        clearRefsIn(*scope.Begin, info.Refs);
+        clearRefsIn(*scope.End, info.Refs);
+        clearRefsIn(scope.Releases.begin(), scope.Releases.end(), info.Refs);
+      }
+
+      // Even if one reference is not handled we will not do anything about that
+      // pool variable.
+      if (info.Refs.empty())
+        VarsToHandle.push_back(var);
+    }
+
+    for (unsigned i = 0, e = VarsToHandle.size(); i != e; ++i) {
+      PoolVarInfo &info = PoolVars[VarsToHandle[i]];
+
+      Transaction Trans(Pass.TA);
+
+      clearUnavailableDiags(info.Dcl);
+      Pass.TA.removeStmt(info.Dcl);
+
+      // Add "@autoreleasepool { }"
+      for (llvm::SmallVectorImpl<PoolScope>::iterator
+             scpI = info.Scopes.begin(),
+             scpE = info.Scopes.end(); scpI != scpE; ++scpI) {
+        PoolScope &scope = *scpI;
+        clearUnavailableDiags(*scope.Begin);
+        clearUnavailableDiags(*scope.End);
+        if (scope.IsFollowedBySimpleReturnStmt) {
+          // Include the return in the scope.
+          Pass.TA.replaceStmt(*scope.Begin, "@autoreleasepool {");
+          Pass.TA.removeStmt(*scope.End);
+          Stmt::child_iterator retI = scope.End;
+          ++retI;
+          SourceLocation afterSemi = findLocationAfterSemi((*retI)->getLocEnd(),
+                                                           Pass.Ctx);
+          assert(afterSemi.isValid() &&
+                 "Didn't we check before setting IsFollowedBySimpleReturnStmt "
+                 "to true?");
+          Pass.TA.insertAfterToken(afterSemi, "\n}");
+          Pass.TA.increaseIndentation(
+                                SourceRange(scope.getIndentedRange().getBegin(),
+                                            (*retI)->getLocEnd()),
+                                      scope.CompoundParent->getLocStart());
+        } else {
+          Pass.TA.replaceStmt(*scope.Begin, "@autoreleasepool {");
+          Pass.TA.replaceStmt(*scope.End, "}");
+          Pass.TA.increaseIndentation(scope.getIndentedRange(),
+                                      scope.CompoundParent->getLocStart());
+        }
+      }
+
+      // Remove rest of pool var references.
+      for (llvm::SmallVectorImpl<PoolScope>::iterator
+             scpI = info.Scopes.begin(),
+             scpE = info.Scopes.end(); scpI != scpE; ++scpI) {
+        PoolScope &scope = *scpI;
+        for (llvm::SmallVectorImpl<ObjCMessageExpr *>::iterator
+               relI = scope.Releases.begin(),
+               relE = scope.Releases.end(); relI != relE; ++relI) {
+          clearUnavailableDiags(*relI);
+          Pass.TA.removeStmt(*relI);
+        }
+      }
+    }
+  }
+
+  bool VisitCompoundStmt(CompoundStmt *S) {
+    llvm::SmallVector<PoolScope, 4> Scopes;
+
+    for (Stmt::child_iterator
+           I = S->body_begin(), E = S->body_end(); I != E; ++I) {
+      Stmt *child = getEssential(*I);
+      if (DeclStmt *DclS = dyn_cast<DeclStmt>(child)) {
+        if (DclS->isSingleDecl()) {
+          if (VarDecl *VD = dyn_cast<VarDecl>(DclS->getSingleDecl())) {
+            if (isNSAutoreleasePool(VD->getType())) {
+              PoolVarInfo &info = PoolVars[VD];
+              info.Dcl = DclS;
+              collectRefs(VD, S, info.Refs);
+              // Does this statement follow the pattern:  
+              // NSAutoreleasePool * pool = [NSAutoreleasePool  new];
+              if (isPoolCreation(VD->getInit())) {
+                Scopes.push_back(PoolScope());
+                Scopes.back().PoolVar = VD;
+                Scopes.back().CompoundParent = S;
+                Scopes.back().Begin = I;
+              }
+            }
+          }
+        }
+      } else if (BinaryOperator *bop = dyn_cast<BinaryOperator>(child)) {
+        if (DeclRefExpr *dref = dyn_cast<DeclRefExpr>(bop->getLHS())) {
+          if (VarDecl *VD = dyn_cast<VarDecl>(dref->getDecl())) {
+            // Does this statement follow the pattern:  
+            // pool = [NSAutoreleasePool  new];
+            if (isNSAutoreleasePool(VD->getType()) &&
+                isPoolCreation(bop->getRHS())) {
+              Scopes.push_back(PoolScope());
+              Scopes.back().PoolVar = VD;
+              Scopes.back().CompoundParent = S;
+              Scopes.back().Begin = I;
+            }
+          }
+        }
+      }
+
+      if (Scopes.empty())
+        continue;
+
+      if (isPoolDrain(Scopes.back().PoolVar, child)) {
+        PoolScope &scope = Scopes.back();
+        scope.End = I;
+        handlePoolScope(scope, S);
+        Scopes.pop_back();
+      }
+    }
+    return true;
+  }
+
+private:
+  void clearUnavailableDiags(Stmt *S) {
+    if (S)
+      Pass.TA.clearDiagnostic(diag::err_unavailable,
+                              diag::err_unavailable_message,
+                              S->getSourceRange());
+  }
+
+  struct PoolScope {
+    VarDecl *PoolVar;
+    CompoundStmt *CompoundParent;
+    Stmt::child_iterator Begin;
+    Stmt::child_iterator End;
+    bool IsFollowedBySimpleReturnStmt;
+    llvm::SmallVector<ObjCMessageExpr *, 4> Releases;
+
+    PoolScope() : PoolVar(0), CompoundParent(0), Begin(), End(),
+                  IsFollowedBySimpleReturnStmt(false) { }
+
+    SourceRange getIndentedRange() const {
+      Stmt::child_iterator rangeS = Begin;
+      ++rangeS;
+      if (rangeS == End)
+        return SourceRange();
+      Stmt::child_iterator rangeE = Begin;
+      for (Stmt::child_iterator I = rangeS; I != End; ++I)
+        ++rangeE;
+      return SourceRange((*rangeS)->getLocStart(), (*rangeE)->getLocEnd());
+    }
+  };
+
+  class NameReferenceChecker : public RecursiveASTVisitor<NameReferenceChecker>{
+    ASTContext &Ctx;
+    SourceRange ScopeRange;
+    SourceLocation &referenceLoc, &declarationLoc;
+
+  public:
+    NameReferenceChecker(ASTContext &ctx, PoolScope &scope,
+                         SourceLocation &referenceLoc,
+                         SourceLocation &declarationLoc)
+      : Ctx(ctx), referenceLoc(referenceLoc),
+        declarationLoc(declarationLoc) {
+      ScopeRange = SourceRange((*scope.Begin)->getLocStart(),
+                               (*scope.End)->getLocStart());
+    }
+
+    bool VisitDeclRefExpr(DeclRefExpr *E) {
+      return checkRef(E->getLocation(), E->getDecl()->getLocation());
+    }
+
+    bool VisitBlockDeclRefExpr(BlockDeclRefExpr *E) {
+      return checkRef(E->getLocation(), E->getDecl()->getLocation());
+    }
+
+    bool VisitTypedefTypeLoc(TypedefTypeLoc TL) {
+      return checkRef(TL.getBeginLoc(), TL.getTypedefNameDecl()->getLocation());
+    }
+
+    bool VisitTagTypeLoc(TagTypeLoc TL) {
+      return checkRef(TL.getBeginLoc(), TL.getDecl()->getLocation());
+    }
+
+  private:
+    bool checkRef(SourceLocation refLoc, SourceLocation declLoc) {
+      if (isInScope(declLoc)) {
+        referenceLoc = refLoc;
+        declarationLoc = declLoc;
+        return false;
+      }
+      return true;
+    }
+
+    bool isInScope(SourceLocation loc) {
+      SourceManager &SM = Ctx.getSourceManager();
+      if (SM.isBeforeInTranslationUnit(loc, ScopeRange.getBegin()))
+        return false;
+      return SM.isBeforeInTranslationUnit(loc, ScopeRange.getEnd());
+    }
+  };
+
+  void handlePoolScope(PoolScope &scope, CompoundStmt *compoundS) {
+    // Check that all names declared inside the scope are not used
+    // outside the scope.
+    {
+      bool nameUsedOutsideScope = false;
+      SourceLocation referenceLoc, declarationLoc;
+      Stmt::child_iterator SI = scope.End, SE = compoundS->body_end();
+      ++SI;
+      // Check if the autoreleasepool scope is followed by a simple return
+      // statement, in which case we will include the return in the scope.
+      if (SI != SE)
+        if (ReturnStmt *retS = dyn_cast<ReturnStmt>(*SI))
+          if ((retS->getRetValue() == 0 ||
+               isa<DeclRefExpr>(retS->getRetValue()->IgnoreParenCasts())) &&
+              findLocationAfterSemi(retS->getLocEnd(), Pass.Ctx).isValid()) {
+            scope.IsFollowedBySimpleReturnStmt = true;
+            ++SI; // the return will be included in scope, don't check it.
+          }
+      
+      for (; SI != SE; ++SI) {
+        nameUsedOutsideScope = !NameReferenceChecker(Pass.Ctx, scope,
+                                                     referenceLoc,
+                                              declarationLoc).TraverseStmt(*SI);
+        if (nameUsedOutsideScope)
+          break;
+      }
+
+      // If not all references were cleared it means some variables/typenames/etc
+      // declared inside the pool scope are used outside of it.
+      // We won't try to rewrite the pool.
+      if (nameUsedOutsideScope) {
+        Pass.TA.reportError("a name is referenced outside the "
+            "NSAutoreleasePool scope that it was declared in", referenceLoc);
+        Pass.TA.reportNote("name declared here", declarationLoc);
+        Pass.TA.reportNote("intended @autoreleasepool scope begins here",
+                           (*scope.Begin)->getLocStart());
+        Pass.TA.reportNote("intended @autoreleasepool scope ends here",
+                           (*scope.End)->getLocStart());
+        return;
+      }
+    }
+
+    // Collect all releases of the pool; they will be removed.
+    {
+      ReleaseCollector releaseColl(scope.PoolVar, scope.Releases);
+      Stmt::child_iterator I = scope.Begin;
+      ++I;
+      for (; I != scope.End; ++I)
+        releaseColl.TraverseStmt(*I);
+    }
+
+    PoolVars[scope.PoolVar].Scopes.push_back(scope);
+  }
+
+  bool isPoolCreation(Expr *E) {
+    if (!E) return false;
+    E = getEssential(E);
+    ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E);
+    if (!ME) return false;
+    if (ME->getMethodFamily() == OMF_new &&
+        ME->getReceiverKind() == ObjCMessageExpr::Class &&
+        isNSAutoreleasePool(ME->getReceiverInterface()))
+      return true;
+    if (ME->getReceiverKind() == ObjCMessageExpr::Instance &&
+        ME->getMethodFamily() == OMF_init) {
+      Expr *rec = getEssential(ME->getInstanceReceiver());
+      if (ObjCMessageExpr *recME = dyn_cast_or_null<ObjCMessageExpr>(rec)) {
+        if (recME->getMethodFamily() == OMF_alloc &&
+            recME->getReceiverKind() == ObjCMessageExpr::Class &&
+            isNSAutoreleasePool(recME->getReceiverInterface()))
+          return true;
+      }
+    }
+
+    return false;
+  }
+
+  bool isPoolDrain(VarDecl *poolVar, Stmt *S) {
+    if (!S) return false;
+    S = getEssential(S);
+    ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(S);
+    if (!ME) return false;
+    if (ME->getReceiverKind() == ObjCMessageExpr::Instance) {
+      Expr *rec = getEssential(ME->getInstanceReceiver());
+      if (DeclRefExpr *dref = dyn_cast<DeclRefExpr>(rec))
+        if (dref->getDecl() == poolVar)
+          return ME->getMethodFamily() == OMF_release ||
+                 ME->getSelector() == DrainSel;
+    }
+
+    return false;
+  }
+
+  bool isNSAutoreleasePool(ObjCInterfaceDecl *IDecl) {
+    return IDecl && IDecl->getIdentifier() == PoolII;
+  }
+
+  bool isNSAutoreleasePool(QualType Ty) {
+    QualType pointee = Ty->getPointeeType();
+    if (pointee.isNull())
+      return false;
+    if (const ObjCInterfaceType *interT = pointee->getAs<ObjCInterfaceType>())
+      return isNSAutoreleasePool(interT->getDecl());
+    return false;
+  }
+
+  static Expr *getEssential(Expr *E) {
+    return cast<Expr>(getEssential((Stmt*)E));
+  }
+  static Stmt *getEssential(Stmt *S) {
+    if (ExprWithCleanups *EWC = dyn_cast<ExprWithCleanups>(S))
+      S = EWC->getSubExpr();
+    if (Expr *E = dyn_cast<Expr>(S))
+      S = E->IgnoreParenCasts();
+    return S;
+  }
+
+  Decl *Dcl;
+  Stmt *Body;
+  MigrationPass &Pass;
+
+  IdentifierInfo *PoolII;
+  Selector DrainSel;
+  
+  struct PoolVarInfo {
+    DeclStmt *Dcl;
+    ExprSet Refs;
+    llvm::SmallVector<PoolScope, 2> Scopes;
+
+    PoolVarInfo() : Dcl(0) { }
+  };
+
+  std::map<VarDecl *, PoolVarInfo> PoolVars;
+};
+
+} // anonymous namespace
+
+void trans::rewriteAutoreleasePool(MigrationPass &pass) {
+  BodyTransform<AutoreleasePoolRewriter> trans(pass);
+  trans.TraverseDecl(pass.Ctx.getTranslationUnitDecl());
+}
diff --git a/lib/ARCMigrate/TransBlockObjCVariable.cpp b/lib/ARCMigrate/TransBlockObjCVariable.cpp
new file mode 100644
index 0000000..ba55627
--- /dev/null
+++ b/lib/ARCMigrate/TransBlockObjCVariable.cpp
@@ -0,0 +1,143 @@
+//===--- TransBlockObjCVariable.cpp - Tranformations to ARC mode ----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// rewriteBlockObjCVariable:
+//
+// Adding __block to an obj-c variable could be either because the the variable
+// is used for output storage or the user wanted to break a retain cycle.
+// This transformation checks whether a reference of the variable for the block
+// is actually needed (it is assigned to or its address is taken) or not.
+// If the reference is not needed it will assume __block was added to break a
+// cycle so it will remove '__block' and add __weak/__unsafe_unretained.
+// e.g
+//
+//   __block Foo *x;
+//   bar(^ { [x cake]; });
+// ---->
+//   __weak Foo *x;
+//   bar(^ { [x cake]; });
+//
+//===----------------------------------------------------------------------===//
+
+#include "Transforms.h"
+#include "Internals.h"
+#include "clang/Basic/SourceManager.h"
+
+using namespace clang;
+using namespace arcmt;
+using namespace trans;
+using llvm::StringRef;
+
+namespace {
+
+class RootBlockObjCVarRewriter :
+                          public RecursiveASTVisitor<RootBlockObjCVarRewriter> {
+  MigrationPass &Pass;
+  llvm::DenseSet<VarDecl *> CheckedVars;
+
+  class BlockVarChecker : public RecursiveASTVisitor<BlockVarChecker> {
+    VarDecl *Var;
+  
+    typedef RecursiveASTVisitor<BlockVarChecker> base;
+  public:
+    BlockVarChecker(VarDecl *var) : Var(var) { }
+  
+    bool TraverseImplicitCastExpr(ImplicitCastExpr *castE) {
+      if (BlockDeclRefExpr *
+            ref = dyn_cast<BlockDeclRefExpr>(castE->getSubExpr())) {
+        if (ref->getDecl() == Var) {
+          if (castE->getCastKind() == CK_LValueToRValue)
+            return true; // Using the value of the variable.
+          if (castE->getCastKind() == CK_NoOp && castE->isLValue() &&
+              Var->getASTContext().getLangOptions().CPlusPlus)
+            return true; // Binding to const C++ reference.
+        }
+      }
+
+      return base::TraverseImplicitCastExpr(castE);
+    }
+
+    bool VisitBlockDeclRefExpr(BlockDeclRefExpr *E) {
+      if (E->getDecl() == Var)
+        return false; // The reference of the variable, and not just its value,
+                      //  is needed.
+      return true;
+    }
+  };
+
+public:
+  RootBlockObjCVarRewriter(MigrationPass &pass) : Pass(pass) { }
+
+  bool VisitBlockDecl(BlockDecl *block) {
+    llvm::SmallVector<VarDecl *, 4> BlockVars;
+    
+    for (BlockDecl::capture_iterator
+           I = block->capture_begin(), E = block->capture_end(); I != E; ++I) {
+      VarDecl *var = I->getVariable();
+      if (I->isByRef() &&
+          !isAlreadyChecked(var) &&
+          var->getType()->isObjCObjectPointerType() &&
+          isImplicitStrong(var->getType())) {
+        BlockVars.push_back(var);
+      }
+    }
+
+    for (unsigned i = 0, e = BlockVars.size(); i != e; ++i) {
+      VarDecl *var = BlockVars[i];
+      CheckedVars.insert(var);
+
+      BlockVarChecker checker(var);
+      bool onlyValueOfVarIsNeeded = checker.TraverseStmt(block->getBody());
+      if (onlyValueOfVarIsNeeded) {
+        BlocksAttr *attr = var->getAttr<BlocksAttr>();
+        if(!attr)
+          continue;
+        bool hasARCRuntime = !Pass.Ctx.getLangOptions().ObjCNoAutoRefCountRuntime;
+        SourceManager &SM = Pass.Ctx.getSourceManager();
+        Transaction Trans(Pass.TA);
+        Pass.TA.replaceText(SM.getInstantiationLoc(attr->getLocation()),
+                            "__block",
+                            hasARCRuntime ? "__weak" : "__unsafe_unretained");
+      }
+
+    }
+
+    return true;
+  }
+
+private:
+  bool isAlreadyChecked(VarDecl *VD) {
+    return CheckedVars.count(VD);
+  }
+
+  bool isImplicitStrong(QualType ty) {
+    if (isa<AttributedType>(ty.getTypePtr()))
+      return false;
+    return ty.getLocalQualifiers().getObjCLifetime() == Qualifiers::OCL_Strong;
+  }
+};
+
+class BlockObjCVarRewriter : public RecursiveASTVisitor<BlockObjCVarRewriter> {
+  MigrationPass &Pass;
+
+public:
+  BlockObjCVarRewriter(MigrationPass &pass) : Pass(pass) { }
+
+  bool TraverseBlockDecl(BlockDecl *block) {
+    RootBlockObjCVarRewriter(Pass).TraverseDecl(block);
+    return true;
+  }
+};
+
+} // anonymous namespace
+
+void trans::rewriteBlockObjCVariable(MigrationPass &pass) {
+  BlockObjCVarRewriter trans(pass);
+  trans.TraverseDecl(pass.Ctx.getTranslationUnitDecl());
+}
diff --git a/lib/ARCMigrate/TransDeallocMethod.cpp b/lib/ARCMigrate/TransDeallocMethod.cpp
new file mode 100644
index 0000000..a7c3c1e
--- /dev/null
+++ b/lib/ARCMigrate/TransDeallocMethod.cpp
@@ -0,0 +1,47 @@
+//===--- TransDeallocMethod.cpp - Tranformations to ARC mode --------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Transforms.h"
+#include "Internals.h"
+
+using namespace clang;
+using namespace arcmt;
+using namespace trans;
+using llvm::StringRef;
+
+void trans::removeDeallocMethod(MigrationPass &pass) {
+  ASTContext &Ctx = pass.Ctx;
+  TransformActions &TA = pass.TA;
+  DeclContext *DC = Ctx.getTranslationUnitDecl();
+  ObjCMethodDecl *DeallocMethodDecl = 0;
+  IdentifierInfo *II = &Ctx.Idents.get("dealloc");
+
+  for (DeclContext::decl_iterator
+         I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) {
+    Decl *D = *I;
+    if (ObjCImplementationDecl *IMD = dyn_cast<ObjCImplementationDecl>(D)) {
+      DeallocMethodDecl = 0;
+      for (ObjCImplementationDecl::instmeth_iterator
+             I = IMD->instmeth_begin(), E = IMD->instmeth_end();
+          I != E; ++I) {
+        ObjCMethodDecl *OMD = *I;
+        if (OMD->isInstanceMethod() &&
+            OMD->getSelector() == Ctx.Selectors.getSelector(0, &II)) {
+          DeallocMethodDecl = OMD;
+          break;
+        }
+      }
+      if (DeallocMethodDecl && 
+          DeallocMethodDecl->getCompoundBody()->body_empty()) {
+        Transaction Trans(TA);
+        TA.remove(DeallocMethodDecl->getSourceRange());
+      }
+    }
+  }
+}
diff --git a/lib/ARCMigrate/TransEmptyStatements.cpp b/lib/ARCMigrate/TransEmptyStatements.cpp
new file mode 100644
index 0000000..1b62bbf
--- /dev/null
+++ b/lib/ARCMigrate/TransEmptyStatements.cpp
@@ -0,0 +1,161 @@
+//===--- TransEmptyStatements.cpp - Tranformations to ARC mode ------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// removeEmptyStatements:
+//
+// Removes empty statements that are leftovers from previous transformations.
+// e.g for
+//
+//  [x retain];
+//
+// removeRetainReleaseDealloc will leave an empty ";" that removeEmptyStatements
+// will remove.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Transforms.h"
+#include "Internals.h"
+#include "clang/AST/StmtVisitor.h"
+
+using namespace clang;
+using namespace arcmt;
+using namespace trans;
+using llvm::StringRef;
+
+namespace {
+
+class EmptyStatementsRemover :
+                            public RecursiveASTVisitor<EmptyStatementsRemover> {
+  MigrationPass &Pass;
+  llvm::DenseSet<unsigned> MacroLocs;
+
+public:
+  EmptyStatementsRemover(MigrationPass &pass) : Pass(pass) {
+    for (unsigned i = 0, e = Pass.ARCMTMacroLocs.size(); i != e; ++i)
+      MacroLocs.insert(Pass.ARCMTMacroLocs[i].getRawEncoding());
+  }
+
+  bool TraverseStmtExpr(StmtExpr *E) {
+    CompoundStmt *S = E->getSubStmt();
+    for (CompoundStmt::body_iterator
+           I = S->body_begin(), E = S->body_end(); I != E; ++I) {
+      if (I != E - 1)
+        check(*I);
+      TraverseStmt(*I);
+    }
+    return true;
+  }
+
+  bool VisitCompoundStmt(CompoundStmt *S) {
+    for (CompoundStmt::body_iterator
+           I = S->body_begin(), E = S->body_end(); I != E; ++I)
+      check(*I);
+    return true;
+  }
+
+  bool isMacroLoc(SourceLocation loc) {
+    if (loc.isInvalid()) return false;
+    return MacroLocs.count(loc.getRawEncoding());
+  }
+
+  ASTContext &getContext() { return Pass.Ctx; }
+
+private:
+  /// \brief Returns true if the statement became empty due to previous
+  /// transformations.
+  class EmptyChecker : public StmtVisitor<EmptyChecker, bool> {
+    EmptyStatementsRemover &Trans;
+
+  public:
+    EmptyChecker(EmptyStatementsRemover &trans) : Trans(trans) { }
+
+    bool VisitNullStmt(NullStmt *S) {
+      return Trans.isMacroLoc(S->getLeadingEmptyMacroLoc());
+    }
+    bool VisitCompoundStmt(CompoundStmt *S) {
+      if (S->body_empty())
+        return false; // was already empty, not because of transformations.
+      for (CompoundStmt::body_iterator
+             I = S->body_begin(), E = S->body_end(); I != E; ++I)
+        if (!Visit(*I))
+          return false;
+      return true;
+    }
+    bool VisitIfStmt(IfStmt *S) {
+      if (S->getConditionVariable())
+        return false;
+      Expr *condE = S->getCond();
+      if (!condE)
+        return false;
+      if (hasSideEffects(condE, Trans.getContext()))
+        return false;
+      if (!S->getThen() || !Visit(S->getThen()))
+        return false;
+      if (S->getElse() && !Visit(S->getElse()))
+        return false;
+      return true;
+    }
+    bool VisitWhileStmt(WhileStmt *S) {
+      if (S->getConditionVariable())
+        return false;
+      Expr *condE = S->getCond();
+      if (!condE)
+        return false;
+      if (hasSideEffects(condE, Trans.getContext()))
+        return false;
+      if (!S->getBody())
+        return false;
+      return Visit(S->getBody());
+    }
+    bool VisitDoStmt(DoStmt *S) {
+      Expr *condE = S->getCond();
+      if (!condE)
+        return false;
+      if (hasSideEffects(condE, Trans.getContext()))
+        return false;
+      if (!S->getBody())
+        return false;
+      return Visit(S->getBody());
+    }
+    bool VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
+      Expr *Exp = S->getCollection();
+      if (!Exp)
+        return false;
+      if (hasSideEffects(Exp, Trans.getContext()))
+        return false;
+      if (!S->getBody())
+        return false;
+      return Visit(S->getBody());
+    }
+    bool VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S) {
+      if (!S->getSubStmt())
+        return false;
+      return Visit(S->getSubStmt());
+    }
+  };
+
+  void check(Stmt *S) {
+    if (!S) return;
+    if (EmptyChecker(*this).Visit(S)) {
+      Transaction Trans(Pass.TA);
+      Pass.TA.removeStmt(S);
+    }
+  }
+};
+
+} // anonymous namespace
+
+void trans::removeEmptyStatements(MigrationPass &pass) {
+  EmptyStatementsRemover(pass).TraverseDecl(pass.Ctx.getTranslationUnitDecl());
+
+  for (unsigned i = 0, e = pass.ARCMTMacroLocs.size(); i != e; ++i) {
+    Transaction Trans(pass.TA);
+    pass.TA.remove(pass.ARCMTMacroLocs[i]);
+  }
+}
diff --git a/lib/ARCMigrate/TransProperties.cpp b/lib/ARCMigrate/TransProperties.cpp
new file mode 100644
index 0000000..2122e03
--- /dev/null
+++ b/lib/ARCMigrate/TransProperties.cpp
@@ -0,0 +1,260 @@
+//===--- TransProperties.cpp - Tranformations to ARC mode -----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// changeIvarsOfAssignProperties:
+//
+// If a property is synthesized with 'assign' attribute and the user didn't
+// set a lifetime attribute, change the property to 'weak' or add
+// __unsafe_unretained if the ARC runtime is not available.
+//
+//  @interface Foo : NSObject {
+//      NSObject *x;
+//  }
+//  @property (assign) id x;
+//  @end
+// ---->
+//  @interface Foo : NSObject {
+//      NSObject *__weak x;
+//  }
+//  @property (weak) id x;
+//  @end
+//
+//===----------------------------------------------------------------------===//
+
+#include "Transforms.h"
+#include "Internals.h"
+#include "clang/Sema/SemaDiagnostic.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Lex/Lexer.h"
+
+using namespace clang;
+using namespace arcmt;
+using namespace trans;
+using llvm::StringRef;
+
+namespace {
+
+class AssignPropertiesTrans {
+  MigrationPass &Pass;
+  struct PropData {
+    ObjCPropertyDecl *PropD;
+    ObjCIvarDecl *IvarD;
+    bool ShouldChangeToWeak;
+    SourceLocation ArcPropAssignErrorLoc;
+  };
+
+  typedef llvm::SmallVector<PropData, 2> PropsTy; 
+  typedef llvm::DenseMap<unsigned, PropsTy> PropsMapTy;
+  PropsMapTy PropsMap;
+
+public:
+  AssignPropertiesTrans(MigrationPass &pass) : Pass(pass) { }
+
+  void doTransform(ObjCImplementationDecl *D) {
+    SourceManager &SM = Pass.Ctx.getSourceManager();
+
+    ObjCInterfaceDecl *IFace = D->getClassInterface();
+    for (ObjCInterfaceDecl::prop_iterator
+           I = IFace->prop_begin(), E = IFace->prop_end(); I != E; ++I) {
+      ObjCPropertyDecl *propD = *I;
+      unsigned loc = SM.getInstantiationLoc(propD->getAtLoc()).getRawEncoding();
+      PropsTy &props = PropsMap[loc];
+      props.push_back(PropData());
+      props.back().PropD = propD;
+      props.back().IvarD = 0;
+      props.back().ShouldChangeToWeak = false;
+    }
+
+    typedef DeclContext::specific_decl_iterator<ObjCPropertyImplDecl>
+        prop_impl_iterator;
+    for (prop_impl_iterator
+           I = prop_impl_iterator(D->decls_begin()),
+           E = prop_impl_iterator(D->decls_end()); I != E; ++I) {
+      VisitObjCPropertyImplDecl(*I);
+    }
+
+    for (PropsMapTy::iterator
+           I = PropsMap.begin(), E = PropsMap.end(); I != E; ++I) {
+      SourceLocation atLoc = SourceLocation::getFromRawEncoding(I->first);
+      PropsTy &props = I->second;
+      if (shouldApplyWeakToAllProp(props)) {
+        if (changeAssignToWeak(atLoc)) {
+          // Couldn't add the 'weak' property attribute,
+          // try adding __unsafe_unretained.
+          applyUnsafeUnretained(props);
+        } else {
+          for (PropsTy::iterator
+                 PI = props.begin(), PE = props.end(); PI != PE; ++PI) {
+            applyWeak(*PI);
+          }
+        }
+      } else {
+        // We should not add 'weak' attribute since not all properties need it.
+        // So just add __unsafe_unretained to the ivars.
+        applyUnsafeUnretained(props);
+      }
+    }
+  }
+
+  bool shouldApplyWeakToAllProp(PropsTy &props) {
+    for (PropsTy::iterator
+           PI = props.begin(), PE = props.end(); PI != PE; ++PI) {
+      if (!PI->ShouldChangeToWeak)
+        return false;
+    }
+    return true;
+  }
+
+  void applyWeak(PropData &prop) {
+    assert(!Pass.Ctx.getLangOptions().ObjCNoAutoRefCountRuntime);
+
+    Transaction Trans(Pass.TA);
+    Pass.TA.insert(prop.IvarD->getLocation(), "__weak "); 
+    Pass.TA.clearDiagnostic(diag::err_arc_assign_property_lifetime,
+                            prop.ArcPropAssignErrorLoc);
+  }
+
+  void applyUnsafeUnretained(PropsTy &props) {
+    for (PropsTy::iterator
+           PI = props.begin(), PE = props.end(); PI != PE; ++PI) {
+      if (PI->ShouldChangeToWeak) {
+        Transaction Trans(Pass.TA);
+        Pass.TA.insert(PI->IvarD->getLocation(), "__unsafe_unretained ");
+        Pass.TA.clearDiagnostic(diag::err_arc_assign_property_lifetime,
+                                PI->ArcPropAssignErrorLoc);
+      }
+    }
+  }
+
+  bool VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
+    SourceManager &SM = Pass.Ctx.getSourceManager();
+
+    if (D->getPropertyImplementation() != ObjCPropertyImplDecl::Synthesize)
+      return true;
+    ObjCPropertyDecl *propD = D->getPropertyDecl();
+    if (!propD || propD->isInvalidDecl())
+      return true;
+    ObjCIvarDecl *ivarD = D->getPropertyIvarDecl();
+    if (!ivarD || ivarD->isInvalidDecl())
+      return true;
+    if (!(propD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_assign))
+      return true;
+    if (isa<AttributedType>(ivarD->getType().getTypePtr()))
+      return true;
+    if (ivarD->getType().getLocalQualifiers().getObjCLifetime()
+          != Qualifiers::OCL_Strong)
+      return true;
+    if (!Pass.TA.hasDiagnostic(
+                      diag::err_arc_assign_property_lifetime, D->getLocation()))
+      return true;
+
+    // There is a "error: existing ivar for assign property must be
+    // __unsafe_unretained"; fix it.
+
+    if (Pass.Ctx.getLangOptions().ObjCNoAutoRefCountRuntime) {
+      // We will just add __unsafe_unretained to the ivar.
+      Transaction Trans(Pass.TA);
+      Pass.TA.insert(ivarD->getLocation(), "__unsafe_unretained ");
+      Pass.TA.clearDiagnostic(
+                      diag::err_arc_assign_property_lifetime, D->getLocation());
+    } else {
+      // Mark that we want the ivar to become weak.
+      unsigned loc = SM.getInstantiationLoc(propD->getAtLoc()).getRawEncoding();
+      PropsTy &props = PropsMap[loc];
+      for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) {
+        if (I->PropD == propD) {
+          I->IvarD = ivarD;
+          I->ShouldChangeToWeak = true;
+          I->ArcPropAssignErrorLoc = D->getLocation();
+        }
+      }
+    }
+
+    return true;
+  }
+
+private:
+  bool changeAssignToWeak(SourceLocation atLoc) {
+    SourceManager &SM = Pass.Ctx.getSourceManager();
+
+    // Break down the source location.
+    std::pair<FileID, unsigned> locInfo = SM.getDecomposedLoc(atLoc);
+
+    // Try to load the file buffer.
+    bool invalidTemp = false;
+    llvm::StringRef file = SM.getBufferData(locInfo.first, &invalidTemp);
+    if (invalidTemp)
+      return true;
+
+    const char *tokenBegin = file.data() + locInfo.second;
+
+    // Lex from the start of the given location.
+    Lexer lexer(SM.getLocForStartOfFile(locInfo.first),
+                Pass.Ctx.getLangOptions(),
+                file.begin(), tokenBegin, file.end());
+    Token tok;
+    lexer.LexFromRawLexer(tok);
+    if (tok.isNot(tok::at)) return true;
+    lexer.LexFromRawLexer(tok);
+    if (tok.isNot(tok::raw_identifier)) return true;
+    if (llvm::StringRef(tok.getRawIdentifierData(), tok.getLength())
+          != "property")
+      return true;
+    lexer.LexFromRawLexer(tok);
+    if (tok.isNot(tok::l_paren)) return true;
+    
+    SourceLocation LParen = tok.getLocation();
+    SourceLocation assignLoc;
+    bool isEmpty = false;
+
+    lexer.LexFromRawLexer(tok);
+    if (tok.is(tok::r_paren)) {
+      isEmpty = true;
+    } else {
+      while (1) {
+        if (tok.isNot(tok::raw_identifier)) return true;
+        llvm::StringRef ident(tok.getRawIdentifierData(), tok.getLength());
+        if (ident == "assign")
+          assignLoc = tok.getLocation();
+  
+        do {
+          lexer.LexFromRawLexer(tok);
+        } while (tok.isNot(tok::comma) && tok.isNot(tok::r_paren));
+        if (tok.is(tok::r_paren))
+          break;
+        lexer.LexFromRawLexer(tok);
+      }
+    }
+
+    Transaction Trans(Pass.TA);
+    if (assignLoc.isValid())
+      Pass.TA.replaceText(assignLoc, "assign", "weak");
+    else 
+      Pass.TA.insertAfterToken(LParen, isEmpty ? "weak" : "weak, ");
+    return false;
+  }
+};
+
+class PropertiesChecker : public RecursiveASTVisitor<PropertiesChecker> {
+  MigrationPass &Pass;
+
+public:
+  PropertiesChecker(MigrationPass &pass) : Pass(pass) { }
+
+  bool TraverseObjCImplementationDecl(ObjCImplementationDecl *D) {
+    AssignPropertiesTrans(Pass).doTransform(D);
+    return true;
+  }
+};
+
+} // anonymous namespace
+
+void trans::changeIvarsOfAssignProperties(MigrationPass &pass) {
+  PropertiesChecker(pass).TraverseDecl(pass.Ctx.getTranslationUnitDecl());
+}
diff --git a/lib/ARCMigrate/TransRetainReleaseDealloc.cpp b/lib/ARCMigrate/TransRetainReleaseDealloc.cpp
new file mode 100644
index 0000000..f03ab5a
--- /dev/null
+++ b/lib/ARCMigrate/TransRetainReleaseDealloc.cpp
@@ -0,0 +1,142 @@
+//===--- TransRetainReleaseDealloc.cpp - Tranformations to ARC mode -------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// removeRetainReleaseDealloc:
+//
+// Removes retain/release/autorelease/dealloc messages.
+//
+//  return [[foo retain] autorelease];
+// ---->
+//  return foo;
+//
+//===----------------------------------------------------------------------===//
+
+#include "Transforms.h"
+#include "Internals.h"
+#include "clang/Sema/SemaDiagnostic.h"
+#include "clang/AST/ParentMap.h"
+
+using namespace clang;
+using namespace arcmt;
+using namespace trans;
+using llvm::StringRef;
+
+namespace {
+
+class RetainReleaseDeallocRemover :
+                       public RecursiveASTVisitor<RetainReleaseDeallocRemover> {
+  Decl *Dcl;
+  Stmt *Body;
+  MigrationPass &Pass;
+
+  ExprSet Removables;
+  llvm::OwningPtr<ParentMap> StmtMap;
+
+public:
+  RetainReleaseDeallocRemover(Decl *D, MigrationPass &pass)
+    : Dcl(D), Body(0), Pass(pass) { }
+
+  void transformBody(Stmt *body) {
+    Body = body;
+    collectRemovables(body, Removables);
+    StmtMap.reset(new ParentMap(body));
+    TraverseStmt(body);
+  }
+
+  bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
+    switch (E->getMethodFamily()) {
+    default:
+      return true;
+    case OMF_retain:
+    case OMF_release:
+    case OMF_autorelease:
+      if (E->getReceiverKind() == ObjCMessageExpr::Instance)
+        if (Expr *rec = E->getInstanceReceiver()) {
+          rec = rec->IgnoreParenImpCasts();
+          if (rec->getType().getObjCLifetime() == Qualifiers::OCL_ExplicitNone){
+            std::string err = "It is not safe to remove '";
+            err += E->getSelector().getAsString() + "' message on "
+                "an __unsafe_unretained type";
+            Pass.TA.reportError(err, rec->getLocStart());
+            return true;
+          }
+        }
+    case OMF_dealloc:
+      break;
+    }
+
+    switch (E->getReceiverKind()) {
+    default:
+      return true;
+    case ObjCMessageExpr::SuperInstance: {
+      Transaction Trans(Pass.TA);
+      Pass.TA.clearDiagnostic(diag::err_arc_illegal_explicit_message,
+                              diag::err_unavailable,
+                              diag::err_unavailable_message,
+                              E->getSuperLoc());
+      if (tryRemoving(E))
+        return true;
+      Pass.TA.replace(E->getSourceRange(), "self");
+      return true;
+    }
+    case ObjCMessageExpr::Instance:
+      break;
+    }
+
+    Expr *rec = E->getInstanceReceiver();
+    if (!rec) return true;
+
+    Transaction Trans(Pass.TA);
+    Pass.TA.clearDiagnostic(diag::err_arc_illegal_explicit_message,
+                            diag::err_unavailable,
+                            diag::err_unavailable_message,
+                            rec->getExprLoc());
+    if (!hasSideEffects(E, Pass.Ctx)) {
+      if (tryRemoving(E))
+        return true;
+    }
+    Pass.TA.replace(E->getSourceRange(), rec->getSourceRange());
+
+    return true;
+  }
+
+private:
+  bool isRemovable(Expr *E) const {
+    return Removables.count(E);
+  }
+  
+  bool tryRemoving(Expr *E) const {
+    if (isRemovable(E)) {
+      Pass.TA.removeStmt(E);
+      return true;
+    }
+
+    if (ParenExpr *parenE = dyn_cast_or_null<ParenExpr>(StmtMap->getParent(E)))
+      return tryRemoving(parenE);
+
+    if (BinaryOperator *
+          bopE = dyn_cast_or_null<BinaryOperator>(StmtMap->getParent(E))) {
+      if (bopE->getOpcode() == BO_Comma && bopE->getLHS() == E &&
+          isRemovable(bopE)) {
+        Pass.TA.replace(bopE->getSourceRange(), bopE->getRHS()->getSourceRange());
+        return true;
+      }
+    }
+
+    return false;
+  }
+
+};
+
+} // anonymous namespace
+
+void trans::removeRetainReleaseDealloc(MigrationPass &pass) {
+  BodyTransform<RetainReleaseDeallocRemover> trans(pass);
+  trans.TraverseDecl(pass.Ctx.getTranslationUnitDecl());
+}
diff --git a/lib/ARCMigrate/TransUnbridgedCasts.cpp b/lib/ARCMigrate/TransUnbridgedCasts.cpp
new file mode 100644
index 0000000..6513d98
--- /dev/null
+++ b/lib/ARCMigrate/TransUnbridgedCasts.cpp
@@ -0,0 +1,214 @@
+//===--- TransUnbridgedCasts.cpp - Tranformations to ARC mode -------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// rewriteUnbridgedCasts:
+//
+// A cast of non-objc pointer to an objc one is checked. If the non-objc pointer
+// is from a file-level variable, __bridge cast is used to convert it.
+// For the result of a function call that we know is +1/+0,
+// __bridge/__bridge_transfer is used.
+//
+//  NSString *str = (NSString *)kUTTypePlainText;
+//  str = b ? kUTTypeRTF : kUTTypePlainText;
+//  NSString *_uuidString = (NSString *)CFUUIDCreateString(kCFAllocatorDefault,
+//                                                         _uuid);
+// ---->
+//  NSString *str = (__bridge NSString *)kUTTypePlainText;
+//  str = (__bridge NSString *)(b ? kUTTypeRTF : kUTTypePlainText);
+// NSString *_uuidString = (__bridge_transfer NSString *)
+//                               CFUUIDCreateString(kCFAllocatorDefault, _uuid);
+//
+// For a C pointer to ObjC, for casting 'self', __bridge is used.
+//
+//  CFStringRef str = (CFStringRef)self;
+// ---->
+//  CFStringRef str = (__bridge CFStringRef)self;
+//
+//===----------------------------------------------------------------------===//
+
+#include "Transforms.h"
+#include "Internals.h"
+#include "clang/Analysis/DomainSpecific/CocoaConventions.h"
+#include "clang/Sema/SemaDiagnostic.h"
+#include "clang/Basic/SourceManager.h"
+
+using namespace clang;
+using namespace arcmt;
+using namespace trans;
+using llvm::StringRef;
+
+namespace {
+
+class UnbridgedCastRewriter : public RecursiveASTVisitor<UnbridgedCastRewriter>{
+  MigrationPass &Pass;
+  IdentifierInfo *SelfII;
+public:
+  UnbridgedCastRewriter(MigrationPass &pass) : Pass(pass) {
+    SelfII = &Pass.Ctx.Idents.get("self");
+  }
+
+  bool VisitCastExpr(CastExpr *E) {
+    if (E->getCastKind() != CK_AnyPointerToObjCPointerCast
+        && E->getCastKind() != CK_BitCast)
+      return true;
+
+    QualType castType = E->getType();
+    Expr *castExpr = E->getSubExpr();
+    QualType castExprType = castExpr->getType();
+
+    if (castType->isObjCObjectPointerType() &&
+        castExprType->isObjCObjectPointerType())
+      return true;
+    if (!castType->isObjCObjectPointerType() &&
+        !castExprType->isObjCObjectPointerType())
+      return true;
+    
+    bool exprRetainable = castExprType->isObjCIndirectLifetimeType();
+    bool castRetainable = castType->isObjCIndirectLifetimeType();
+    if (exprRetainable == castRetainable) return true;
+
+    if (castExpr->isNullPointerConstant(Pass.Ctx,
+                                        Expr::NPC_ValueDependentIsNull))
+      return true;
+
+    SourceLocation loc = castExpr->getExprLoc();
+    if (loc.isValid() && Pass.Ctx.getSourceManager().isInSystemHeader(loc))
+      return true;
+
+    if (castType->isObjCObjectPointerType())
+      transformNonObjCToObjCCast(E);
+    else
+      transformObjCToNonObjCCast(E);
+
+    return true;
+  }
+
+private:
+  void transformNonObjCToObjCCast(CastExpr *E) {
+    if (!E) return;
+
+    // Global vars are assumed that are cast as unretained.
+    if (isGlobalVar(E))
+      if (E->getSubExpr()->getType()->isPointerType()) {
+        castToObjCObject(E, /*retained=*/false);
+        return;
+      }
+
+    // If the cast is directly over the result of a Core Foundation function
+    // try to figure out whether it should be cast as retained or unretained.
+    Expr *inner = E->IgnoreParenCasts();
+    if (CallExpr *callE = dyn_cast<CallExpr>(inner)) {
+      if (FunctionDecl *FD = callE->getDirectCallee()) {
+        if (FD->getAttr<CFReturnsRetainedAttr>()) {
+          castToObjCObject(E, /*retained=*/true);
+          return;
+        }
+        if (FD->getAttr<CFReturnsNotRetainedAttr>()) {
+          castToObjCObject(E, /*retained=*/false);
+          return;
+        }
+        if (FD->isGlobal() &&
+            FD->getIdentifier() &&
+            ento::cocoa::isRefType(E->getSubExpr()->getType(), "CF",
+                                   FD->getIdentifier()->getName())) {
+          StringRef fname = FD->getIdentifier()->getName();
+          if (fname.endswith("Retain") ||
+              fname.find("Create") != StringRef::npos ||
+              fname.find("Copy") != StringRef::npos) {
+            castToObjCObject(E, /*retained=*/true);
+            return;
+          }
+
+          if (fname.find("Get") != StringRef::npos) {
+            castToObjCObject(E, /*retained=*/false);
+            return;
+          }
+        }
+      }
+    }
+  }
+
+  void castToObjCObject(CastExpr *E, bool retained) {
+    rewriteToBridgedCast(E, retained ? OBC_BridgeTransfer : OBC_Bridge);
+  }
+
+  void rewriteToBridgedCast(CastExpr *E, ObjCBridgeCastKind Kind) {
+    TransformActions &TA = Pass.TA;
+
+    // We will remove the compiler diagnostic.
+    if (!TA.hasDiagnostic(diag::err_arc_mismatched_cast,
+                          diag::err_arc_cast_requires_bridge,
+                          E->getLocStart()))
+      return;
+
+    StringRef bridge;
+    switch(Kind) {
+    case OBC_Bridge:
+      bridge = "__bridge "; break;
+    case OBC_BridgeTransfer:
+      bridge = "__bridge_transfer "; break;
+    case OBC_BridgeRetained:
+      bridge = "__bridge_retained "; break;
+    }
+
+    Transaction Trans(TA);
+    TA.clearDiagnostic(diag::err_arc_mismatched_cast,
+                       diag::err_arc_cast_requires_bridge,
+                       E->getLocStart());
+    if (CStyleCastExpr *CCE = dyn_cast<CStyleCastExpr>(E)) {
+      TA.insertAfterToken(CCE->getLParenLoc(), bridge);
+    } else {
+      SourceLocation insertLoc = E->getSubExpr()->getLocStart();
+      llvm::SmallString<128> newCast;
+      newCast += '(';
+      newCast += bridge;
+      newCast += E->getType().getAsString(Pass.Ctx.PrintingPolicy);
+      newCast += ')';
+
+      if (isa<ParenExpr>(E->getSubExpr())) {
+        TA.insert(insertLoc, newCast.str());
+      } else {
+        newCast += '(';
+        TA.insert(insertLoc, newCast.str());
+        TA.insertAfterToken(E->getLocEnd(), ")");
+      }
+    }
+  }
+
+  void transformObjCToNonObjCCast(CastExpr *E) {
+    if (isSelf(E->getSubExpr()))
+      return rewriteToBridgedCast(E, OBC_Bridge);
+  }
+
+  bool isSelf(Expr *E) {
+    E = E->IgnoreParenLValueCasts();
+    if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
+      if (DRE->getDecl()->getIdentifier() == SelfII)
+        return true;
+    return false;
+  }
+
+  static bool isGlobalVar(Expr *E) {
+    E = E->IgnoreParenCasts();
+    if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
+      return DRE->getDecl()->getDeclContext()->isFileContext();
+    if (ConditionalOperator *condOp = dyn_cast<ConditionalOperator>(E))
+      return isGlobalVar(condOp->getTrueExpr()) &&
+             isGlobalVar(condOp->getFalseExpr());
+
+    return false;  
+  }
+};
+
+} // end anonymous namespace
+
+void trans::rewriteUnbridgedCasts(MigrationPass &pass) {
+  UnbridgedCastRewriter trans(pass);
+  trans.TraverseDecl(pass.Ctx.getTranslationUnitDecl());
+}
diff --git a/lib/ARCMigrate/TransUnusedInitDelegate.cpp b/lib/ARCMigrate/TransUnusedInitDelegate.cpp
new file mode 100644
index 0000000..2fa18a3
--- /dev/null
+++ b/lib/ARCMigrate/TransUnusedInitDelegate.cpp
@@ -0,0 +1,75 @@
+//===--- TransUnusedInitDelegate.cpp - Tranformations to ARC mode ---------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Transformations:
+//===----------------------------------------------------------------------===//
+//
+// rewriteUnusedInitDelegate:
+//
+// Rewrites an unused result of calling a delegate initialization, to assigning
+// the result to self.
+// e.g
+//  [self init];
+// ---->
+//  self = [self init];
+//
+//===----------------------------------------------------------------------===//
+
+#include "Transforms.h"
+#include "Internals.h"
+#include "clang/Sema/SemaDiagnostic.h"
+
+using namespace clang;
+using namespace arcmt;
+using namespace trans;
+using llvm::StringRef;
+
+namespace {
+
+class UnusedInitRewriter : public RecursiveASTVisitor<UnusedInitRewriter> {
+  Decl *Dcl;
+  Stmt *Body;
+  MigrationPass &Pass;
+
+  ExprSet Removables;
+
+public:
+  UnusedInitRewriter(Decl *D, MigrationPass &pass)
+    : Dcl(D), Body(0), Pass(pass) { }
+
+  void transformBody(Stmt *body) {
+    Body = body;
+    collectRemovables(body, Removables);
+    TraverseStmt(body);
+  }
+
+  bool VisitObjCMessageExpr(ObjCMessageExpr *ME) {
+    if (ME->isDelegateInitCall() &&
+        isRemovable(ME) &&
+        Pass.TA.hasDiagnostic(diag::err_arc_unused_init_message,
+                              ME->getExprLoc())) {
+      Transaction Trans(Pass.TA);
+      Pass.TA.clearDiagnostic(diag::err_arc_unused_init_message,
+                              ME->getExprLoc());
+      Pass.TA.insert(ME->getExprLoc(), "self = ");
+    }
+    return true;
+  }
+
+private:
+  bool isRemovable(Expr *E) const {
+    return Removables.count(E);
+  }
+};
+
+} // anonymous namespace
+
+void trans::rewriteUnusedInitDelegate(MigrationPass &pass) {
+  BodyTransform<UnusedInitRewriter> trans(pass);
+  trans.TraverseDecl(pass.Ctx.getTranslationUnitDecl());
+}
diff --git a/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp b/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp
new file mode 100644
index 0000000..07ccf70
--- /dev/null
+++ b/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp
@@ -0,0 +1,198 @@
+//===--- TransZeroOutPropsInDealloc.cpp - Tranformations to ARC mode ------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// removeZeroOutPropsInDealloc:
+//
+// Removes zero'ing out "strong" @synthesized properties in a -dealloc method.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Transforms.h"
+#include "Internals.h"
+
+using namespace clang;
+using namespace arcmt;
+using namespace trans;
+using llvm::StringRef;
+
+namespace {
+
+class ZeroOutInDeallocRemover :
+                           public RecursiveASTVisitor<ZeroOutInDeallocRemover> {
+  typedef RecursiveASTVisitor<ZeroOutInDeallocRemover> base;
+
+  MigrationPass &Pass;
+
+  llvm::DenseMap<ObjCPropertyDecl*, ObjCPropertyImplDecl*> SynthesizedProperties;
+  ImplicitParamDecl *SelfD;
+  ExprSet Removables;
+
+public:
+  ZeroOutInDeallocRemover(MigrationPass &pass) : Pass(pass), SelfD(0) { }
+
+  bool VisitObjCMessageExpr(ObjCMessageExpr *ME) {
+    ASTContext &Ctx = Pass.Ctx;
+    TransformActions &TA = Pass.TA;
+
+    if (ME->getReceiverKind() != ObjCMessageExpr::Instance)
+      return true;
+    Expr *receiver = ME->getInstanceReceiver();
+    if (!receiver)
+      return true;
+
+    DeclRefExpr *refE = dyn_cast<DeclRefExpr>(receiver->IgnoreParenCasts());
+    if (!refE || refE->getDecl() != SelfD)
+      return true;
+
+    bool BackedBySynthesizeSetter = false;
+    for (llvm::DenseMap<ObjCPropertyDecl*, ObjCPropertyImplDecl*>::iterator
+         P = SynthesizedProperties.begin(), 
+         E = SynthesizedProperties.end(); P != E; ++P) {
+      ObjCPropertyDecl *PropDecl = P->first;
+      if (PropDecl->getSetterName() == ME->getSelector()) {
+        BackedBySynthesizeSetter = true;
+        break;
+      }
+    }
+    if (!BackedBySynthesizeSetter)
+      return true;
+    
+    // Remove the setter message if RHS is null
+    Transaction Trans(TA);
+    Expr *RHS = ME->getArg(0);
+    bool RHSIsNull = 
+      RHS->isNullPointerConstant(Ctx,
+                                 Expr::NPC_ValueDependentIsNull);
+    if (RHSIsNull && isRemovable(ME))
+      TA.removeStmt(ME);
+
+    return true;
+  }
+
+  bool VisitBinaryOperator(BinaryOperator *BOE) {
+    if (isZeroingPropIvar(BOE) && isRemovable(BOE)) {
+      Transaction Trans(Pass.TA);
+      Pass.TA.removeStmt(BOE);
+    }
+
+    return true;
+  }
+
+  bool TraverseObjCMethodDecl(ObjCMethodDecl *D) {
+    if (D->getMethodFamily() != OMF_dealloc)
+      return true;
+    if (!D->hasBody())
+      return true;
+
+    ObjCImplDecl *IMD = dyn_cast<ObjCImplDecl>(D->getDeclContext());
+    if (!IMD)
+      return true;
+
+    SelfD = D->getSelfDecl();
+    collectRemovables(D->getBody(), Removables);
+
+    // For a 'dealloc' method use, find all property implementations in
+    // this class implementation.
+    for (ObjCImplDecl::propimpl_iterator
+           I = IMD->propimpl_begin(), EI = IMD->propimpl_end(); I != EI; ++I) {
+        ObjCPropertyImplDecl *PID = *I;
+        if (PID->getPropertyImplementation() ==
+            ObjCPropertyImplDecl::Synthesize) {
+          ObjCPropertyDecl *PD = PID->getPropertyDecl();
+          ObjCMethodDecl *setterM = PD->getSetterMethodDecl();
+          if (!(setterM && setterM->isDefined())) {
+            ObjCPropertyDecl::PropertyAttributeKind AttrKind = 
+              PD->getPropertyAttributes();
+              if (AttrKind & 
+                  (ObjCPropertyDecl::OBJC_PR_retain | 
+                   ObjCPropertyDecl::OBJC_PR_copy   |
+                   ObjCPropertyDecl::OBJC_PR_strong))
+                SynthesizedProperties[PD] = PID;
+          }
+        }
+    }
+
+    // Now, remove all zeroing of ivars etc.
+    base::TraverseObjCMethodDecl(D);
+
+    // clear out for next method.
+    SynthesizedProperties.clear();
+    SelfD = 0;
+    Removables.clear();
+    return true;
+  }
+
+  bool TraverseFunctionDecl(FunctionDecl *D) { return true; }
+  bool TraverseBlockDecl(BlockDecl *block) { return true; }
+  bool TraverseBlockExpr(BlockExpr *block) { return true; }
+
+private:
+  bool isRemovable(Expr *E) const {
+    return Removables.count(E);
+  }
+
+  bool isZeroingPropIvar(Expr *E) {
+    BinaryOperator *BOE = dyn_cast_or_null<BinaryOperator>(E);
+    if (!BOE) return false;
+
+    if (BOE->getOpcode() == BO_Comma)
+      return isZeroingPropIvar(BOE->getLHS()) &&
+             isZeroingPropIvar(BOE->getRHS());
+
+    if (BOE->getOpcode() != BO_Assign)
+        return false;
+
+    ASTContext &Ctx = Pass.Ctx;
+
+    Expr *LHS = BOE->getLHS();
+    if (ObjCIvarRefExpr *IV = dyn_cast<ObjCIvarRefExpr>(LHS)) {
+      ObjCIvarDecl *IVDecl = IV->getDecl();
+      if (!IVDecl->getType()->isObjCObjectPointerType())
+        return false;
+      bool IvarBacksPropertySynthesis = false;
+      for (llvm::DenseMap<ObjCPropertyDecl*, ObjCPropertyImplDecl*>::iterator
+           P = SynthesizedProperties.begin(), 
+           E = SynthesizedProperties.end(); P != E; ++P) {
+        ObjCPropertyImplDecl *PropImpDecl = P->second;
+        if (PropImpDecl && PropImpDecl->getPropertyIvarDecl() == IVDecl) {
+          IvarBacksPropertySynthesis = true;
+          break;
+        }
+      }
+      if (!IvarBacksPropertySynthesis)
+        return false;
+    }
+    else if (ObjCPropertyRefExpr *PropRefExp = dyn_cast<ObjCPropertyRefExpr>(LHS)) {
+      // TODO: Using implicit property decl.
+      if (PropRefExp->isImplicitProperty())
+        return false;
+      if (ObjCPropertyDecl *PDecl = PropRefExp->getExplicitProperty()) {
+        if (!SynthesizedProperties.count(PDecl))
+          return false;
+      }
+    }
+    else
+        return false;
+
+    Expr *RHS = BOE->getRHS();
+    bool RHSIsNull = RHS->isNullPointerConstant(Ctx,
+                                                Expr::NPC_ValueDependentIsNull);
+    if (RHSIsNull)
+      return true;
+
+    return isZeroingPropIvar(RHS);
+  }
+};
+
+} // anonymous namespace
+
+void trans::removeZeroOutPropsInDealloc(MigrationPass &pass) {
+  ZeroOutInDeallocRemover trans(pass);
+  trans.TraverseDecl(pass.Ctx.getTranslationUnitDecl());
+}
diff --git a/lib/ARCMigrate/Transforms.cpp b/lib/ARCMigrate/Transforms.cpp
index 499c8f0..0650e3b 100644
--- a/lib/ARCMigrate/Transforms.cpp
+++ b/lib/ARCMigrate/Transforms.cpp
@@ -6,151 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-// Transformations:
-//===----------------------------------------------------------------------===//
-//
-// castNonObjCToObjC:
-//
-// A cast of non-objc pointer to an objc one is checked. If the non-objc pointer
-// is from a file-level variable, objc_unretainedObject function is used to
-// convert it.
-//
-//  NSString *str = (NSString *)kUTTypePlainText;
-//  str = b ? kUTTypeRTF : kUTTypePlainText;
-// ---->
-//  NSString *str = objc_unretainedObject(kUTTypePlainText);
-//  str = objc_unretainedObject(b ? kUTTypeRTF : kUTTypePlainText);
-//
-// For a C pointer to ObjC, objc_unretainedPointer is used.
-//
-//  void *vp = str; // NSString*
-// ---->
-//  void *vp = (void*)objc_unretainedPointer(str);
-//
-//===----------------------------------------------------------------------===//
-//
-// rewriteAllocCopyWithZone:
-//
-// Calls to +allocWithZone/-copyWithZone/-mutableCopyWithZone are changed to
-// +alloc/-copy/-mutableCopy if we can safely remove the given parameter.
-//
-//  Foo *foo1 = [[Foo allocWithZone:[self zone]] init];
-// ---->
-//  Foo *foo1 = [[Foo alloc] init];
-//
-//===----------------------------------------------------------------------===//
-//
-// rewriteAutoreleasePool:
-//
-// Calls to NSAutoreleasePools will be rewritten as an @autorelease scope.
-//
-//  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-//  ...
-//  [pool release];
-// ---->
-//  @autorelease {
-//  ...
-//  }
-//
-// An NSAutoreleasePool will not be touched if:
-// - There is not a corresponding -release/-drain in the same scope
-// - Not all references of the NSAutoreleasePool variable can be removed
-// - There is a variable that is declared inside the intended @autorelease scope
-//   which is also used outside it.
-//
-//===----------------------------------------------------------------------===//
-//
-// makeAssignARCSafe:
-//
-// Add '__strong' where appropriate.
-//
-//  for (id x in collection) {
-//    x = 0;
-//  }
-// ---->
-//  for (__strong id x in collection) {
-//    x = 0;
-//  }
-//
-//===----------------------------------------------------------------------===//
-//
-// removeRetainReleaseDealloc:
-//
-// Removes retain/release/autorelease/dealloc messages.
-//
-//  return [[foo retain] autorelease];
-// ---->
-//  return foo;
-//
-//===----------------------------------------------------------------------===//
-//
-// removeEmptyStatements:
-//
-// Removes empty statements that are leftovers from previous transformations.
-// e.g for
-//
-//  [x retain];
-//
-// removeRetainReleaseDealloc will leave an empty ";" that removeEmptyStatements
-// will remove.
-//
-//===----------------------------------------------------------------------===//
-//
-// changeIvarsOfAssignProperties:
-//
-// If a property is synthesized with 'assign' attribute and the user didn't
-// set a lifetime attribute, change the property to 'weak' or add
-// __unsafe_unretained if the ARC runtime is not available.
-//
-//  @interface Foo : NSObject {
-//      NSObject *x;
-//  }
-//  @property (assign) id x;
-//  @end
-// ---->
-//  @interface Foo : NSObject {
-//      NSObject *__weak x;
-//  }
-//  @property (weak) id x;
-//  @end
-//
-//===----------------------------------------------------------------------===//
-//
-// rewriteUnusedDelegateInit:
-//
-// Rewrites an unused result of calling a delegate initialization, to assigning
-// the result to self.
-// e.g
-//  [self init];
-// ---->
-//  self = [self init];
-//
-//===----------------------------------------------------------------------===//
-//
-// rewriteBlockObjCVariable:
-//
-// Adding __block to an obj-c variable could be either because the the variable
-// is used for output storage or the user wanted to break a retain cycle.
-// This transformation checks whether a reference of the variable for the block
-// is actually needed (it is assigned to or its address is taken) or not.
-// If the reference is not needed it will assume __block was added to break a
-// cycle so it will remove '__block' and add __weak/__unsafe_unretained.
-// e.g
-//
-//   __block Foo *x;
-//   bar(^ { [x cake]; });
-// ---->
-//   __weak Foo *x;
-//   bar(^ { [x cake]; });
-//
-//===----------------------------------------------------------------------===//
-//
-// removeZeroOutIvarsInDealloc:
-//
-// Removes zero'ing out "strong" @synthesized properties in a -dealloc method.
-//
-//===----------------------------------------------------------------------===//
 
+#include "Transforms.h"
 #include "Internals.h"
 #include "clang/Sema/SemaDiagnostic.h"
 #include "clang/AST/RecursiveASTVisitor.h"
@@ -165,19 +22,115 @@
 
 using namespace clang;
 using namespace arcmt;
+using namespace trans;
 using llvm::StringRef;
 
 //===----------------------------------------------------------------------===//
-// Transformations.
+// Helpers.
 //===----------------------------------------------------------------------===//
 
+/// \brief 'Loc' is the end of a statement range. This returns the location
+/// immediately after the semicolon following the statement.
+/// If no semicolon is found or the location is inside a macro, the returned
+/// source location will be invalid.
+SourceLocation trans::findLocationAfterSemi(SourceLocation loc,
+                                            ASTContext &Ctx) {
+  SourceManager &SM = Ctx.getSourceManager();
+  if (loc.isMacroID()) {
+    if (!SM.isAtEndOfMacroInstantiation(loc))
+      return SourceLocation();
+    loc = SM.getInstantiationRange(loc).second;
+  }
+  loc = Lexer::getLocForEndOfToken(loc, /*Offset=*/0, SM, Ctx.getLangOptions());
+
+  // Break down the source location.
+  std::pair<FileID, unsigned> locInfo = SM.getDecomposedLoc(loc);
+
+  // Try to load the file buffer.
+  bool invalidTemp = false;
+  llvm::StringRef file = SM.getBufferData(locInfo.first, &invalidTemp);
+  if (invalidTemp)
+    return SourceLocation();
+
+  const char *tokenBegin = file.data() + locInfo.second;
+
+  // Lex from the start of the given location.
+  Lexer lexer(SM.getLocForStartOfFile(locInfo.first),
+              Ctx.getLangOptions(),
+              file.begin(), tokenBegin, file.end());
+  Token tok;
+  lexer.LexFromRawLexer(tok);
+  if (tok.isNot(tok::semi))
+    return SourceLocation();
+
+  return tok.getLocation().getFileLocWithOffset(1);
+}
+
+bool trans::hasSideEffects(Expr *E, ASTContext &Ctx) {
+  if (!E || !E->HasSideEffects(Ctx))
+    return false;
+
+  E = E->IgnoreParenCasts();
+  ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E);
+  if (!ME)
+    return true;
+  switch (ME->getMethodFamily()) {
+  case OMF_autorelease:
+  case OMF_dealloc:
+  case OMF_release:
+  case OMF_retain:
+    switch (ME->getReceiverKind()) {
+    case ObjCMessageExpr::SuperInstance:
+      return false;
+    case ObjCMessageExpr::Instance:
+      return hasSideEffects(ME->getInstanceReceiver(), Ctx);
+    default:
+      break;
+    }
+    break;
+  default:
+    break;
+  }
+
+  return true;
+}
+
 namespace {
 
-class RemovablesCollector : public RecursiveASTVisitor<RemovablesCollector> {
-  llvm::DenseSet<Expr *> &Removables;
+class ReferenceClear : public RecursiveASTVisitor<ReferenceClear> {
+  ExprSet &Refs;
+public:
+  ReferenceClear(ExprSet &refs) : Refs(refs) { }
+  bool VisitDeclRefExpr(DeclRefExpr *E) { Refs.erase(E); return true; }
+  bool VisitBlockDeclRefExpr(BlockDeclRefExpr *E) { Refs.erase(E); return true; }
+};
+
+class ReferenceCollector : public RecursiveASTVisitor<ReferenceCollector> {
+  ValueDecl *Dcl;
+  ExprSet &Refs;
 
 public:
-  RemovablesCollector(llvm::DenseSet<Expr *> &removables)
+  ReferenceCollector(ValueDecl *D, ExprSet &refs)
+    : Dcl(D), Refs(refs) { }
+
+  bool VisitDeclRefExpr(DeclRefExpr *E) {
+    if (E->getDecl() == Dcl)
+      Refs.insert(E);
+    return true;
+  }
+
+  bool VisitBlockDeclRefExpr(BlockDeclRefExpr *E) {
+    if (E->getDecl() == Dcl)
+      Refs.insert(E);
+    return true;
+  }
+};
+
+class RemovablesCollector : public RecursiveASTVisitor<RemovablesCollector> {
+  ExprSet &Removables;
+
+public:
+  RemovablesCollector(ExprSet &removables)
   : Removables(removables) { }
   
   bool shouldWalkTypesOfTypeLocs() const { return false; }
@@ -238,1823 +191,18 @@
   }
 };
 
-} // end anonymous namespace.
-
-static bool HasSideEffects(Expr *E, ASTContext &Ctx) {
-  if (!E || !E->HasSideEffects(Ctx))
-    return false;
-
-  E = E->IgnoreParenCasts();
-  ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E);
-  if (!ME)
-    return true;
-  switch (ME->getMethodFamily()) {
-  case OMF_autorelease:
-  case OMF_dealloc:
-  case OMF_release:
-  case OMF_retain:
-    switch (ME->getReceiverKind()) {
-    case ObjCMessageExpr::SuperInstance:
-      return false;
-    case ObjCMessageExpr::Instance:
-      return HasSideEffects(ME->getInstanceReceiver(), Ctx);
-    default:
-      break;
-    }
-    break;
-  default:
-    break;
-  }
-
-  return true;
-}
-
-static void removeDeallocMethod(MigrationPass &pass) {
-    ASTContext &Ctx = pass.Ctx;
-    TransformActions &TA = pass.TA;
-    DeclContext *DC = Ctx.getTranslationUnitDecl();
-    ObjCMethodDecl *DeallocMethodDecl = 0;
-    IdentifierInfo *II = &Ctx.Idents.get("dealloc");
-    
-    for (DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
-         I != E; ++I) {
-        Decl *D = *I;
-        if (ObjCImplementationDecl *IMD = 
-            dyn_cast<ObjCImplementationDecl>(D)) {
-            DeallocMethodDecl = 0;
-            for (ObjCImplementationDecl::instmeth_iterator I = 
-                 IMD->instmeth_begin(), E = IMD->instmeth_end();
-                 I != E; ++I) {
-                ObjCMethodDecl *OMD = *I;
-                if (OMD->isInstanceMethod() &&
-                    OMD->getSelector() == Ctx.Selectors.getSelector(0, &II)) {
-                    DeallocMethodDecl = OMD;
-                    break;
-                }
-            }
-            if (DeallocMethodDecl && 
-                DeallocMethodDecl->getCompoundBody()->body_empty()) {
-              Transaction Trans(TA);
-              TA.remove(DeallocMethodDecl->getSourceRange());
-            }
-        }
-    }
-}
-
-namespace {
-
-class ReferenceClear : public RecursiveASTVisitor<ReferenceClear> {
-  llvm::DenseSet<Expr *> &Refs;
-public:
-  ReferenceClear(llvm::DenseSet<Expr *> &refs) : Refs(refs) { }
-  bool VisitDeclRefExpr(DeclRefExpr *E) { Refs.erase(E); return true; }
-  bool VisitBlockDeclRefExpr(BlockDeclRefExpr *E) { Refs.erase(E); return true; }
-  void clearRefsIn(Stmt *S) { TraverseStmt(S); }
-  template <typename iterator>
-  void clearRefsIn(iterator begin, iterator end) {
-    for (; begin != end; ++begin)
-      TraverseStmt(*begin);
-  }
-};
-
-class ReferenceCollector : public RecursiveASTVisitor<ReferenceCollector> {
-  ValueDecl *Dcl;
-  llvm::DenseSet<Expr *> &Refs;
-
-public:
-  ReferenceCollector(llvm::DenseSet<Expr *> &refs)
-    : Dcl(0), Refs(refs) { }
-
-  void lookFor(ValueDecl *D, Stmt *S) {
-    Dcl = D;
-    TraverseStmt(S);
-  }
-
-  bool VisitDeclRefExpr(DeclRefExpr *E) {
-    if (E->getDecl() == Dcl)
-      Refs.insert(E);
-    return true;
-  }
-
-  bool VisitBlockDeclRefExpr(BlockDeclRefExpr *E) {
-    if (E->getDecl() == Dcl)
-      Refs.insert(E);
-    return true;
-  }
-};
-
-class ReleaseCollector : public RecursiveASTVisitor<ReleaseCollector> {
-  Decl *Dcl;
-  llvm::SmallVectorImpl<ObjCMessageExpr *> &Releases;
-
-public:
-  ReleaseCollector(Decl *D, llvm::SmallVectorImpl<ObjCMessageExpr *> &releases)
-    : Dcl(D), Releases(releases) { }
-
-  bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
-    if (!E->isInstanceMessage())
-      return true;
-    if (E->getMethodFamily() != OMF_release)
-      return true;
-    Expr *instance = E->getInstanceReceiver()->IgnoreParenCasts();
-    if (DeclRefExpr *DE = dyn_cast<DeclRefExpr>(instance)) {
-      if (DE->getDecl() == Dcl)
-        Releases.push_back(E);
-    }
-    return true;
-  }
-};
-
-template <typename BODY_TRANS>
-class BodyTransform : public RecursiveASTVisitor<BodyTransform<BODY_TRANS> > {
-  MigrationPass &Pass;
-
-public:
-  BodyTransform(MigrationPass &pass) : Pass(pass) { }
-
-  void handleBody(Decl *D) {
-    Stmt *body = D->getBody();
-    if (body) {
-      BODY_TRANS(D, Pass).transformBody(body);
-    }
-  }
-
-  bool TraverseBlockDecl(BlockDecl *D) {
-    handleBody(D);
-    return true;
-  }
-  bool TraverseObjCMethodDecl(ObjCMethodDecl *D) {
-    if (D->isThisDeclarationADefinition())
-      handleBody(D);
-    return true;
-  }
-  bool TraverseFunctionDecl(FunctionDecl *D) {
-    if (D->isThisDeclarationADefinition())
-      handleBody(D);
-    return true;
-  }
-};
-
-} // anonymous namespace
-
-//===----------------------------------------------------------------------===//
-// makeAssignARCSafe
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-class ARCAssignChecker : public RecursiveASTVisitor<ARCAssignChecker> {
-  MigrationPass &Pass;
-  llvm::DenseSet<VarDecl *> ModifiedVars;
-
-public:
-  ARCAssignChecker(MigrationPass &pass) : Pass(pass) { }
-
-  bool VisitBinaryOperator(BinaryOperator *Exp) {
-    Expr *E = Exp->getLHS();
-    SourceLocation OrigLoc = E->getExprLoc();
-    SourceLocation Loc = OrigLoc;
-    DeclRefExpr *declRef = dyn_cast<DeclRefExpr>(E->IgnoreParenCasts());
-    if (declRef && isa<VarDecl>(declRef->getDecl())) {
-      ASTContext &Ctx = Pass.Ctx;
-      Expr::isModifiableLvalueResult IsLV = E->isModifiableLvalue(Ctx, &Loc);
-      if (IsLV != Expr::MLV_ConstQualified)
-        return true;
-      VarDecl *var = cast<VarDecl>(declRef->getDecl());
-      if (var->isARCPseudoStrong()) {
-        Transaction Trans(Pass.TA);
-        if (Pass.TA.clearDiagnostic(diag::err_typecheck_arr_assign_enumeration,
-                                    Exp->getOperatorLoc())) {
-          if (!ModifiedVars.count(var)) {
-            TypeLoc TLoc = var->getTypeSourceInfo()->getTypeLoc();
-            Pass.TA.insert(TLoc.getBeginLoc(), "__strong ");
-            ModifiedVars.insert(var);
-          }
-        }
-      }
-    }
-    
-    return true;
-  }
-};
-
-} // anonymous namespace
-
-static void makeAssignARCSafe(MigrationPass &pass) {
-  ARCAssignChecker assignCheck(pass);
-  assignCheck.TraverseDecl(pass.Ctx.getTranslationUnitDecl());
-}
-
-//===----------------------------------------------------------------------===//
-// castNonObjCToObjC
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-class NonObjCToObjCCaster : public RecursiveASTVisitor<NonObjCToObjCCaster> {
-  MigrationPass &Pass;
-  IdentifierInfo *SelfII;
-public:
-  NonObjCToObjCCaster(MigrationPass &pass) : Pass(pass) {
-    SelfII = &Pass.Ctx.Idents.get("self");
-  }
-
-  bool VisitCastExpr(CastExpr *E) {
-    if (E->getCastKind() != CK_AnyPointerToObjCPointerCast
-        && E->getCastKind() != CK_BitCast)
-      return true;
-
-    QualType castType = E->getType();
-    Expr *castExpr = E->getSubExpr();
-    QualType castExprType = castExpr->getType();
-
-    if (castType->isObjCObjectPointerType() &&
-        castExprType->isObjCObjectPointerType())
-      return true;
-    if (!castType->isObjCObjectPointerType() &&
-        !castExprType->isObjCObjectPointerType())
-      return true;
-    
-    bool exprRetainable = castExprType->isObjCIndirectLifetimeType();
-    bool castRetainable = castType->isObjCIndirectLifetimeType();
-    if (exprRetainable == castRetainable) return true;
-
-    if (castExpr->isNullPointerConstant(Pass.Ctx,
-                                        Expr::NPC_ValueDependentIsNull))
-      return true;
-
-    SourceLocation loc = castExpr->getExprLoc();
-    if (loc.isValid() && Pass.Ctx.getSourceManager().isInSystemHeader(loc))
-      return true;
-
-    if (castType->isObjCObjectPointerType())
-      transformNonObjCToObjCCast(E);
-    else
-      transformObjCToNonObjCCast(E);
-
-    return true;
-  }
-
-private:
-  void transformNonObjCToObjCCast(CastExpr *E) {
-    if (!E) return;
-
-    // Global vars are assumed that are cast as unretained.
-    if (isGlobalVar(E))
-      if (E->getSubExpr()->getType()->isPointerType()) {
-        castToObjCObject(E, /*retained=*/false);
-        return;
-      }
-
-    // If the cast is directly over the result of a Core Foundation function
-    // try to figure out whether it should be cast as retained or unretained.
-    Expr *inner = E->IgnoreParenCasts();
-    if (CallExpr *callE = dyn_cast<CallExpr>(inner)) {
-      if (FunctionDecl *FD = callE->getDirectCallee()) {
-        if (FD->getAttr<CFReturnsRetainedAttr>()) {
-          castToObjCObject(E, /*retained=*/true);
-          return;
-        }
-        if (FD->getAttr<CFReturnsNotRetainedAttr>()) {
-          castToObjCObject(E, /*retained=*/false);
-          return;
-        }
-        if (FD->isGlobal() &&
-            FD->getIdentifier() &&
-            ento::cocoa::isRefType(E->getSubExpr()->getType(), "CF",
-                                   FD->getIdentifier()->getName())) {
-          StringRef fname = FD->getIdentifier()->getName();
-          if (fname.endswith("Retain") ||
-              fname.find("Create") != StringRef::npos ||
-              fname.find("Copy") != StringRef::npos) {
-            castToObjCObject(E, /*retained=*/true);
-            return;
-          }
-
-          if (fname.find("Get") != StringRef::npos) {
-            castToObjCObject(E, /*retained=*/false);
-            return;
-          }
-        }
-      }
-    }
-  }
-
-  void castToObjCObject(CastExpr *E, bool retained) {
-    rewriteToBridgedCast(E, retained ? OBC_BridgeTransfer : OBC_Bridge);
-  }
-
-  void rewriteToBridgedCast(CastExpr *E, ObjCBridgeCastKind Kind) {
-    TransformActions &TA = Pass.TA;
-
-    // We will remove the compiler diagnostic.
-    if (!TA.hasDiagnostic(diag::err_arc_mismatched_cast,
-                          diag::err_arc_cast_requires_bridge,
-                          E->getLocStart()))
-      return;
-
-    StringRef bridge;
-    switch(Kind) {
-    case OBC_Bridge:
-      bridge = "__bridge "; break;
-    case OBC_BridgeTransfer:
-      bridge = "__bridge_transfer "; break;
-    case OBC_BridgeRetained:
-      bridge = "__bridge_retained "; break;
-    }
-
-    Transaction Trans(TA);
-    TA.clearDiagnostic(diag::err_arc_mismatched_cast,
-                       diag::err_arc_cast_requires_bridge,
-                       E->getLocStart());
-    if (CStyleCastExpr *CCE = dyn_cast<CStyleCastExpr>(E)) {
-      TA.insertAfterToken(CCE->getLParenLoc(), bridge);
-    } else {
-      SourceLocation insertLoc = E->getSubExpr()->getLocStart();
-      llvm::SmallString<128> newCast;
-      newCast += '(';
-      newCast += bridge;
-      newCast += E->getType().getAsString(Pass.Ctx.PrintingPolicy);
-      newCast += ')';
-
-      if (isa<ParenExpr>(E->getSubExpr())) {
-        TA.insert(insertLoc, newCast.str());
-      } else {
-        newCast += '(';
-        TA.insert(insertLoc, newCast.str());
-        TA.insertAfterToken(E->getLocEnd(), ")");
-      }
-    }
-  }
-
-  void transformObjCToNonObjCCast(CastExpr *E) {
-    if (isSelf(E->getSubExpr()))
-      return rewriteToBridgedCast(E, OBC_Bridge);
-  }
-
-  bool isSelf(Expr *E) {
-    E = E->IgnoreParenLValueCasts();
-    if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
-      if (DRE->getDecl()->getIdentifier() == SelfII)
-        return true;
-    return false;
-  }
-
-  static bool isGlobalVar(Expr *E) {
-    E = E->IgnoreParenCasts();
-    if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
-      return DRE->getDecl()->getDeclContext()->isFileContext();
-    if (ConditionalOperator *condOp = dyn_cast<ConditionalOperator>(E))
-      return isGlobalVar(condOp->getTrueExpr()) &&
-             isGlobalVar(condOp->getFalseExpr());
-
-    return false;  
-  }
-};
-
 } // end anonymous namespace
 
-static void castNonObjCToObjC(MigrationPass &pass) {
-  NonObjCToObjCCaster trans(pass);
-  trans.TraverseDecl(pass.Ctx.getTranslationUnitDecl());
+void trans::clearRefsIn(Stmt *S, ExprSet &refs) {
+  ReferenceClear(refs).TraverseStmt(S);
 }
 
-//===----------------------------------------------------------------------===//
-// rewriteAllocCopyWithZone
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-class AllocCopyWithZoneRewriter :
-                         public RecursiveASTVisitor<AllocCopyWithZoneRewriter> {
-  Decl *Dcl;
-  Stmt *Body;
-  MigrationPass &Pass;
-
-  Selector allocWithZoneSel;
-  Selector copyWithZoneSel;
-  Selector mutableCopyWithZoneSel;
-  Selector zoneSel;
-  IdentifierInfo *NSZoneII;
-
-  std::vector<DeclStmt *> NSZoneVars;
-  std::vector<Expr *> Removals;
-
-public:
-  AllocCopyWithZoneRewriter(Decl *D, MigrationPass &pass)
-    : Dcl(D), Body(0), Pass(pass) {
-    SelectorTable &sels = pass.Ctx.Selectors;
-    IdentifierTable &ids = pass.Ctx.Idents; 
-    allocWithZoneSel = sels.getUnarySelector(&ids.get("allocWithZone"));
-    copyWithZoneSel = sels.getUnarySelector(&ids.get("copyWithZone"));
-    mutableCopyWithZoneSel = sels.getUnarySelector(
-                                               &ids.get("mutableCopyWithZone"));
-    zoneSel = sels.getNullarySelector(&ids.get("zone"));
-    NSZoneII = &ids.get("_NSZone");
-  }
-
-  void transformBody(Stmt *body) {
-    Body = body;
-    // Don't change allocWithZone/copyWithZone messages inside
-    // custom implementations of such methods, it can lead to infinite loops.
-    if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(Dcl)) {
-      Selector sel = MD->getSelector();
-      if (sel == allocWithZoneSel ||
-          sel == copyWithZoneSel ||
-          sel == mutableCopyWithZoneSel ||
-          sel == zoneSel)
-        return;
-    }
-
-    TraverseStmt(body);
-  }
-
-  ~AllocCopyWithZoneRewriter() {
-    for (std::vector<DeclStmt *>::reverse_iterator
-           I = NSZoneVars.rbegin(), E = NSZoneVars.rend(); I != E; ++I) {
-      DeclStmt *DS = *I;
-      DeclGroupRef group = DS->getDeclGroup();
-      std::vector<Expr *> varRemovals = Removals;
-
-      bool areAllVarsUnused = true;
-      for (std::reverse_iterator<DeclGroupRef::iterator>
-             DI(group.end()), DE(group.begin()); DI != DE; ++DI) {
-        VarDecl *VD = cast<VarDecl>(*DI);
-        if (isNSZoneVarUsed(VD, varRemovals)) {
-          areAllVarsUnused = false;
-          break;
-        }
-        varRemovals.push_back(VD->getInit());
-      }
-
-      if (areAllVarsUnused) {
-        Transaction Trans(Pass.TA);
-        clearUnavailableDiags(DS);
-        Pass.TA.removeStmt(DS);
-        Removals.swap(varRemovals);
-      }
-    }
-  }
-
-  bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
-    if (!isAllocCopyWithZoneCall(E))
-      return true;
-    Expr *arg = E->getArg(0);
-    if (paramToAllocWithZoneHasSideEffects(arg))
-      return true;
-
-    Pass.TA.startTransaction();
-
-    clearUnavailableDiags(arg);
-    Pass.TA.clearDiagnostic(diag::err_unavailable_message,
-                            E->getReceiverRange().getBegin());
-
-    Pass.TA.remove(SourceRange(E->getSelectorLoc(), arg->getLocEnd()));
-    StringRef rewrite;
-    if (E->getSelector() == allocWithZoneSel)
-      rewrite = "alloc";
-    else if (E->getSelector() == copyWithZoneSel)
-      rewrite = "copy";
-    else {
-      assert(E->getSelector() == mutableCopyWithZoneSel);
-      rewrite = "mutableCopy";
-    }
-    Pass.TA.insert(E->getSelectorLoc(), rewrite);
-
-    bool failed = Pass.TA.commitTransaction();
-    if (!failed)
-      Removals.push_back(arg);
-
-    return true;
-  }
-
-  bool VisitDeclStmt(DeclStmt *DS) {
-    DeclGroupRef group = DS->getDeclGroup();
-    if (group.begin() == group.end())
-      return true;
-    for (DeclGroupRef::iterator
-           DI = group.begin(), DE = group.end(); DI != DE; ++DI)
-      if (!isRemovableNSZoneVar(*DI))
-        return true;
-
-    NSZoneVars.push_back(DS);
-    return true;
-  }
-
-private:
-  bool isRemovableNSZoneVar(Decl *D) {
-    if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
-      if (isNSZone(VD->getType()))
-        return !paramToAllocWithZoneHasSideEffects(VD->getInit());
-    }
-    return false;
-  }
-
-  bool isNSZone(RecordDecl *RD) {
-    return RD && RD->getIdentifier() == NSZoneII;
-  }
-
-  bool isNSZone(QualType Ty) {
-    QualType pointee = Ty->getPointeeType();
-    if (pointee.isNull())
-      return false;
-    if (const RecordType *recT = pointee->getAsStructureType())
-      return isNSZone(recT->getDecl());
-    return false;
-  }
-
-  bool isNSZoneVarUsed(VarDecl *D, std::vector<Expr *> &removals) {
-    llvm::DenseSet<Expr *> refs;
-
-    ReferenceCollector refColl(refs);
-    refColl.lookFor(D, Body);
-
-    ReferenceClear refClear(refs);
-    refClear.clearRefsIn(removals.begin(), removals.end());
-
-    return !refs.empty();
-  }
-
-  bool isAllocCopyWithZoneCall(ObjCMessageExpr *E) {
-    if (E->getNumArgs() == 1 &&
-        E->getSelector() == allocWithZoneSel &&
-        (E->isClassMessage() ||
-         Pass.TA.hasDiagnostic(diag::err_unavailable_message,
-                               E->getReceiverRange().getBegin())))
-      return true;
-
-    return E->isInstanceMessage() &&
-           E->getNumArgs() == 1   &&
-           (E->getSelector() == copyWithZoneSel ||
-            E->getSelector() == mutableCopyWithZoneSel);
-  }
-
-  bool isZoneCall(ObjCMessageExpr *E) {
-    return E->isInstanceMessage() &&
-           E->getNumArgs() == 0   &&
-           E->getSelector() == zoneSel;
-  }
-
-  bool paramToAllocWithZoneHasSideEffects(Expr *E) {
-    if (!HasSideEffects(E, Pass.Ctx))
-      return false;
-    E = E->IgnoreParenCasts();
-    ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E);
-    if (!ME)
-      return true;
-    if (!isZoneCall(ME))
-      return true;
-    return HasSideEffects(ME->getInstanceReceiver(), Pass.Ctx);
-  }
-
-  void clearUnavailableDiags(Stmt *S) {
-    if (S)
-      Pass.TA.clearDiagnostic(diag::err_unavailable,
-                              diag::err_unavailable_message,
-                              S->getSourceRange());
-  }
-};
-
-} // end anonymous namespace
-
-static void rewriteAllocCopyWithZone(MigrationPass &pass) {
-  BodyTransform<AllocCopyWithZoneRewriter> trans(pass);
-  trans.TraverseDecl(pass.Ctx.getTranslationUnitDecl());
+void trans::collectRefs(ValueDecl *D, Stmt *S, ExprSet &refs) {
+  ReferenceCollector(D, refs).TraverseStmt(S);
 }
 
-//===----------------------------------------------------------------------===//
-// rewriteAutoreleasePool
-//===----------------------------------------------------------------------===//
-
-/// \brief 'Loc' is the end of a statement range. This returns the location
-/// immediately after the semicolon following the statement.
-/// If no semicolon is found or the location is inside a macro, the returned
-/// source location will be invalid.
-static SourceLocation findLocationAfterSemi(ASTContext &Ctx,
-                                            SourceLocation loc) {
-  SourceManager &SM = Ctx.getSourceManager();
-  if (loc.isMacroID()) {
-    if (!SM.isAtEndOfMacroInstantiation(loc))
-      return SourceLocation();
-    loc = SM.getInstantiationRange(loc).second;
-  }
-  loc = Lexer::getLocForEndOfToken(loc, /*Offset=*/0, SM, Ctx.getLangOptions());
-
-  // Break down the source location.
-  std::pair<FileID, unsigned> locInfo = SM.getDecomposedLoc(loc);
-
-  // Try to load the file buffer.
-  bool invalidTemp = false;
-  llvm::StringRef file = SM.getBufferData(locInfo.first, &invalidTemp);
-  if (invalidTemp)
-    return SourceLocation();
-
-  const char *tokenBegin = file.data() + locInfo.second;
-
-  // Lex from the start of the given location.
-  Lexer lexer(SM.getLocForStartOfFile(locInfo.first),
-              Ctx.getLangOptions(),
-              file.begin(), tokenBegin, file.end());
-  Token tok;
-  lexer.LexFromRawLexer(tok);
-  if (tok.isNot(tok::semi))
-    return SourceLocation();
-
-  return tok.getLocation().getFileLocWithOffset(1);
-}
-
-namespace {
-
-class AutoreleasePoolRewriter
-                         : public RecursiveASTVisitor<AutoreleasePoolRewriter> {
-public:
-  AutoreleasePoolRewriter(Decl *D, MigrationPass &pass)
-    : Dcl(D), Body(0), Pass(pass) {
-    PoolII = &pass.Ctx.Idents.get("NSAutoreleasePool");
-    DrainSel = pass.Ctx.Selectors.getNullarySelector(
-                                                 &pass.Ctx.Idents.get("drain"));
-  }
-
-  void transformBody(Stmt *body) {
-    Body = body;
-    TraverseStmt(body);
-  }
-  
-  ~AutoreleasePoolRewriter() {
-    llvm::SmallVector<VarDecl *, 8> VarsToHandle;
-
-    for (std::map<VarDecl *, PoolVarInfo>::iterator
-           I = PoolVars.begin(), E = PoolVars.end(); I != E; ++I) {
-      VarDecl *var = I->first;
-      PoolVarInfo &info = I->second;
-
-      // Check that we can handle/rewrite all references of the pool.
-
-      ReferenceClear refClear(info.Refs);
-      refClear.clearRefsIn(info.Dcl);
-      for (llvm::SmallVectorImpl<PoolScope>::iterator
-             scpI = info.Scopes.begin(),
-             scpE = info.Scopes.end(); scpI != scpE; ++scpI) {
-        PoolScope &scope = *scpI;
-        refClear.clearRefsIn(*scope.Begin);
-        refClear.clearRefsIn(*scope.End);
-        refClear.clearRefsIn(scope.Releases.begin(), scope.Releases.end());
-      }
-
-      // Even if one reference is not handled we will not do anything about that
-      // pool variable.
-      if (info.Refs.empty())
-        VarsToHandle.push_back(var);
-    }
-
-    for (unsigned i = 0, e = VarsToHandle.size(); i != e; ++i) {
-      PoolVarInfo &info = PoolVars[VarsToHandle[i]];
-
-      Transaction Trans(Pass.TA);
-
-      clearUnavailableDiags(info.Dcl);
-      Pass.TA.removeStmt(info.Dcl);
-
-      // Add "@autoreleasepool { }"
-      for (llvm::SmallVectorImpl<PoolScope>::iterator
-             scpI = info.Scopes.begin(),
-             scpE = info.Scopes.end(); scpI != scpE; ++scpI) {
-        PoolScope &scope = *scpI;
-        clearUnavailableDiags(*scope.Begin);
-        clearUnavailableDiags(*scope.End);
-        if (scope.IsFollowedBySimpleReturnStmt) {
-          // Include the return in the scope.
-          Pass.TA.replaceStmt(*scope.Begin, "@autoreleasepool {");
-          Pass.TA.removeStmt(*scope.End);
-          Stmt::child_iterator retI = scope.End;
-          ++retI;
-          SourceLocation afterSemi = findLocationAfterSemi(Pass.Ctx,
-                                                          (*retI)->getLocEnd());
-          assert(afterSemi.isValid() &&
-                 "Didn't we check before setting IsFollowedBySimpleReturnStmt "
-                 "to true?");
-          Pass.TA.insertAfterToken(afterSemi, "\n}");
-          Pass.TA.increaseIndentation(
-                                SourceRange(scope.getIndentedRange().getBegin(),
-                                            (*retI)->getLocEnd()),
-                                      scope.CompoundParent->getLocStart());
-        } else {
-          Pass.TA.replaceStmt(*scope.Begin, "@autoreleasepool {");
-          Pass.TA.replaceStmt(*scope.End, "}");
-          Pass.TA.increaseIndentation(scope.getIndentedRange(),
-                                      scope.CompoundParent->getLocStart());
-        }
-      }
-
-      // Remove rest of pool var references.
-      for (llvm::SmallVectorImpl<PoolScope>::iterator
-             scpI = info.Scopes.begin(),
-             scpE = info.Scopes.end(); scpI != scpE; ++scpI) {
-        PoolScope &scope = *scpI;
-        for (llvm::SmallVectorImpl<ObjCMessageExpr *>::iterator
-               relI = scope.Releases.begin(),
-               relE = scope.Releases.end(); relI != relE; ++relI) {
-          clearUnavailableDiags(*relI);
-          Pass.TA.removeStmt(*relI);
-        }
-      }
-    }
-  }
-
-  bool VisitCompoundStmt(CompoundStmt *S) {
-    llvm::SmallVector<PoolScope, 4> Scopes;
-
-    for (Stmt::child_iterator
-           I = S->body_begin(), E = S->body_end(); I != E; ++I) {
-      Stmt *child = getEssential(*I);
-      if (DeclStmt *DclS = dyn_cast<DeclStmt>(child)) {
-        if (DclS->isSingleDecl()) {
-          if (VarDecl *VD = dyn_cast<VarDecl>(DclS->getSingleDecl())) {
-            if (isNSAutoreleasePool(VD->getType())) {
-              PoolVarInfo &info = PoolVars[VD];
-              info.Dcl = DclS;
-              ReferenceCollector refColl(info.Refs);
-              refColl.lookFor(VD, S);
-              // Does this statement follow the pattern:  
-              // NSAutoreleasePool * pool = [NSAutoreleasePool  new];
-              if (isPoolCreation(VD->getInit())) {
-                Scopes.push_back(PoolScope());
-                Scopes.back().PoolVar = VD;
-                Scopes.back().CompoundParent = S;
-                Scopes.back().Begin = I;
-              }
-            }
-          }
-        }
-      } else if (BinaryOperator *bop = dyn_cast<BinaryOperator>(child)) {
-        if (DeclRefExpr *dref = dyn_cast<DeclRefExpr>(bop->getLHS())) {
-          if (VarDecl *VD = dyn_cast<VarDecl>(dref->getDecl())) {
-            // Does this statement follow the pattern:  
-            // pool = [NSAutoreleasePool  new];
-            if (isNSAutoreleasePool(VD->getType()) &&
-                isPoolCreation(bop->getRHS())) {
-              Scopes.push_back(PoolScope());
-              Scopes.back().PoolVar = VD;
-              Scopes.back().CompoundParent = S;
-              Scopes.back().Begin = I;
-            }
-          }
-        }
-      }
-
-      if (Scopes.empty())
-        continue;
-
-      if (isPoolDrain(Scopes.back().PoolVar, child)) {
-        PoolScope &scope = Scopes.back();
-        scope.End = I;
-        handlePoolScope(scope, S);
-        Scopes.pop_back();
-      }
-    }
-    return true;
-  }
-
-private:
-  void clearUnavailableDiags(Stmt *S) {
-    if (S)
-      Pass.TA.clearDiagnostic(diag::err_unavailable,
-                              diag::err_unavailable_message,
-                              S->getSourceRange());
-  }
-
-  struct PoolScope {
-    VarDecl *PoolVar;
-    CompoundStmt *CompoundParent;
-    Stmt::child_iterator Begin;
-    Stmt::child_iterator End;
-    bool IsFollowedBySimpleReturnStmt;
-    llvm::SmallVector<ObjCMessageExpr *, 4> Releases;
-
-    PoolScope() : PoolVar(0), CompoundParent(0), Begin(), End(),
-                  IsFollowedBySimpleReturnStmt(false) { }
-
-    SourceRange getIndentedRange() const {
-      Stmt::child_iterator rangeS = Begin;
-      ++rangeS;
-      if (rangeS == End)
-        return SourceRange();
-      Stmt::child_iterator rangeE = Begin;
-      for (Stmt::child_iterator I = rangeS; I != End; ++I)
-        ++rangeE;
-      return SourceRange((*rangeS)->getLocStart(), (*rangeE)->getLocEnd());
-    }
-  };
-
-  class NameReferenceChecker : public RecursiveASTVisitor<NameReferenceChecker>{
-    ASTContext &Ctx;
-    SourceRange ScopeRange;
-    SourceLocation &referenceLoc, &declarationLoc;
-
-  public:
-    NameReferenceChecker(ASTContext &ctx, PoolScope &scope,
-                         SourceLocation &referenceLoc,
-                         SourceLocation &declarationLoc)
-      : Ctx(ctx), referenceLoc(referenceLoc),
-        declarationLoc(declarationLoc) {
-      ScopeRange = SourceRange((*scope.Begin)->getLocStart(),
-                               (*scope.End)->getLocStart());
-    }
-
-    bool VisitDeclRefExpr(DeclRefExpr *E) {
-      return checkRef(E->getLocation(), E->getDecl()->getLocation());
-    }
-
-    bool VisitBlockDeclRefExpr(BlockDeclRefExpr *E) {
-      return checkRef(E->getLocation(), E->getDecl()->getLocation());
-    }
-
-    bool VisitTypedefTypeLoc(TypedefTypeLoc TL) {
-      return checkRef(TL.getBeginLoc(), TL.getTypedefNameDecl()->getLocation());
-    }
-
-    bool VisitTagTypeLoc(TagTypeLoc TL) {
-      return checkRef(TL.getBeginLoc(), TL.getDecl()->getLocation());
-    }
-
-  private:
-    bool checkRef(SourceLocation refLoc, SourceLocation declLoc) {
-      if (isInScope(declLoc)) {
-        referenceLoc = refLoc;
-        declarationLoc = declLoc;
-        return false;
-      }
-      return true;
-    }
-
-    bool isInScope(SourceLocation loc) {
-      SourceManager &SM = Ctx.getSourceManager();
-      if (SM.isBeforeInTranslationUnit(loc, ScopeRange.getBegin()))
-        return false;
-      return SM.isBeforeInTranslationUnit(loc, ScopeRange.getEnd());
-    }
-  };
-
-  void handlePoolScope(PoolScope &scope, CompoundStmt *compoundS) {
-    // Check that all names declared inside the scope are not used
-    // outside the scope.
-    {
-      bool nameUsedOutsideScope = false;
-      SourceLocation referenceLoc, declarationLoc;
-      Stmt::child_iterator SI = scope.End, SE = compoundS->body_end();
-      ++SI;
-      // Check if the autoreleasepool scope is followed by a simple return
-      // statement, in which case we will include the return in the scope.
-      if (SI != SE)
-        if (ReturnStmt *retS = dyn_cast<ReturnStmt>(*SI))
-          if ((retS->getRetValue() == 0 ||
-               isa<DeclRefExpr>(retS->getRetValue()->IgnoreParenCasts())) &&
-              findLocationAfterSemi(Pass.Ctx, retS->getLocEnd()).isValid()) {
-            scope.IsFollowedBySimpleReturnStmt = true;
-            ++SI; // the return will be included in scope, don't check it.
-          }
-      
-      for (; SI != SE; ++SI) {
-        nameUsedOutsideScope = !NameReferenceChecker(Pass.Ctx, scope,
-                                                     referenceLoc,
-                                              declarationLoc).TraverseStmt(*SI);
-        if (nameUsedOutsideScope)
-          break;
-      }
-
-      // If not all references were cleared it means some variables/typenames/etc
-      // declared inside the pool scope are used outside of it.
-      // We won't try to rewrite the pool.
-      if (nameUsedOutsideScope) {
-        Pass.TA.reportError("a name is referenced outside the "
-            "NSAutoreleasePool scope that it was declared in", referenceLoc);
-        Pass.TA.reportNote("name declared here", declarationLoc);
-        Pass.TA.reportNote("intended @autoreleasepool scope begins here",
-                           (*scope.Begin)->getLocStart());
-        Pass.TA.reportNote("intended @autoreleasepool scope ends here",
-                           (*scope.End)->getLocStart());
-        return;
-      }
-    }
-
-    // Collect all releases of the pool; they will be removed.
-    {
-      ReleaseCollector releaseColl(scope.PoolVar, scope.Releases);
-      Stmt::child_iterator I = scope.Begin;
-      ++I;
-      for (; I != scope.End; ++I)
-        releaseColl.TraverseStmt(*I);
-    }
-
-    PoolVars[scope.PoolVar].Scopes.push_back(scope);
-  }
-
-  bool isPoolCreation(Expr *E) {
-    if (!E) return false;
-    E = getEssential(E);
-    ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E);
-    if (!ME) return false;
-    if (ME->getMethodFamily() == OMF_new &&
-        ME->getReceiverKind() == ObjCMessageExpr::Class &&
-        isNSAutoreleasePool(ME->getReceiverInterface()))
-      return true;
-    if (ME->getReceiverKind() == ObjCMessageExpr::Instance &&
-        ME->getMethodFamily() == OMF_init) {
-      Expr *rec = getEssential(ME->getInstanceReceiver());
-      if (ObjCMessageExpr *recME = dyn_cast_or_null<ObjCMessageExpr>(rec)) {
-        if (recME->getMethodFamily() == OMF_alloc &&
-            recME->getReceiverKind() == ObjCMessageExpr::Class &&
-            isNSAutoreleasePool(recME->getReceiverInterface()))
-          return true;
-      }
-    }
-
-    return false;
-  }
-
-  bool isPoolDrain(VarDecl *poolVar, Stmt *S) {
-    if (!S) return false;
-    S = getEssential(S);
-    ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(S);
-    if (!ME) return false;
-    if (ME->getReceiverKind() == ObjCMessageExpr::Instance) {
-      Expr *rec = getEssential(ME->getInstanceReceiver());
-      if (DeclRefExpr *dref = dyn_cast<DeclRefExpr>(rec))
-        if (dref->getDecl() == poolVar)
-          return ME->getMethodFamily() == OMF_release ||
-                 ME->getSelector() == DrainSel;
-    }
-
-    return false;
-  }
-
-  bool isNSAutoreleasePool(ObjCInterfaceDecl *IDecl) {
-    return IDecl && IDecl->getIdentifier() == PoolII;
-  }
-
-  bool isNSAutoreleasePool(QualType Ty) {
-    QualType pointee = Ty->getPointeeType();
-    if (pointee.isNull())
-      return false;
-    if (const ObjCInterfaceType *interT = pointee->getAs<ObjCInterfaceType>())
-      return isNSAutoreleasePool(interT->getDecl());
-    return false;
-  }
-
-  static Expr *getEssential(Expr *E) {
-    return cast<Expr>(getEssential((Stmt*)E));
-  }
-  static Stmt *getEssential(Stmt *S) {
-    if (ExprWithCleanups *EWC = dyn_cast<ExprWithCleanups>(S))
-      S = EWC->getSubExpr();
-    if (Expr *E = dyn_cast<Expr>(S))
-      S = E->IgnoreParenCasts();
-    return S;
-  }
-
-  Decl *Dcl;
-  Stmt *Body;
-  MigrationPass &Pass;
-
-  IdentifierInfo *PoolII;
-  Selector DrainSel;
-  
-  struct PoolVarInfo {
-    DeclStmt *Dcl;
-    llvm::DenseSet<Expr *> Refs;
-    llvm::SmallVector<PoolScope, 2> Scopes;
-
-    PoolVarInfo() : Dcl(0) { }
-  };
-
-  std::map<VarDecl *, PoolVarInfo> PoolVars;
-};
-
-} // anonymous namespace
-
-static void rewriteAutoreleasePool(MigrationPass &pass) {
-  BodyTransform<AutoreleasePoolRewriter> trans(pass);
-  trans.TraverseDecl(pass.Ctx.getTranslationUnitDecl());
-}
-
-//===----------------------------------------------------------------------===//
-// removeRetainReleaseDealloc
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-class RetainReleaseDeallocRemover :
-                       public RecursiveASTVisitor<RetainReleaseDeallocRemover> {
-  Decl *Dcl;
-  Stmt *Body;
-  MigrationPass &Pass;
-
-  llvm::DenseSet<Expr *> Removables;
-  llvm::OwningPtr<ParentMap> StmtMap;
-
-public:
-  RetainReleaseDeallocRemover(Decl *D, MigrationPass &pass)
-    : Dcl(D), Body(0), Pass(pass) { }
-
-  void transformBody(Stmt *body) {
-    Body = body;
-    RemovablesCollector(Removables).TraverseStmt(body);
-    StmtMap.reset(new ParentMap(body));
-    TraverseStmt(body);
-  }
-
-  bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
-    switch (E->getMethodFamily()) {
-    default:
-      return true;
-    case OMF_retain:
-    case OMF_release:
-    case OMF_autorelease:
-      if (E->getReceiverKind() == ObjCMessageExpr::Instance)
-        if (Expr *rec = E->getInstanceReceiver()) {
-          rec = rec->IgnoreParenImpCasts();
-          if (rec->getType().getObjCLifetime() == Qualifiers::OCL_ExplicitNone){
-            std::string err = "It is not safe to remove '";
-            err += E->getSelector().getAsString() + "' message on "
-                "an __unsafe_unretained type";
-            Pass.TA.reportError(err, rec->getLocStart());
-            return true;
-          }
-        }
-    case OMF_dealloc:
-      break;
-    }
-
-    switch (E->getReceiverKind()) {
-    default:
-      return true;
-    case ObjCMessageExpr::SuperInstance: {
-      Transaction Trans(Pass.TA);
-      Pass.TA.clearDiagnostic(diag::err_arc_illegal_explicit_message,
-                              diag::err_unavailable,
-                              diag::err_unavailable_message,
-                              E->getSuperLoc());
-      if (tryRemoving(E))
-        return true;
-      Pass.TA.replace(E->getSourceRange(), "self");
-      return true;
-    }
-    case ObjCMessageExpr::Instance:
-      break;
-    }
-
-    Expr *rec = E->getInstanceReceiver();
-    if (!rec) return true;
-
-    Transaction Trans(Pass.TA);
-    Pass.TA.clearDiagnostic(diag::err_arc_illegal_explicit_message,
-                            diag::err_unavailable,
-                            diag::err_unavailable_message,
-                            rec->getExprLoc());
-    if (!HasSideEffects(E, Pass.Ctx)) {
-      if (tryRemoving(E))
-        return true;
-    }
-    Pass.TA.replace(E->getSourceRange(), rec->getSourceRange());
-
-    return true;
-  }
-
-private:
-  bool isRemovable(Expr *E) const {
-    return Removables.count(E);
-  }
-  
-  bool tryRemoving(Expr *E) const {
-    if (isRemovable(E)) {
-      Pass.TA.removeStmt(E);
-      return true;
-    }
-
-    if (ParenExpr *parenE = dyn_cast_or_null<ParenExpr>(StmtMap->getParent(E)))
-      return tryRemoving(parenE);
-
-    if (BinaryOperator *
-          bopE = dyn_cast_or_null<BinaryOperator>(StmtMap->getParent(E))) {
-      if (bopE->getOpcode() == BO_Comma && bopE->getLHS() == E &&
-          isRemovable(bopE)) {
-        Pass.TA.replace(bopE->getSourceRange(), bopE->getRHS()->getSourceRange());
-        return true;
-      }
-    }
-
-    return false;
-  }
-
-};
-
-} // anonymous namespace
-
-static void removeRetainReleaseDealloc(MigrationPass &pass) {
-  BodyTransform<RetainReleaseDeallocRemover> trans(pass);
-  trans.TraverseDecl(pass.Ctx.getTranslationUnitDecl());
-}
-
-//===----------------------------------------------------------------------===//
-// removeEmptyStatements
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-class EmptyStatementsRemover :
-                            public RecursiveASTVisitor<EmptyStatementsRemover> {
-  MigrationPass &Pass;
-  llvm::DenseSet<unsigned> MacroLocs;
-
-public:
-  EmptyStatementsRemover(MigrationPass &pass) : Pass(pass) {
-    for (unsigned i = 0, e = Pass.ARCMTMacroLocs.size(); i != e; ++i)
-      MacroLocs.insert(Pass.ARCMTMacroLocs[i].getRawEncoding());
-  }
-
-  bool TraverseStmtExpr(StmtExpr *E) {
-    CompoundStmt *S = E->getSubStmt();
-    for (CompoundStmt::body_iterator
-           I = S->body_begin(), E = S->body_end(); I != E; ++I) {
-      if (I != E - 1)
-        check(*I);
-      TraverseStmt(*I);
-    }
-    return true;
-  }
-
-  bool VisitCompoundStmt(CompoundStmt *S) {
-    for (CompoundStmt::body_iterator
-           I = S->body_begin(), E = S->body_end(); I != E; ++I)
-      check(*I);
-    return true;
-  }
-
-  bool isMacroLoc(SourceLocation loc) {
-    if (loc.isInvalid()) return false;
-    return MacroLocs.count(loc.getRawEncoding());
-  }
-
-  ASTContext &getContext() { return Pass.Ctx; }
-
-private:
-  /// \brief Returns true if the statement became empty due to previous
-  /// transformations.
-  class EmptyChecker : public StmtVisitor<EmptyChecker, bool> {
-    EmptyStatementsRemover &Trans;
-
-  public:
-    EmptyChecker(EmptyStatementsRemover &trans) : Trans(trans) { }
-
-    bool VisitNullStmt(NullStmt *S) {
-      return Trans.isMacroLoc(S->getLeadingEmptyMacroLoc());
-    }
-    bool VisitCompoundStmt(CompoundStmt *S) {
-      if (S->body_empty())
-        return false; // was already empty, not because of transformations.
-      for (CompoundStmt::body_iterator
-             I = S->body_begin(), E = S->body_end(); I != E; ++I)
-        if (!Visit(*I))
-          return false;
-      return true;
-    }
-    bool VisitIfStmt(IfStmt *S) {
-      if (S->getConditionVariable())
-        return false;
-      Expr *condE = S->getCond();
-      if (!condE)
-        return false;
-      if (HasSideEffects(condE, Trans.getContext()))
-        return false;
-      if (!S->getThen() || !Visit(S->getThen()))
-        return false;
-      if (S->getElse() && !Visit(S->getElse()))
-        return false;
-      return true;
-    }
-    bool VisitWhileStmt(WhileStmt *S) {
-      if (S->getConditionVariable())
-        return false;
-      Expr *condE = S->getCond();
-      if (!condE)
-        return false;
-      if (HasSideEffects(condE, Trans.getContext()))
-        return false;
-      if (!S->getBody())
-        return false;
-      return Visit(S->getBody());
-    }
-    bool VisitDoStmt(DoStmt *S) {
-      Expr *condE = S->getCond();
-      if (!condE)
-        return false;
-      if (HasSideEffects(condE, Trans.getContext()))
-        return false;
-      if (!S->getBody())
-        return false;
-      return Visit(S->getBody());
-    }
-    bool VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
-      Expr *Exp = S->getCollection();
-      if (!Exp)
-        return false;
-      if (HasSideEffects(Exp, Trans.getContext()))
-        return false;
-      if (!S->getBody())
-        return false;
-      return Visit(S->getBody());
-    }
-    bool VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S) {
-      if (!S->getSubStmt())
-        return false;
-      return Visit(S->getSubStmt());
-    }
-  };
-
-  void check(Stmt *S) {
-    if (!S) return;
-    if (EmptyChecker(*this).Visit(S)) {
-      Transaction Trans(Pass.TA);
-      Pass.TA.removeStmt(S);
-    }
-  }
-};
-
-} // anonymous namespace
-
-static void removeEmptyStatements(MigrationPass &pass) {
-  EmptyStatementsRemover(pass).TraverseDecl(pass.Ctx.getTranslationUnitDecl());
-
-  for (unsigned i = 0, e = pass.ARCMTMacroLocs.size(); i != e; ++i) {
-    Transaction Trans(pass.TA);
-    pass.TA.remove(pass.ARCMTMacroLocs[i]);
-  }
-}
-
-//===----------------------------------------------------------------------===//
-// changeIvarsOfAssignProperties.
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-class AssignPropertiesTrans {
-  MigrationPass &Pass;
-  struct PropData {
-    ObjCPropertyDecl *PropD;
-    ObjCIvarDecl *IvarD;
-    bool ShouldChangeToWeak;
-    SourceLocation ArcPropAssignErrorLoc;
-  };
-
-  typedef llvm::SmallVector<PropData, 2> PropsTy; 
-  typedef llvm::DenseMap<unsigned, PropsTy> PropsMapTy;
-  PropsMapTy PropsMap;
-
-public:
-  AssignPropertiesTrans(MigrationPass &pass) : Pass(pass) { }
-
-  void doTransform(ObjCImplementationDecl *D) {
-    SourceManager &SM = Pass.Ctx.getSourceManager();
-
-    ObjCInterfaceDecl *IFace = D->getClassInterface();
-    for (ObjCInterfaceDecl::prop_iterator
-           I = IFace->prop_begin(), E = IFace->prop_end(); I != E; ++I) {
-      ObjCPropertyDecl *propD = *I;
-      unsigned loc = SM.getInstantiationLoc(propD->getAtLoc()).getRawEncoding();
-      PropsTy &props = PropsMap[loc];
-      props.push_back(PropData());
-      props.back().PropD = propD;
-      props.back().IvarD = 0;
-      props.back().ShouldChangeToWeak = false;
-    }
-
-    typedef DeclContext::specific_decl_iterator<ObjCPropertyImplDecl>
-        prop_impl_iterator;
-    for (prop_impl_iterator
-           I = prop_impl_iterator(D->decls_begin()),
-           E = prop_impl_iterator(D->decls_end()); I != E; ++I) {
-      VisitObjCPropertyImplDecl(*I);
-    }
-
-    for (PropsMapTy::iterator
-           I = PropsMap.begin(), E = PropsMap.end(); I != E; ++I) {
-      SourceLocation atLoc = SourceLocation::getFromRawEncoding(I->first);
-      PropsTy &props = I->second;
-      if (shouldApplyWeakToAllProp(props)) {
-        if (changeAssignToWeak(atLoc)) {
-          // Couldn't add the 'weak' property attribute,
-          // try adding __unsafe_unretained.
-          applyUnsafeUnretained(props);
-        } else {
-          for (PropsTy::iterator
-                 PI = props.begin(), PE = props.end(); PI != PE; ++PI) {
-            applyWeak(*PI);
-          }
-        }
-      } else {
-        // We should not add 'weak' attribute since not all properties need it.
-        // So just add __unsafe_unretained to the ivars.
-        applyUnsafeUnretained(props);
-      }
-    }
-  }
-
-  bool shouldApplyWeakToAllProp(PropsTy &props) {
-    for (PropsTy::iterator
-           PI = props.begin(), PE = props.end(); PI != PE; ++PI) {
-      if (!PI->ShouldChangeToWeak)
-        return false;
-    }
-    return true;
-  }
-
-  void applyWeak(PropData &prop) {
-    assert(!Pass.Ctx.getLangOptions().ObjCNoAutoRefCountRuntime);
-
-    Transaction Trans(Pass.TA);
-    Pass.TA.insert(prop.IvarD->getLocation(), "__weak "); 
-    Pass.TA.clearDiagnostic(diag::err_arc_assign_property_lifetime,
-                            prop.ArcPropAssignErrorLoc);
-  }
-
-  void applyUnsafeUnretained(PropsTy &props) {
-    for (PropsTy::iterator
-           PI = props.begin(), PE = props.end(); PI != PE; ++PI) {
-      if (PI->ShouldChangeToWeak) {
-        Transaction Trans(Pass.TA);
-        Pass.TA.insert(PI->IvarD->getLocation(), "__unsafe_unretained ");
-        Pass.TA.clearDiagnostic(diag::err_arc_assign_property_lifetime,
-                                PI->ArcPropAssignErrorLoc);
-      }
-    }
-  }
-
-  bool VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
-    SourceManager &SM = Pass.Ctx.getSourceManager();
-
-    if (D->getPropertyImplementation() != ObjCPropertyImplDecl::Synthesize)
-      return true;
-    ObjCPropertyDecl *propD = D->getPropertyDecl();
-    if (!propD || propD->isInvalidDecl())
-      return true;
-    ObjCIvarDecl *ivarD = D->getPropertyIvarDecl();
-    if (!ivarD || ivarD->isInvalidDecl())
-      return true;
-    if (!(propD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_assign))
-      return true;
-    if (isa<AttributedType>(ivarD->getType().getTypePtr()))
-      return true;
-    if (ivarD->getType().getLocalQualifiers().getObjCLifetime()
-          != Qualifiers::OCL_Strong)
-      return true;
-    if (!Pass.TA.hasDiagnostic(
-                      diag::err_arc_assign_property_lifetime, D->getLocation()))
-      return true;
-
-    // There is a "error: existing ivar for assign property must be
-    // __unsafe_unretained"; fix it.
-
-    if (Pass.Ctx.getLangOptions().ObjCNoAutoRefCountRuntime) {
-      // We will just add __unsafe_unretained to the ivar.
-      Transaction Trans(Pass.TA);
-      Pass.TA.insert(ivarD->getLocation(), "__unsafe_unretained ");
-      Pass.TA.clearDiagnostic(
-                      diag::err_arc_assign_property_lifetime, D->getLocation());
-    } else {
-      // Mark that we want the ivar to become weak.
-      unsigned loc = SM.getInstantiationLoc(propD->getAtLoc()).getRawEncoding();
-      PropsTy &props = PropsMap[loc];
-      for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) {
-        if (I->PropD == propD) {
-          I->IvarD = ivarD;
-          I->ShouldChangeToWeak = true;
-          I->ArcPropAssignErrorLoc = D->getLocation();
-        }
-      }
-    }
-
-    return true;
-  }
-
-private:
-  bool changeAssignToWeak(SourceLocation atLoc) {
-    SourceManager &SM = Pass.Ctx.getSourceManager();
-
-    // Break down the source location.
-    std::pair<FileID, unsigned> locInfo = SM.getDecomposedLoc(atLoc);
-
-    // Try to load the file buffer.
-    bool invalidTemp = false;
-    llvm::StringRef file = SM.getBufferData(locInfo.first, &invalidTemp);
-    if (invalidTemp)
-      return true;
-
-    const char *tokenBegin = file.data() + locInfo.second;
-
-    // Lex from the start of the given location.
-    Lexer lexer(SM.getLocForStartOfFile(locInfo.first),
-                Pass.Ctx.getLangOptions(),
-                file.begin(), tokenBegin, file.end());
-    Token tok;
-    lexer.LexFromRawLexer(tok);
-    if (tok.isNot(tok::at)) return true;
-    lexer.LexFromRawLexer(tok);
-    if (tok.isNot(tok::raw_identifier)) return true;
-    if (llvm::StringRef(tok.getRawIdentifierData(), tok.getLength())
-          != "property")
-      return true;
-    lexer.LexFromRawLexer(tok);
-    if (tok.isNot(tok::l_paren)) return true;
-    
-    SourceLocation LParen = tok.getLocation();
-    SourceLocation assignLoc;
-    bool isEmpty = false;
-
-    lexer.LexFromRawLexer(tok);
-    if (tok.is(tok::r_paren)) {
-      isEmpty = true;
-    } else {
-      while (1) {
-        if (tok.isNot(tok::raw_identifier)) return true;
-        llvm::StringRef ident(tok.getRawIdentifierData(), tok.getLength());
-        if (ident == "assign")
-          assignLoc = tok.getLocation();
-  
-        do {
-          lexer.LexFromRawLexer(tok);
-        } while (tok.isNot(tok::comma) && tok.isNot(tok::r_paren));
-        if (tok.is(tok::r_paren))
-          break;
-        lexer.LexFromRawLexer(tok);
-      }
-    }
-
-    Transaction Trans(Pass.TA);
-    if (assignLoc.isValid())
-      Pass.TA.replaceText(assignLoc, "assign", "weak");
-    else 
-      Pass.TA.insertAfterToken(LParen, isEmpty ? "weak" : "weak, ");
-    return false;
-  }
-};
-
-class PropertiesChecker : public RecursiveASTVisitor<PropertiesChecker> {
-  MigrationPass &Pass;
-
-public:
-  PropertiesChecker(MigrationPass &pass) : Pass(pass) { }
-
-  bool TraverseObjCImplementationDecl(ObjCImplementationDecl *D) {
-    AssignPropertiesTrans(Pass).doTransform(D);
-    return true;
-  }
-};
-
-} // anonymous namespace
-
-static void changeIvarsOfAssignProperties(MigrationPass &pass) {
-  PropertiesChecker(pass).TraverseDecl(pass.Ctx.getTranslationUnitDecl());
-}
-
-//===----------------------------------------------------------------------===//
-// rewriteUnusedDelegateInit
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-class UnusedInitRewriter : public RecursiveASTVisitor<UnusedInitRewriter> {
-  Decl *Dcl;
-  Stmt *Body;
-  MigrationPass &Pass;
-
-  llvm::DenseSet<Expr *> Removables;
-
-public:
-  UnusedInitRewriter(Decl *D, MigrationPass &pass)
-    : Dcl(D), Body(0), Pass(pass) { }
-
-  void transformBody(Stmt *body) {
-    Body = body;
-    RemovablesCollector(Removables).TraverseStmt(body);
-    TraverseStmt(body);
-  }
-
-  bool VisitObjCMessageExpr(ObjCMessageExpr *ME) {
-    if (ME->isDelegateInitCall() &&
-        isRemovable(ME) &&
-        Pass.TA.hasDiagnostic(diag::err_arc_unused_init_message,
-                              ME->getExprLoc())) {
-      Transaction Trans(Pass.TA);
-      Pass.TA.clearDiagnostic(diag::err_arc_unused_init_message,
-                              ME->getExprLoc());
-      Pass.TA.insert(ME->getExprLoc(), "self = ");
-    }
-    return true;
-  }
-
-private:
-  bool isRemovable(Expr *E) const {
-    return Removables.count(E);
-  }
-};
-
-} // anonymous namespace
-
-static void rewriteUnusedDelegateInit(MigrationPass &pass) {
-  BodyTransform<UnusedInitRewriter> trans(pass);
-  trans.TraverseDecl(pass.Ctx.getTranslationUnitDecl());
-}
-
-//===----------------------------------------------------------------------===//
-// rewriteBlockObjCVariable
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-class RootBlockObjCVarRewriter :
-                          public RecursiveASTVisitor<RootBlockObjCVarRewriter> {
-  MigrationPass &Pass;
-  llvm::DenseSet<VarDecl *> CheckedVars;
-
-  class BlockVarChecker : public RecursiveASTVisitor<BlockVarChecker> {
-    VarDecl *Var;
-  
-    typedef RecursiveASTVisitor<BlockVarChecker> base;
-  public:
-    BlockVarChecker(VarDecl *var) : Var(var) { }
-  
-    bool TraverseImplicitCastExpr(ImplicitCastExpr *castE) {
-      if (BlockDeclRefExpr *
-            ref = dyn_cast<BlockDeclRefExpr>(castE->getSubExpr())) {
-        if (ref->getDecl() == Var) {
-          if (castE->getCastKind() == CK_LValueToRValue)
-            return true; // Using the value of the variable.
-          if (castE->getCastKind() == CK_NoOp && castE->isLValue() &&
-              Var->getASTContext().getLangOptions().CPlusPlus)
-            return true; // Binding to const C++ reference.
-        }
-      }
-
-      return base::TraverseImplicitCastExpr(castE);
-    }
-
-    bool VisitBlockDeclRefExpr(BlockDeclRefExpr *E) {
-      if (E->getDecl() == Var)
-        return false; // The reference of the variable, and not just its value,
-                      //  is needed.
-      return true;
-    }
-  };
-
-public:
-  RootBlockObjCVarRewriter(MigrationPass &pass) : Pass(pass) { }
-
-  bool VisitBlockDecl(BlockDecl *block) {
-    llvm::SmallVector<VarDecl *, 4> BlockVars;
-    
-    for (BlockDecl::capture_iterator
-           I = block->capture_begin(), E = block->capture_end(); I != E; ++I) {
-      VarDecl *var = I->getVariable();
-      if (I->isByRef() &&
-          !isAlreadyChecked(var) &&
-          var->getType()->isObjCObjectPointerType() &&
-          isImplicitStrong(var->getType())) {
-        BlockVars.push_back(var);
-      }
-    }
-
-    for (unsigned i = 0, e = BlockVars.size(); i != e; ++i) {
-      VarDecl *var = BlockVars[i];
-      CheckedVars.insert(var);
-
-      BlockVarChecker checker(var);
-      bool onlyValueOfVarIsNeeded = checker.TraverseStmt(block->getBody());
-      if (onlyValueOfVarIsNeeded) {
-        BlocksAttr *attr = var->getAttr<BlocksAttr>();
-        if(!attr)
-          continue;
-        bool hasARCRuntime = !Pass.Ctx.getLangOptions().ObjCNoAutoRefCountRuntime;
-        SourceManager &SM = Pass.Ctx.getSourceManager();
-        Transaction Trans(Pass.TA);
-        Pass.TA.replaceText(SM.getInstantiationLoc(attr->getLocation()),
-                            "__block",
-                            hasARCRuntime ? "__weak" : "__unsafe_unretained");
-      }
-
-    }
-
-    return true;
-  }
-
-private:
-  bool isAlreadyChecked(VarDecl *VD) {
-    return CheckedVars.count(VD);
-  }
-
-  bool isImplicitStrong(QualType ty) {
-    if (isa<AttributedType>(ty.getTypePtr()))
-      return false;
-    return ty.getLocalQualifiers().getObjCLifetime() == Qualifiers::OCL_Strong;
-  }
-};
-
-class BlockObjCVarRewriter : public RecursiveASTVisitor<BlockObjCVarRewriter> {
-  MigrationPass &Pass;
-
-public:
-  BlockObjCVarRewriter(MigrationPass &pass) : Pass(pass) { }
-
-  bool TraverseBlockDecl(BlockDecl *block) {
-    RootBlockObjCVarRewriter(Pass).TraverseDecl(block);
-    return true;
-  }
-};
-
-} // anonymous namespace
-
-static void rewriteBlockObjCVariable(MigrationPass &pass) {
-  BlockObjCVarRewriter trans(pass);
-  trans.TraverseDecl(pass.Ctx.getTranslationUnitDecl());
-}
-
-//===----------------------------------------------------------------------===//
-// removeZeroOutIvarsInDealloc
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-class ZeroOutInDeallocRemover :
-                           public RecursiveASTVisitor<ZeroOutInDeallocRemover> {
-  typedef RecursiveASTVisitor<ZeroOutInDeallocRemover> base;
-
-  MigrationPass &Pass;
-
-  llvm::DenseMap<ObjCPropertyDecl*, ObjCPropertyImplDecl*> SynthesizedProperties;
-  ImplicitParamDecl *SelfD;
-  llvm::DenseSet<Expr *> Removables;
-
-public:
-  ZeroOutInDeallocRemover(MigrationPass &pass) : Pass(pass), SelfD(0) { }
-
-  bool VisitObjCMessageExpr(ObjCMessageExpr *ME) {
-    ASTContext &Ctx = Pass.Ctx;
-    TransformActions &TA = Pass.TA;
-
-    if (ME->getReceiverKind() != ObjCMessageExpr::Instance)
-      return true;
-    Expr *receiver = ME->getInstanceReceiver();
-    if (!receiver)
-      return true;
-
-    DeclRefExpr *refE = dyn_cast<DeclRefExpr>(receiver->IgnoreParenCasts());
-    if (!refE || refE->getDecl() != SelfD)
-      return true;
-
-    bool BackedBySynthesizeSetter = false;
-    for (llvm::DenseMap<ObjCPropertyDecl*, ObjCPropertyImplDecl*>::iterator
-         P = SynthesizedProperties.begin(), 
-         E = SynthesizedProperties.end(); P != E; ++P) {
-      ObjCPropertyDecl *PropDecl = P->first;
-      if (PropDecl->getSetterName() == ME->getSelector()) {
-        BackedBySynthesizeSetter = true;
-        break;
-      }
-    }
-    if (!BackedBySynthesizeSetter)
-      return true;
-    
-    // Remove the setter message if RHS is null
-    Transaction Trans(TA);
-    Expr *RHS = ME->getArg(0);
-    bool RHSIsNull = 
-      RHS->isNullPointerConstant(Ctx,
-                                 Expr::NPC_ValueDependentIsNull);
-    if (RHSIsNull && isRemovable(ME))
-      TA.removeStmt(ME);
-
-    return true;
-  }
-
-  bool VisitBinaryOperator(BinaryOperator *BOE) {
-    if (isZeroingPropIvar(BOE) && isRemovable(BOE)) {
-      Transaction Trans(Pass.TA);
-      Pass.TA.removeStmt(BOE);
-    }
-
-    return true;
-  }
-
-  bool TraverseObjCMethodDecl(ObjCMethodDecl *D) {
-    if (D->getMethodFamily() != OMF_dealloc)
-      return true;
-    if (!D->hasBody())
-      return true;
-
-    ObjCImplDecl *IMD = dyn_cast<ObjCImplDecl>(D->getDeclContext());
-    if (!IMD)
-      return true;
-
-    SelfD = D->getSelfDecl();
-    RemovablesCollector(Removables).TraverseStmt(D->getBody());
-
-    // For a 'dealloc' method use, find all property implementations in
-    // this class implementation.
-    for (ObjCImplDecl::propimpl_iterator
-           I = IMD->propimpl_begin(), EI = IMD->propimpl_end(); I != EI; ++I) {
-        ObjCPropertyImplDecl *PID = *I;
-        if (PID->getPropertyImplementation() ==
-            ObjCPropertyImplDecl::Synthesize) {
-          ObjCPropertyDecl *PD = PID->getPropertyDecl();
-          ObjCMethodDecl *setterM = PD->getSetterMethodDecl();
-          if (!(setterM && setterM->isDefined())) {
-            ObjCPropertyDecl::PropertyAttributeKind AttrKind = 
-              PD->getPropertyAttributes();
-              if (AttrKind & 
-                  (ObjCPropertyDecl::OBJC_PR_retain | 
-                   ObjCPropertyDecl::OBJC_PR_copy   |
-                   ObjCPropertyDecl::OBJC_PR_strong))
-                SynthesizedProperties[PD] = PID;
-          }
-        }
-    }
-
-    // Now, remove all zeroing of ivars etc.
-    base::TraverseObjCMethodDecl(D);
-
-    // clear out for next method.
-    SynthesizedProperties.clear();
-    SelfD = 0;
-    Removables.clear();
-    return true;
-  }
-
-  bool TraverseFunctionDecl(FunctionDecl *D) { return true; }
-  bool TraverseBlockDecl(BlockDecl *block) { return true; }
-  bool TraverseBlockExpr(BlockExpr *block) { return true; }
-
-private:
-  bool isRemovable(Expr *E) const {
-    return Removables.count(E);
-  }
-
-  bool isZeroingPropIvar(Expr *E) {
-    BinaryOperator *BOE = dyn_cast_or_null<BinaryOperator>(E);
-    if (!BOE) return false;
-
-    if (BOE->getOpcode() == BO_Comma)
-      return isZeroingPropIvar(BOE->getLHS()) &&
-             isZeroingPropIvar(BOE->getRHS());
-
-    if (BOE->getOpcode() != BO_Assign)
-        return false;
-
-    ASTContext &Ctx = Pass.Ctx;
-
-    Expr *LHS = BOE->getLHS();
-    if (ObjCIvarRefExpr *IV = dyn_cast<ObjCIvarRefExpr>(LHS)) {
-      ObjCIvarDecl *IVDecl = IV->getDecl();
-      if (!IVDecl->getType()->isObjCObjectPointerType())
-        return false;
-      bool IvarBacksPropertySynthesis = false;
-      for (llvm::DenseMap<ObjCPropertyDecl*, ObjCPropertyImplDecl*>::iterator
-           P = SynthesizedProperties.begin(), 
-           E = SynthesizedProperties.end(); P != E; ++P) {
-        ObjCPropertyImplDecl *PropImpDecl = P->second;
-        if (PropImpDecl && PropImpDecl->getPropertyIvarDecl() == IVDecl) {
-          IvarBacksPropertySynthesis = true;
-          break;
-        }
-      }
-      if (!IvarBacksPropertySynthesis)
-        return false;
-    }
-    else if (ObjCPropertyRefExpr *PropRefExp = dyn_cast<ObjCPropertyRefExpr>(LHS)) {
-      // TODO: Using implicit property decl.
-      if (PropRefExp->isImplicitProperty())
-        return false;
-      if (ObjCPropertyDecl *PDecl = PropRefExp->getExplicitProperty()) {
-        if (!SynthesizedProperties.count(PDecl))
-          return false;
-      }
-    }
-    else
-        return false;
-
-    Expr *RHS = BOE->getRHS();
-    bool RHSIsNull = RHS->isNullPointerConstant(Ctx,
-                                                Expr::NPC_ValueDependentIsNull);
-    if (RHSIsNull)
-      return true;
-
-    return isZeroingPropIvar(RHS);
-  }
-};
-
-} // anonymous namespace
-
-static void removeZeroOutIvarsInDealloc(MigrationPass &pass) {
-  ZeroOutInDeallocRemover trans(pass);
-  trans.TraverseDecl(pass.Ctx.getTranslationUnitDecl());
+void trans::collectRemovables(Stmt *S, ExprSet &exprs) {
+  RemovablesCollector(exprs).TraverseStmt(S);
 }
 
 //===----------------------------------------------------------------------===//
@@ -2065,10 +213,10 @@
   rewriteAutoreleasePool(pass);
   changeIvarsOfAssignProperties(pass);
   removeRetainReleaseDealloc(pass);
-  rewriteUnusedDelegateInit(pass);
-  removeZeroOutIvarsInDealloc(pass);
+  rewriteUnusedInitDelegate(pass);
+  removeZeroOutPropsInDealloc(pass);
   makeAssignARCSafe(pass);
-  castNonObjCToObjC(pass);
+  rewriteUnbridgedCasts(pass);
   rewriteBlockObjCVariable(pass);
   rewriteAllocCopyWithZone(pass);
 }
diff --git a/lib/ARCMigrate/Transforms.h b/lib/ARCMigrate/Transforms.h
new file mode 100644
index 0000000..d95b1bc
--- /dev/null
+++ b/lib/ARCMigrate/Transforms.h
@@ -0,0 +1,105 @@
+//===-- Transforms.h - Tranformations to ARC mode ---------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_ARCMIGRATE_TRANSFORMS_H
+#define LLVM_CLANG_LIB_ARCMIGRATE_TRANSFORMS_H
+
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "llvm/ADT/DenseSet.h"
+
+namespace clang {
+  class Decl;
+  class Stmt;
+  class BlockDecl;
+  class ObjCMethodDecl;
+  class FunctionDecl;
+
+namespace arcmt {
+  class MigrationPass;
+
+namespace trans {
+
+//===----------------------------------------------------------------------===//
+// Transformations.
+//===----------------------------------------------------------------------===//
+
+void rewriteAutoreleasePool(MigrationPass &pass);
+void rewriteUnbridgedCasts(MigrationPass &pass);
+void rewriteAllocCopyWithZone(MigrationPass &pass);
+void makeAssignARCSafe(MigrationPass &pass);
+void removeRetainReleaseDealloc(MigrationPass &pass);
+void removeEmptyStatements(MigrationPass &pass);
+void removeZeroOutPropsInDealloc(MigrationPass &pass);
+void changeIvarsOfAssignProperties(MigrationPass &pass);
+void rewriteBlockObjCVariable(MigrationPass &pass);
+void removeDeallocMethod(MigrationPass &pass);
+void rewriteUnusedInitDelegate(MigrationPass &pass);
+
+//===----------------------------------------------------------------------===//
+// Helpers.
+//===----------------------------------------------------------------------===//
+
+/// \brief 'Loc' is the end of a statement range. This returns the location
+/// immediately after the semicolon following the statement.
+/// If no semicolon is found or the location is inside a macro, the returned
+/// source location will be invalid.
+SourceLocation findLocationAfterSemi(SourceLocation loc, ASTContext &Ctx);
+
+bool hasSideEffects(Expr *E, ASTContext &Ctx);
+
+template <typename BODY_TRANS>
+class BodyTransform : public RecursiveASTVisitor<BodyTransform<BODY_TRANS> > {
+  MigrationPass &Pass;
+
+public:
+  BodyTransform(MigrationPass &pass) : Pass(pass) { }
+
+  void handleBody(Decl *D) {
+    Stmt *body = D->getBody();
+    if (body) {
+      BODY_TRANS(D, Pass).transformBody(body);
+    }
+  }
+
+  bool TraverseBlockDecl(BlockDecl *D) {
+    handleBody(D);
+    return true;
+  }
+  bool TraverseObjCMethodDecl(ObjCMethodDecl *D) {
+    if (D->isThisDeclarationADefinition())
+      handleBody(D);
+    return true;
+  }
+  bool TraverseFunctionDecl(FunctionDecl *D) {
+    if (D->isThisDeclarationADefinition())
+      handleBody(D);
+    return true;
+  }
+};
+
+typedef llvm::DenseSet<Expr *> ExprSet;
+
+void clearRefsIn(Stmt *S, ExprSet &refs);
+template <typename iterator>
+void clearRefsIn(iterator begin, iterator end, ExprSet &refs) {
+  for (; begin != end; ++begin)
+    clearRefsIn(*begin, refs);
+}
+
+void collectRefs(ValueDecl *D, Stmt *S, ExprSet &refs);
+
+void collectRemovables(Stmt *S, ExprSet &exprs);
+
+} // end namespace trans
+
+} // end namespace arcmt
+
+} // end namespace clang
+
+#endif
