diff --git a/lib/Format/CMakeLists.txt b/lib/Format/CMakeLists.txt
index 560e38b..c4f9c6f 100644
--- a/lib/Format/CMakeLists.txt
+++ b/lib/Format/CMakeLists.txt
@@ -2,6 +2,7 @@
 
 add_clang_library(clangFormat
   BreakableToken.cpp
+  ContinuationIndenter.cpp
   Format.cpp
   TokenAnnotator.cpp
   UnwrappedLineParser.cpp
diff --git a/lib/Format/ContinuationIndenter.cpp b/lib/Format/ContinuationIndenter.cpp
new file mode 100644
index 0000000..b26d453
--- /dev/null
+++ b/lib/Format/ContinuationIndenter.cpp
@@ -0,0 +1,670 @@
+//===--- ContinuationIndenter.cpp - Format C++ code -----------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief This file implements the continuation indenter.
+///
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "format-formatter"
+
+#include "BreakableToken.h"
+#include "ContinuationIndenter.h"
+#include "WhitespaceManager.h"
+#include "clang/Basic/OperatorPrecedence.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Format/Format.h"
+#include "llvm/Support/Debug.h"
+#include <string>
+
+namespace clang {
+namespace format {
+
+// Returns the length of everything up to the first possible line break after
+// the ), ], } or > matching \c Tok.
+static unsigned getLengthToMatchingParen(const FormatToken &Tok) {
+  if (Tok.MatchingParen == NULL)
+    return 0;
+  FormatToken *End = Tok.MatchingParen;
+  while (End->Next && !End->Next->CanBreakBefore) {
+    End = End->Next;
+  }
+  return End->TotalLength - Tok.TotalLength + 1;
+}
+
+ContinuationIndenter::ContinuationIndenter(const FormatStyle &Style,
+                                           SourceManager &SourceMgr,
+                                           const AnnotatedLine &Line,
+                                           unsigned FirstIndent,
+                                           WhitespaceManager &Whitespaces,
+                                           encoding::Encoding Encoding,
+                                           bool BinPackInconclusiveFunctions)
+    : Style(Style), SourceMgr(SourceMgr), Line(Line), FirstIndent(FirstIndent),
+      Whitespaces(Whitespaces), Encoding(Encoding),
+      BinPackInconclusiveFunctions(BinPackInconclusiveFunctions) {}
+
+LineState ContinuationIndenter::getInitialState() {
+  // Initialize state dependent on indent.
+  LineState State;
+  State.Column = FirstIndent;
+  State.NextToken = Line.First;
+  State.Stack.push_back(ParenState(FirstIndent, FirstIndent,
+                                   /*AvoidBinPacking=*/false,
+                                   /*NoLineBreak=*/false));
+  State.LineContainsContinuedForLoopSection = false;
+  State.ParenLevel = 0;
+  State.StartOfStringLiteral = 0;
+  State.StartOfLineLevel = State.ParenLevel;
+  State.LowestLevelOnLine = State.ParenLevel;
+  State.IgnoreStackForComparison = false;
+
+  // The first token has already been indented and thus consumed.
+  moveStateToNextToken(State, /*DryRun=*/false,
+                       /*Newline=*/false);
+  return State;
+}
+
+bool ContinuationIndenter::canBreak(const LineState &State) {
+  const FormatToken &Current = *State.NextToken;
+  const FormatToken &Previous = *Current.Previous;
+  assert(&Previous == Current.Previous);
+  if (!Current.CanBreakBefore &&
+      !(Current.is(tok::r_brace) && State.Stack.back().BreakBeforeClosingBrace))
+    return false;
+  // The opening "{" of a braced list has to be on the same line as the first
+  // element if it is nested in another braced init list or function call.
+  if (!Current.MustBreakBefore && Previous.is(tok::l_brace) &&
+      Previous.Previous &&
+      Previous.Previous->isOneOf(tok::l_brace, tok::l_paren, tok::comma))
+    return false;
+  // This prevents breaks like:
+  //   ...
+  //   SomeParameter, OtherParameter).DoSomething(
+  //   ...
+  // As they hide "DoSomething" and are generally bad for readability.
+  if (Previous.opensScope() && State.LowestLevelOnLine < State.StartOfLineLevel)
+    return false;
+  return !State.Stack.back().NoLineBreak;
+}
+
+bool ContinuationIndenter::mustBreak(const LineState &State) {
+  const FormatToken &Current = *State.NextToken;
+  const FormatToken &Previous = *Current.Previous;
+  if (Current.MustBreakBefore || Current.Type == TT_InlineASMColon)
+    return true;
+  if (!Style.Cpp11BracedListStyle && Current.is(tok::r_brace) &&
+      State.Stack.back().BreakBeforeClosingBrace)
+    return true;
+  if (Previous.is(tok::semi) && State.LineContainsContinuedForLoopSection)
+    return true;
+  if (Style.BreakConstructorInitializersBeforeComma) {
+    if (Previous.Type == TT_CtorInitializerComma)
+      return false;
+    if (Current.Type == TT_CtorInitializerComma)
+      return true;
+  }
+  if ((Previous.isOneOf(tok::comma, tok::semi) || Current.is(tok::question) ||
+       (Current.Type == TT_ConditionalExpr &&
+        !(Current.is(tok::colon) && Previous.is(tok::question)))) &&
+      State.Stack.back().BreakBeforeParameter && !Current.isTrailingComment() &&
+      !Current.isOneOf(tok::r_paren, tok::r_brace))
+    return true;
+  if (Style.AlwaysBreakBeforeMultilineStrings &&
+      State.Column > State.Stack.back().Indent &&
+      Current.is(tok::string_literal) && Previous.isNot(tok::lessless) &&
+      Previous.Type != TT_InlineASMColon &&
+      ((Current.getNextNonComment() &&
+        Current.getNextNonComment()->is(tok::string_literal)) ||
+       (Current.TokenText.find("\\\n") != StringRef::npos)))
+    return true;
+
+  if (!Style.BreakBeforeBinaryOperators) {
+    // If we need to break somewhere inside the LHS of a binary expression, we
+    // should also break after the operator. Otherwise, the formatting would
+    // hide the operator precedence, e.g. in:
+    //   if (aaaaaaaaaaaaaa ==
+    //           bbbbbbbbbbbbbb && c) {..
+    // For comparisons, we only apply this rule, if the LHS is a binary
+    // expression itself as otherwise, the line breaks seem superfluous.
+    // We need special cases for ">>" which we have split into two ">" while
+    // lexing in order to make template parsing easier.
+    //
+    // FIXME: We'll need something similar for styles that break before binary
+    // operators.
+    bool IsComparison = (Previous.getPrecedence() == prec::Relational ||
+                         Previous.getPrecedence() == prec::Equality) &&
+                        Previous.Previous &&
+                        Previous.Previous->Type != TT_BinaryOperator; // For >>.
+    bool LHSIsBinaryExpr =
+        Previous.Previous && Previous.Previous->FakeRParens > 0;
+    if (Previous.Type == TT_BinaryOperator &&
+        (!IsComparison || LHSIsBinaryExpr) &&
+        Current.Type != TT_BinaryOperator && // For >>.
+        !Current.isTrailingComment() &&
+        !Previous.isOneOf(tok::lessless, tok::question) &&
+        Previous.getPrecedence() != prec::Assignment &&
+        State.Stack.back().BreakBeforeParameter)
+      return true;
+  }
+
+  // Same as above, but for the first "<<" operator.
+  if (Current.is(tok::lessless) && State.Stack.back().BreakBeforeParameter &&
+      State.Stack.back().FirstLessLess == 0)
+    return true;
+
+  // FIXME: Comparing LongestObjCSelectorName to 0 is a hacky way of finding
+  // out whether it is the first parameter. Clean this up.
+  if (Current.Type == TT_ObjCSelectorName &&
+      Current.LongestObjCSelectorName == 0 &&
+      State.Stack.back().BreakBeforeParameter)
+    return true;
+  if ((Current.Type == TT_CtorInitializerColon ||
+       (Previous.ClosesTemplateDeclaration && State.ParenLevel == 0)))
+    return true;
+
+  if ((Current.Type == TT_StartOfName || Current.is(tok::kw_operator)) &&
+      Line.MightBeFunctionDecl && State.Stack.back().BreakBeforeParameter &&
+      State.ParenLevel == 0)
+    return true;
+  return false;
+}
+
+unsigned ContinuationIndenter::addTokenToState(LineState &State, bool Newline,
+                                               bool DryRun) {
+  const FormatToken &Current = *State.NextToken;
+  const FormatToken &Previous = *State.NextToken->Previous;
+
+  // Extra penalty that needs to be added because of the way certain line
+  // breaks are chosen.
+  unsigned ExtraPenalty = 0;
+
+  if (State.Stack.size() == 0 || Current.Type == TT_ImplicitStringLiteral) {
+    // FIXME: Is this correct?
+    int WhitespaceLength = SourceMgr.getSpellingColumnNumber(
+                               State.NextToken->WhitespaceRange.getEnd()) -
+                           SourceMgr.getSpellingColumnNumber(
+                               State.NextToken->WhitespaceRange.getBegin());
+    State.Column += WhitespaceLength + State.NextToken->CodePointCount;
+    State.NextToken = State.NextToken->Next;
+    return 0;
+  }
+
+  // If we are continuing an expression, we want to indent an extra 4 spaces.
+  unsigned ContinuationIndent =
+      std::max(State.Stack.back().LastSpace, State.Stack.back().Indent) + 4;
+  if (Newline) {
+    // Breaking before the first "<<" is generally not desirable if the LHS is
+    // short.
+    if (Current.is(tok::lessless) && State.Stack.back().FirstLessLess == 0 &&
+        State.Column <= Style.ColumnLimit / 2)
+      ExtraPenalty += Style.PenaltyBreakFirstLessLess;
+
+    State.Stack.back().ContainsLineBreak = true;
+    if (Current.is(tok::r_brace)) {
+      if (Current.BlockKind == BK_BracedInit)
+        State.Column = State.Stack[State.Stack.size() - 2].LastSpace;
+      else
+        State.Column = FirstIndent;
+    } else if (Current.is(tok::string_literal) &&
+               State.StartOfStringLiteral != 0) {
+      State.Column = State.StartOfStringLiteral;
+      State.Stack.back().BreakBeforeParameter = true;
+    } else if (Current.is(tok::lessless) &&
+               State.Stack.back().FirstLessLess != 0) {
+      State.Column = State.Stack.back().FirstLessLess;
+    } else if (Current.isOneOf(tok::period, tok::arrow) &&
+               Current.Type != TT_DesignatedInitializerPeriod) {
+      if (State.Stack.back().CallContinuation == 0) {
+        State.Column = ContinuationIndent;
+        State.Stack.back().CallContinuation = State.Column;
+      } else {
+        State.Column = State.Stack.back().CallContinuation;
+      }
+    } else if (Current.Type == TT_ConditionalExpr) {
+      State.Column = State.Stack.back().QuestionColumn;
+    } else if (Previous.is(tok::comma) && State.Stack.back().VariablePos != 0) {
+      State.Column = State.Stack.back().VariablePos;
+    } else if (Previous.ClosesTemplateDeclaration ||
+               ((Current.Type == TT_StartOfName ||
+                 Current.is(tok::kw_operator)) &&
+                State.ParenLevel == 0 &&
+                (!Style.IndentFunctionDeclarationAfterType ||
+                 Line.StartsDefinition))) {
+      State.Column = State.Stack.back().Indent;
+    } else if (Current.Type == TT_ObjCSelectorName) {
+      if (State.Stack.back().ColonPos > Current.CodePointCount) {
+        State.Column = State.Stack.back().ColonPos - Current.CodePointCount;
+      } else {
+        State.Column = State.Stack.back().Indent;
+        State.Stack.back().ColonPos = State.Column + Current.CodePointCount;
+      }
+    } else if (Current.is(tok::l_square) && Current.Type != TT_ObjCMethodExpr) {
+      if (State.Stack.back().StartOfArraySubscripts != 0)
+        State.Column = State.Stack.back().StartOfArraySubscripts;
+      else
+        State.Column = ContinuationIndent;
+    } else if (Current.Type == TT_StartOfName ||
+               Previous.isOneOf(tok::coloncolon, tok::equal) ||
+               Previous.Type == TT_ObjCMethodExpr) {
+      State.Column = ContinuationIndent;
+    } else if (Current.Type == TT_CtorInitializerColon) {
+      State.Column = FirstIndent + Style.ConstructorInitializerIndentWidth;
+    } else if (Current.Type == TT_CtorInitializerComma) {
+      State.Column = State.Stack.back().Indent;
+    } else {
+      State.Column = State.Stack.back().Indent;
+      // Ensure that we fall back to indenting 4 spaces instead of just
+      // flushing continuations left.
+      if (State.Column == FirstIndent)
+        State.Column += 4;
+    }
+
+    if (Current.is(tok::question))
+      State.Stack.back().BreakBeforeParameter = true;
+    if ((Previous.isOneOf(tok::comma, tok::semi) &&
+         !State.Stack.back().AvoidBinPacking) ||
+        Previous.Type == TT_BinaryOperator)
+      State.Stack.back().BreakBeforeParameter = false;
+    if (Previous.Type == TT_TemplateCloser && State.ParenLevel == 0)
+      State.Stack.back().BreakBeforeParameter = false;
+
+    if (!DryRun) {
+      unsigned NewLines = 1;
+      if (Current.is(tok::comment))
+        NewLines = std::max(NewLines, std::min(Current.NewlinesBefore,
+                                               Style.MaxEmptyLinesToKeep + 1));
+      Whitespaces.replaceWhitespace(Current, NewLines, State.Column,
+                                    State.Column, Line.InPPDirective);
+    }
+
+    if (!Current.isTrailingComment())
+      State.Stack.back().LastSpace = State.Column;
+    if (Current.isOneOf(tok::arrow, tok::period) &&
+        Current.Type != TT_DesignatedInitializerPeriod)
+      State.Stack.back().LastSpace += Current.CodePointCount;
+    State.StartOfLineLevel = State.ParenLevel;
+    State.LowestLevelOnLine = State.ParenLevel;
+
+    // Any break on this level means that the parent level has been broken
+    // and we need to avoid bin packing there.
+    for (unsigned i = 0, e = State.Stack.size() - 1; i != e; ++i) {
+      State.Stack[i].BreakBeforeParameter = true;
+    }
+    const FormatToken *TokenBefore = Current.getPreviousNonComment();
+    if (TokenBefore && !TokenBefore->isOneOf(tok::comma, tok::semi) &&
+        TokenBefore->Type != TT_TemplateCloser &&
+        TokenBefore->Type != TT_BinaryOperator && !TokenBefore->opensScope())
+      State.Stack.back().BreakBeforeParameter = true;
+
+    // If we break after {, we should also break before the corresponding }.
+    if (Previous.is(tok::l_brace))
+      State.Stack.back().BreakBeforeClosingBrace = true;
+
+    if (State.Stack.back().AvoidBinPacking) {
+      // If we are breaking after '(', '{', '<', this is not bin packing
+      // unless AllowAllParametersOfDeclarationOnNextLine is false.
+      if (!(Previous.isOneOf(tok::l_paren, tok::l_brace) ||
+            Previous.Type == TT_BinaryOperator) ||
+          (!Style.AllowAllParametersOfDeclarationOnNextLine &&
+           Line.MustBeDeclaration))
+        State.Stack.back().BreakBeforeParameter = true;
+    }
+
+  } else {
+    if (Current.is(tok::equal) &&
+        (Line.First->is(tok::kw_for) || State.ParenLevel == 0) &&
+        State.Stack.back().VariablePos == 0) {
+      State.Stack.back().VariablePos = State.Column;
+      // Move over * and & if they are bound to the variable name.
+      const FormatToken *Tok = &Previous;
+      while (Tok && State.Stack.back().VariablePos >= Tok->CodePointCount) {
+        State.Stack.back().VariablePos -= Tok->CodePointCount;
+        if (Tok->SpacesRequiredBefore != 0)
+          break;
+        Tok = Tok->Previous;
+      }
+      if (Previous.PartOfMultiVariableDeclStmt)
+        State.Stack.back().LastSpace = State.Stack.back().VariablePos;
+    }
+
+    unsigned Spaces = State.NextToken->SpacesRequiredBefore;
+
+    if (!DryRun)
+      Whitespaces.replaceWhitespace(Current, 0, Spaces, State.Column + Spaces);
+
+    if (Current.Type == TT_ObjCSelectorName &&
+        State.Stack.back().ColonPos == 0) {
+      if (State.Stack.back().Indent + Current.LongestObjCSelectorName >
+          State.Column + Spaces + Current.CodePointCount)
+        State.Stack.back().ColonPos =
+            State.Stack.back().Indent + Current.LongestObjCSelectorName;
+      else
+        State.Stack.back().ColonPos =
+            State.Column + Spaces + Current.CodePointCount;
+    }
+
+    if (Previous.opensScope() && Previous.Type != TT_ObjCMethodExpr &&
+        Current.Type != TT_LineComment)
+      State.Stack.back().Indent = State.Column + Spaces;
+    if (Previous.is(tok::comma) && !Current.isTrailingComment() &&
+        State.Stack.back().AvoidBinPacking)
+      State.Stack.back().NoLineBreak = true;
+
+    State.Column += Spaces;
+    if (Current.is(tok::l_paren) && Previous.isOneOf(tok::kw_if, tok::kw_for))
+      // Treat the condition inside an if as if it was a second function
+      // parameter, i.e. let nested calls have an indent of 4.
+      State.Stack.back().LastSpace = State.Column + 1; // 1 is length of "(".
+    else if (Previous.is(tok::comma))
+      State.Stack.back().LastSpace = State.Column;
+    else if ((Previous.Type == TT_BinaryOperator ||
+              Previous.Type == TT_ConditionalExpr ||
+              Previous.Type == TT_CtorInitializerColon) &&
+             !(Previous.getPrecedence() == prec::Assignment &&
+               Current.FakeLParens.empty()))
+      // Always indent relative to the RHS of the expression unless this is a
+      // simple assignment without binary expression on the RHS.
+      State.Stack.back().LastSpace = State.Column;
+    else if (Previous.Type == TT_InheritanceColon)
+      State.Stack.back().Indent = State.Column;
+    else if (Previous.opensScope()) {
+      // If a function has multiple parameters (including a single parameter
+      // that is a binary expression) or a trailing call, indent all
+      // parameters from the opening parenthesis. This avoids confusing
+      // indents like:
+      //   OuterFunction(InnerFunctionCall(
+      //       ParameterToInnerFunction),
+      //                 SecondParameterToOuterFunction);
+      bool HasMultipleParameters = !Current.FakeLParens.empty();
+      bool HasTrailingCall = false;
+      if (Previous.MatchingParen) {
+        const FormatToken *Next = Previous.MatchingParen->getNextNonComment();
+        if (Next && Next->isOneOf(tok::period, tok::arrow))
+          HasTrailingCall = true;
+      }
+      if (HasMultipleParameters || HasTrailingCall)
+        State.Stack.back().LastSpace = State.Column;
+    }
+  }
+
+  return moveStateToNextToken(State, DryRun, Newline) + ExtraPenalty;
+}
+
+unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
+                                                    bool DryRun, bool Newline) {
+  const FormatToken &Current = *State.NextToken;
+  assert(State.Stack.size());
+
+  if (Current.Type == TT_InheritanceColon)
+    State.Stack.back().AvoidBinPacking = true;
+  if (Current.is(tok::lessless) && State.Stack.back().FirstLessLess == 0)
+    State.Stack.back().FirstLessLess = State.Column;
+  if (Current.is(tok::l_square) &&
+      State.Stack.back().StartOfArraySubscripts == 0)
+    State.Stack.back().StartOfArraySubscripts = State.Column;
+  if (Current.is(tok::question))
+    State.Stack.back().QuestionColumn = State.Column;
+  if (!Current.opensScope() && !Current.closesScope())
+    State.LowestLevelOnLine =
+        std::min(State.LowestLevelOnLine, State.ParenLevel);
+  if (Current.isOneOf(tok::period, tok::arrow) &&
+      Line.Type == LT_BuilderTypeCall && State.ParenLevel == 0)
+    State.Stack.back().StartOfFunctionCall =
+        Current.LastInChainOfCalls ? 0 : State.Column + Current.CodePointCount;
+  if (Current.Type == TT_CtorInitializerColon) {
+    // Indent 2 from the column, so:
+    // SomeClass::SomeClass()
+    //     : First(...), ...
+    //       Next(...)
+    //       ^ line up here.
+    State.Stack.back().Indent =
+        State.Column + (Style.BreakConstructorInitializersBeforeComma ? 0 : 2);
+    if (Style.ConstructorInitializerAllOnOneLineOrOnePerLine)
+      State.Stack.back().AvoidBinPacking = true;
+    State.Stack.back().BreakBeforeParameter = false;
+  }
+
+  // If return returns a binary expression, align after it.
+  if (Current.is(tok::kw_return) && !Current.FakeLParens.empty())
+    State.Stack.back().LastSpace = State.Column + 7;
+
+  // In ObjC method declaration we align on the ":" of parameters, but we need
+  // to ensure that we indent parameters on subsequent lines by at least 4.
+  if (Current.Type == TT_ObjCMethodSpecifier)
+    State.Stack.back().Indent += 4;
+
+  // Insert scopes created by fake parenthesis.
+  const FormatToken *Previous = Current.getPreviousNonComment();
+  // Don't add extra indentation for the first fake parenthesis after
+  // 'return', assignements or opening <({[. The indentation for these cases
+  // is special cased.
+  bool SkipFirstExtraIndent =
+      Current.is(tok::kw_return) ||
+      (Previous && (Previous->opensScope() ||
+                    Previous->getPrecedence() == prec::Assignment));
+  for (SmallVectorImpl<prec::Level>::const_reverse_iterator
+           I = Current.FakeLParens.rbegin(),
+           E = Current.FakeLParens.rend();
+       I != E; ++I) {
+    ParenState NewParenState = State.Stack.back();
+    NewParenState.ContainsLineBreak = false;
+    NewParenState.Indent =
+        std::max(std::max(State.Column, NewParenState.Indent),
+                 State.Stack.back().LastSpace);
+
+    // Always indent conditional expressions. Never indent expression where
+    // the 'operator' is ',', ';' or an assignment (i.e. *I <=
+    // prec::Assignment) as those have different indentation rules. Indent
+    // other expression, unless the indentation needs to be skipped.
+    if (*I == prec::Conditional ||
+        (!SkipFirstExtraIndent && *I > prec::Assignment &&
+         !Style.BreakBeforeBinaryOperators))
+      NewParenState.Indent += 4;
+    if (Previous && !Previous->opensScope())
+      NewParenState.BreakBeforeParameter = false;
+    State.Stack.push_back(NewParenState);
+    SkipFirstExtraIndent = false;
+  }
+
+  // If we encounter an opening (, [, { or <, we add a level to our stacks to
+  // prepare for the following tokens.
+  if (Current.opensScope()) {
+    unsigned NewIndent;
+    unsigned LastSpace = State.Stack.back().LastSpace;
+    bool AvoidBinPacking;
+    if (Current.is(tok::l_brace)) {
+      NewIndent =
+          LastSpace + (Style.Cpp11BracedListStyle ? 4 : Style.IndentWidth);
+      const FormatToken *NextNoComment = Current.getNextNonComment();
+      AvoidBinPacking = NextNoComment &&
+                        NextNoComment->Type == TT_DesignatedInitializerPeriod;
+    } else {
+      NewIndent =
+          4 + std::max(LastSpace, State.Stack.back().StartOfFunctionCall);
+      AvoidBinPacking = !Style.BinPackParameters ||
+                        (Style.ExperimentalAutoDetectBinPacking &&
+                         (Current.PackingKind == PPK_OnePerLine ||
+                          (!BinPackInconclusiveFunctions &&
+                           Current.PackingKind == PPK_Inconclusive)));
+    }
+
+    State.Stack.push_back(ParenState(NewIndent, LastSpace, AvoidBinPacking,
+                                     State.Stack.back().NoLineBreak));
+    ++State.ParenLevel;
+  }
+
+  // If this '[' opens an ObjC call, determine whether all parameters fit into
+  // one line and put one per line if they don't.
+  if (Current.is(tok::l_square) && Current.Type == TT_ObjCMethodExpr &&
+      Current.MatchingParen != NULL) {
+    if (getLengthToMatchingParen(Current) + State.Column > getColumnLimit())
+      State.Stack.back().BreakBeforeParameter = true;
+  }
+
+  // If we encounter a closing ), ], } or >, we can remove a level from our
+  // stacks.
+  if (Current.isOneOf(tok::r_paren, tok::r_square) ||
+      (Current.is(tok::r_brace) && State.NextToken != Line.First) ||
+      State.NextToken->Type == TT_TemplateCloser) {
+    State.Stack.pop_back();
+    --State.ParenLevel;
+  }
+  if (Current.is(tok::r_square)) {
+    // If this ends the array subscript expr, reset the corresponding value.
+    const FormatToken *NextNonComment = Current.getNextNonComment();
+    if (NextNonComment && NextNonComment->isNot(tok::l_square))
+      State.Stack.back().StartOfArraySubscripts = 0;
+  }
+
+  // Remove scopes created by fake parenthesis.
+  for (unsigned i = 0, e = Current.FakeRParens; i != e; ++i) {
+    unsigned VariablePos = State.Stack.back().VariablePos;
+    State.Stack.pop_back();
+    State.Stack.back().VariablePos = VariablePos;
+  }
+
+  if (Current.is(tok::string_literal) && State.StartOfStringLiteral == 0) {
+    State.StartOfStringLiteral = State.Column;
+  } else if (!Current.isOneOf(tok::comment, tok::identifier, tok::hash,
+                              tok::string_literal)) {
+    State.StartOfStringLiteral = 0;
+  }
+
+  State.Column += Current.CodePointCount;
+
+  State.NextToken = State.NextToken->Next;
+
+  if (!Newline && Style.AlwaysBreakBeforeMultilineStrings &&
+      Current.is(tok::string_literal) && Current.CanBreakBefore)
+    return 0;
+
+  return breakProtrudingToken(Current, State, DryRun);
+}
+
+unsigned ContinuationIndenter::breakProtrudingToken(const FormatToken &Current,
+                                                    LineState &State,
+                                                    bool DryRun) {
+  llvm::OwningPtr<BreakableToken> Token;
+  unsigned StartColumn = State.Column - Current.CodePointCount;
+  unsigned OriginalStartColumn =
+      SourceMgr.getSpellingColumnNumber(Current.getStartOfNonWhitespace()) - 1;
+
+  if (Current.is(tok::string_literal) &&
+      Current.Type != TT_ImplicitStringLiteral) {
+    // Only break up default narrow strings.
+    if (!Current.TokenText.startswith("\""))
+      return 0;
+    // Don't break string literals with escaped newlines. As clang-format must
+    // not change the string's content, it is unlikely that we'll end up with
+    // a better format.
+    if (Current.TokenText.find("\\\n") != StringRef::npos)
+      return 0;
+    // Exempts unterminated string literals from line breaking. The user will
+    // likely want to terminate the string before any line breaking is done.
+    if (Current.IsUnterminatedLiteral)
+      return 0;
+
+    Token.reset(new BreakableStringLiteral(Current, StartColumn,
+                                           Line.InPPDirective, Encoding));
+  } else if (Current.Type == TT_BlockComment && Current.isTrailingComment()) {
+    Token.reset(new BreakableBlockComment(
+        Style, Current, StartColumn, OriginalStartColumn, !Current.Previous,
+        Line.InPPDirective, Encoding));
+  } else if (Current.Type == TT_LineComment &&
+             (Current.Previous == NULL ||
+              Current.Previous->Type != TT_ImplicitStringLiteral)) {
+    // Don't break line comments with escaped newlines. These look like
+    // separate line comments, but in fact contain a single line comment with
+    // multiple lines including leading whitespace and the '//' markers.
+    //
+    // FIXME: If we want to handle them correctly, we'll need to adjust
+    // leading whitespace in consecutive lines when changing indentation of
+    // the first line similar to what we do with block comments.
+    StringRef::size_type EscapedNewlinePos = Current.TokenText.find("\\\n");
+    if (EscapedNewlinePos != StringRef::npos) {
+      State.Column =
+          StartColumn +
+          encoding::getCodePointCount(
+              Current.TokenText.substr(0, EscapedNewlinePos), Encoding) +
+          1;
+      return 0;
+    }
+
+    Token.reset(new BreakableLineComment(Current, StartColumn,
+                                         Line.InPPDirective, Encoding));
+  } else {
+    return 0;
+  }
+  if (Current.UnbreakableTailLength >= getColumnLimit())
+    return 0;
+
+  unsigned RemainingSpace = getColumnLimit() - Current.UnbreakableTailLength;
+  bool BreakInserted = false;
+  unsigned Penalty = 0;
+  unsigned RemainingTokenColumns = 0;
+  for (unsigned LineIndex = 0, EndIndex = Token->getLineCount();
+       LineIndex != EndIndex; ++LineIndex) {
+    if (!DryRun)
+      Token->replaceWhitespaceBefore(LineIndex, Whitespaces);
+    unsigned TailOffset = 0;
+    RemainingTokenColumns =
+        Token->getLineLengthAfterSplit(LineIndex, TailOffset, StringRef::npos);
+    while (RemainingTokenColumns > RemainingSpace) {
+      BreakableToken::Split Split =
+          Token->getSplit(LineIndex, TailOffset, getColumnLimit());
+      if (Split.first == StringRef::npos) {
+        // The last line's penalty is handled in addNextStateToQueue().
+        if (LineIndex < EndIndex - 1)
+          Penalty += Style.PenaltyExcessCharacter *
+                     (RemainingTokenColumns - RemainingSpace);
+        break;
+      }
+      assert(Split.first != 0);
+      unsigned NewRemainingTokenColumns = Token->getLineLengthAfterSplit(
+          LineIndex, TailOffset + Split.first + Split.second, StringRef::npos);
+      assert(NewRemainingTokenColumns < RemainingTokenColumns);
+      if (!DryRun)
+        Token->insertBreak(LineIndex, TailOffset, Split, Whitespaces);
+      Penalty += Current.is(tok::string_literal) ? Style.PenaltyBreakString
+                                                 : Style.PenaltyBreakComment;
+      unsigned ColumnsUsed =
+          Token->getLineLengthAfterSplit(LineIndex, TailOffset, Split.first);
+      if (ColumnsUsed > getColumnLimit()) {
+        Penalty +=
+            Style.PenaltyExcessCharacter * (ColumnsUsed - getColumnLimit());
+      }
+      TailOffset += Split.first + Split.second;
+      RemainingTokenColumns = NewRemainingTokenColumns;
+      BreakInserted = true;
+    }
+  }
+
+  State.Column = RemainingTokenColumns;
+
+  if (BreakInserted) {
+    // If we break the token inside a parameter list, we need to break before
+    // the next parameter on all levels, so that the next parameter is clearly
+    // visible. Line comments already introduce a break.
+    if (Current.Type != TT_LineComment) {
+      for (unsigned i = 0, e = State.Stack.size(); i != e; ++i)
+        State.Stack[i].BreakBeforeParameter = true;
+    }
+
+    State.Stack.back().LastSpace = StartColumn;
+  }
+  return Penalty;
+}
+
+unsigned ContinuationIndenter::getColumnLimit() const {
+  // In preprocessor directives reserve two chars for trailing " \"
+  return Style.ColumnLimit - (Line.InPPDirective ? 2 : 0);
+}
+
+} // namespace format
+} // namespace clang
diff --git a/lib/Format/ContinuationIndenter.h b/lib/Format/ContinuationIndenter.h
new file mode 100644
index 0000000..14e0da0
--- /dev/null
+++ b/lib/Format/ContinuationIndenter.h
@@ -0,0 +1,277 @@
+//===--- ContinuationIndenter.h - Format C++ code ---------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief This file implements an indenter that manages the indentation of
+/// continuations.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FORMAT_CONTINUATION_INDENTER_H
+#define LLVM_CLANG_FORMAT_CONTINUATION_INDENTER_H
+
+#include "Encoding.h"
+#include "clang/Format/Format.h"
+
+namespace clang {
+class SourceManager;
+
+namespace format {
+
+class AnnotatedLine;
+struct FormatToken;
+struct LineState;
+struct ParenState;
+class WhitespaceManager;
+
+class ContinuationIndenter {
+public:
+  /// \brief Constructs a \c ContinuationIndenter to format \p Line starting in
+  /// column \p FirstIndent.
+  ContinuationIndenter(const FormatStyle &Style, SourceManager &SourceMgr,
+                       const AnnotatedLine &Line, unsigned FirstIndent,
+                       WhitespaceManager &Whitespaces,
+                       encoding::Encoding Encoding,
+                       bool BinPackInconclusiveFunctions);
+
+  /// \brief Get the initial state, i.e. the state after placing the line's
+  /// first token.
+  LineState getInitialState();
+
+  // FIXME: canBreak and mustBreak aren't strictly indentation-related. Find a
+  // better home.
+  /// \brief Returns \c true, if a line break after \p State is allowed.
+  bool canBreak(const LineState &State);
+
+  /// \brief Returns \c true, if a line break after \p State is mandatory.
+  bool mustBreak(const LineState &State);
+
+  /// \brief Appends the next token to \p State and updates information
+  /// necessary for indentation.
+  ///
+  /// Puts the token on the current line if \p Newline is \c false and adds a
+  /// line break and necessary indentation otherwise.
+  ///
+  /// If \p DryRun is \c false, also creates and stores the required
+  /// \c Replacement.
+  unsigned addTokenToState(LineState &State, bool Newline, bool DryRun);
+
+  /// \brief Get the column limit for this line. This is the style's column
+  /// limit, potentially reduced for preprocessor definitions.
+  unsigned getColumnLimit() const;
+
+private:
+  /// \brief Mark the next token as consumed in \p State and modify its stacks
+  /// accordingly.
+  unsigned moveStateToNextToken(LineState &State, bool DryRun, bool Newline);
+
+  /// \brief If the current token sticks out over the end of the line, break
+  /// it if possible.
+  ///
+  /// \returns An extra penalty if a token was broken, otherwise 0.
+  ///
+  /// The returned penalty will cover the cost of the additional line breaks and
+  /// column limit violation in all lines except for the last one. The penalty
+  /// for the column limit violation in the last line (and in single line
+  /// tokens) is handled in \c addNextStateToQueue.
+  unsigned breakProtrudingToken(const FormatToken &Current, LineState &State,
+                                bool DryRun);
+
+  FormatStyle Style;
+  SourceManager &SourceMgr;
+  const AnnotatedLine &Line;
+  const unsigned FirstIndent;
+  WhitespaceManager &Whitespaces;
+  encoding::Encoding Encoding;
+  bool BinPackInconclusiveFunctions;
+};
+
+struct ParenState {
+  ParenState(unsigned Indent, unsigned LastSpace, bool AvoidBinPacking,
+             bool NoLineBreak)
+      : Indent(Indent), LastSpace(LastSpace), FirstLessLess(0),
+        BreakBeforeClosingBrace(false), QuestionColumn(0),
+        AvoidBinPacking(AvoidBinPacking), BreakBeforeParameter(false),
+        NoLineBreak(NoLineBreak), ColonPos(0), StartOfFunctionCall(0),
+        StartOfArraySubscripts(0), NestedNameSpecifierContinuation(0),
+        CallContinuation(0), VariablePos(0), ContainsLineBreak(false) {}
+
+  /// \brief The position to which a specific parenthesis level needs to be
+  /// indented.
+  unsigned Indent;
+
+  /// \brief The position of the last space on each level.
+  ///
+  /// Used e.g. to break like:
+  /// functionCall(Parameter, otherCall(
+  ///                             OtherParameter));
+  unsigned LastSpace;
+
+  /// \brief The position the first "<<" operator encountered on each level.
+  ///
+  /// Used to align "<<" operators. 0 if no such operator has been encountered
+  /// on a level.
+  unsigned FirstLessLess;
+
+  /// \brief Whether a newline needs to be inserted before the block's closing
+  /// brace.
+  ///
+  /// We only want to insert a newline before the closing brace if there also
+  /// was a newline after the beginning left brace.
+  bool BreakBeforeClosingBrace;
+
+  /// \brief The column of a \c ? in a conditional expression;
+  unsigned QuestionColumn;
+
+  /// \brief Avoid bin packing, i.e. multiple parameters/elements on multiple
+  /// lines, in this context.
+  bool AvoidBinPacking;
+
+  /// \brief Break after the next comma (or all the commas in this context if
+  /// \c AvoidBinPacking is \c true).
+  bool BreakBeforeParameter;
+
+  /// \brief Line breaking in this context would break a formatting rule.
+  bool NoLineBreak;
+
+  /// \brief The position of the colon in an ObjC method declaration/call.
+  unsigned ColonPos;
+
+  /// \brief The start of the most recent function in a builder-type call.
+  unsigned StartOfFunctionCall;
+
+  /// \brief Contains the start of array subscript expressions, so that they
+  /// can be aligned.
+  unsigned StartOfArraySubscripts;
+
+  /// \brief If a nested name specifier was broken over multiple lines, this
+  /// contains the start column of the second line. Otherwise 0.
+  unsigned NestedNameSpecifierContinuation;
+
+  /// \brief If a call expression was broken over multiple lines, this
+  /// contains the start column of the second line. Otherwise 0.
+  unsigned CallContinuation;
+
+  /// \brief The column of the first variable name in a variable declaration.
+  ///
+  /// Used to align further variables if necessary.
+  unsigned VariablePos;
+
+  /// \brief \c true if this \c ParenState already contains a line-break.
+  ///
+  /// The first line break in a certain \c ParenState causes extra penalty so
+  /// that clang-format prefers similar breaks, i.e. breaks in the same
+  /// parenthesis.
+  bool ContainsLineBreak;
+
+  bool operator<(const ParenState &Other) const {
+    if (Indent != Other.Indent)
+      return Indent < Other.Indent;
+    if (LastSpace != Other.LastSpace)
+      return LastSpace < Other.LastSpace;
+    if (FirstLessLess != Other.FirstLessLess)
+      return FirstLessLess < Other.FirstLessLess;
+    if (BreakBeforeClosingBrace != Other.BreakBeforeClosingBrace)
+      return BreakBeforeClosingBrace;
+    if (QuestionColumn != Other.QuestionColumn)
+      return QuestionColumn < Other.QuestionColumn;
+    if (AvoidBinPacking != Other.AvoidBinPacking)
+      return AvoidBinPacking;
+    if (BreakBeforeParameter != Other.BreakBeforeParameter)
+      return BreakBeforeParameter;
+    if (NoLineBreak != Other.NoLineBreak)
+      return NoLineBreak;
+    if (ColonPos != Other.ColonPos)
+      return ColonPos < Other.ColonPos;
+    if (StartOfFunctionCall != Other.StartOfFunctionCall)
+      return StartOfFunctionCall < Other.StartOfFunctionCall;
+    if (StartOfArraySubscripts != Other.StartOfArraySubscripts)
+      return StartOfArraySubscripts < Other.StartOfArraySubscripts;
+    if (CallContinuation != Other.CallContinuation)
+      return CallContinuation < Other.CallContinuation;
+    if (VariablePos != Other.VariablePos)
+      return VariablePos < Other.VariablePos;
+    if (ContainsLineBreak != Other.ContainsLineBreak)
+      return ContainsLineBreak < Other.ContainsLineBreak;
+    return false;
+  }
+};
+
+/// \brief The current state when indenting a unwrapped line.
+///
+/// As the indenting tries different combinations this is copied by value.
+struct LineState {
+  /// \brief The number of used columns in the current line.
+  unsigned Column;
+
+  /// \brief The token that needs to be next formatted.
+  const FormatToken *NextToken;
+
+  /// \brief \c true if this line contains a continued for-loop section.
+  bool LineContainsContinuedForLoopSection;
+
+  /// \brief The level of nesting inside (), [], <> and {}.
+  unsigned ParenLevel;
+
+  /// \brief The \c ParenLevel at the start of this line.
+  unsigned StartOfLineLevel;
+
+  /// \brief The lowest \c ParenLevel on the current line.
+  unsigned LowestLevelOnLine;
+
+  /// \brief The start column of the string literal, if we're in a string
+  /// literal sequence, 0 otherwise.
+  unsigned StartOfStringLiteral;
+
+  /// \brief A stack keeping track of properties applying to parenthesis
+  /// levels.
+  std::vector<ParenState> Stack;
+
+  /// \brief Ignore the stack of \c ParenStates for state comparison.
+  ///
+  /// In long and deeply nested unwrapped lines, the current algorithm can
+  /// be insufficient for finding the best formatting with a reasonable amount
+  /// of time and memory. Setting this flag will effectively lead to the
+  /// algorithm not analyzing some combinations. However, these combinations
+  /// rarely contain the optimal solution: In short, accepting a higher
+  /// penalty early would need to lead to different values in the \c
+  /// ParenState stack (in an otherwise identical state) and these different
+  /// values would need to lead to a significant amount of avoided penalty
+  /// later.
+  ///
+  /// FIXME: Come up with a better algorithm instead.
+  bool IgnoreStackForComparison;
+
+  /// \brief Comparison operator to be able to used \c LineState in \c map.
+  bool operator<(const LineState &Other) const {
+    if (NextToken != Other.NextToken)
+      return NextToken < Other.NextToken;
+    if (Column != Other.Column)
+      return Column < Other.Column;
+    if (LineContainsContinuedForLoopSection !=
+        Other.LineContainsContinuedForLoopSection)
+      return LineContainsContinuedForLoopSection;
+    if (ParenLevel != Other.ParenLevel)
+      return ParenLevel < Other.ParenLevel;
+    if (StartOfLineLevel != Other.StartOfLineLevel)
+      return StartOfLineLevel < Other.StartOfLineLevel;
+    if (LowestLevelOnLine != Other.LowestLevelOnLine)
+      return LowestLevelOnLine < Other.LowestLevelOnLine;
+    if (StartOfStringLiteral != Other.StartOfStringLiteral)
+      return StartOfStringLiteral < Other.StartOfStringLiteral;
+    if (IgnoreStackForComparison || Other.IgnoreStackForComparison)
+      return false;
+    return Stack < Other.Stack;
+  }
+};
+
+} // end namespace format
+} // end namespace clang
+
+#endif // LLVM_CLANG_FORMAT_CONTINUATION_INDENTER_H
diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp
index ec1497c..20a2af5 100644
--- a/lib/Format/Format.cpp
+++ b/lib/Format/Format.cpp
@@ -15,12 +15,11 @@
 
 #define DEBUG_TYPE "format-formatter"
 
-#include "BreakableToken.h"
+#include "ContinuationIndenter.h"
 #include "TokenAnnotator.h"
 #include "UnwrappedLineParser.h"
 #include "WhitespaceManager.h"
 #include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/OperatorPrecedence.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Format/Format.h"
 #include "clang/Lex/Lexer.h"
@@ -300,67 +299,37 @@
   return Stream.str();
 }
 
-// Returns the length of everything up to the first possible line break after
-// the ), ], } or > matching \c Tok.
-static unsigned getLengthToMatchingParen(const FormatToken &Tok) {
-  if (Tok.MatchingParen == NULL)
-    return 0;
-  FormatToken *End = Tok.MatchingParen;
-  while (End->Next && !End->Next->CanBreakBefore) {
-    End = End->Next;
-  }
-  return End->TotalLength - Tok.TotalLength + 1;
-}
-
 namespace {
 
+class NoColumnLimitFormatter {
+public:
+  NoColumnLimitFormatter(ContinuationIndenter *Indenter)
+      : Indenter(Indenter) {}
+
+  /// \brief Formats the line starting at \p State, simply keeping all of the
+  /// input's line breaking decisions.
+  void format() {
+    LineState State = Indenter->getInitialState();
+    while (State.NextToken != NULL) {
+      bool Newline =
+          Indenter->mustBreak(State) ||
+          (Indenter->canBreak(State) && State.NextToken->NewlinesBefore > 0);
+      Indenter->addTokenToState(State, Newline, /*DryRun=*/false);
+    }
+  }
+private:
+  ContinuationIndenter *Indenter;
+};
+
 class UnwrappedLineFormatter {
 public:
-  UnwrappedLineFormatter(const FormatStyle &Style, SourceManager &SourceMgr,
-                         const AnnotatedLine &Line, unsigned FirstIndent,
-                         const FormatToken *RootToken,
-                         WhitespaceManager &Whitespaces,
-                         encoding::Encoding Encoding,
-                         bool BinPackInconclusiveFunctions)
-      : Style(Style), SourceMgr(SourceMgr), Line(Line),
-        FirstIndent(FirstIndent), RootToken(RootToken),
-        Whitespaces(Whitespaces), Count(0), Encoding(Encoding),
-        BinPackInconclusiveFunctions(BinPackInconclusiveFunctions) {}
+  UnwrappedLineFormatter(ContinuationIndenter *Indenter,
+                         const FormatStyle &Style, const AnnotatedLine &Line)
+      : Indenter(Indenter), Style(Style), Line(Line), Count(0) {}
 
   /// \brief Formats an \c UnwrappedLine.
-  void format(const AnnotatedLine *NextLine) {
-    // Initialize state dependent on indent.
-    LineState State;
-    State.Column = FirstIndent;
-    State.NextToken = RootToken;
-    State.Stack.push_back(ParenState(FirstIndent, FirstIndent,
-                                     /*AvoidBinPacking=*/false,
-                                     /*NoLineBreak=*/false));
-    State.LineContainsContinuedForLoopSection = false;
-    State.ParenLevel = 0;
-    State.StartOfStringLiteral = 0;
-    State.StartOfLineLevel = State.ParenLevel;
-    State.LowestLevelOnLine = State.ParenLevel;
-    State.IgnoreStackForComparison = false;
-
-    // The first token has already been indented and thus consumed.
-    moveStateToNextToken(State, /*DryRun=*/false, /*Newline=*/false);
-
-    if (Style.ColumnLimit == 0) {
-      formatWithoutColumnLimit(State);
-      return;
-    }
-
-    // If everything fits on a single line, just put it there.
-    unsigned ColumnLimit = Style.ColumnLimit;
-    if (NextLine && NextLine->InPPDirective &&
-        !NextLine->First->HasUnescapedNewline)
-      ColumnLimit = getColumnLimit();
-    if (Line.Last->TotalLength <= ColumnLimit - FirstIndent) {
-      while (State.NextToken != NULL) {
-        addTokenToState(false, false, State);
-      }
-    }
+  void format() {
+    LineState State = Indenter->getInitialState();
 
     // If the ObjC method declaration does not fit on a line, we should format
     // it with one arg per line.
@@ -372,717 +341,6 @@
   }
 
 private:
-  void DebugTokenState(const FormatToken &FormatTok) {
-    const Token &Tok = FormatTok.Tok;
-    llvm::dbgs() << StringRef(SourceMgr.getCharacterData(Tok.getLocation()),
-                              Tok.getLength());
-    llvm::dbgs();
-  }
-
-  struct ParenState {
-    ParenState(unsigned Indent, unsigned LastSpace, bool AvoidBinPacking,
-               bool NoLineBreak)
-        : Indent(Indent), LastSpace(LastSpace), FirstLessLess(0),
-          BreakBeforeClosingBrace(false), QuestionColumn(0),
-          AvoidBinPacking(AvoidBinPacking), BreakBeforeParameter(false),
-          NoLineBreak(NoLineBreak), ColonPos(0), StartOfFunctionCall(0),
-          StartOfArraySubscripts(0), NestedNameSpecifierContinuation(0),
-          CallContinuation(0), VariablePos(0), ContainsLineBreak(false) {}
-
-    /// \brief The position to which a specific parenthesis level needs to be
-    /// indented.
-    unsigned Indent;
-
-    /// \brief The position of the last space on each level.
-    ///
-    /// Used e.g. to break like:
-    /// functionCall(Parameter, otherCall(
-    ///                             OtherParameter));
-    unsigned LastSpace;
-
-    /// \brief The position the first "<<" operator encountered on each level.
-    ///
-    /// Used to align "<<" operators. 0 if no such operator has been encountered
-    /// on a level.
-    unsigned FirstLessLess;
-
-    /// \brief Whether a newline needs to be inserted before the block's closing
-    /// brace.
-    ///
-    /// We only want to insert a newline before the closing brace if there also
-    /// was a newline after the beginning left brace.
-    bool BreakBeforeClosingBrace;
-
-    /// \brief The column of a \c ? in a conditional expression;
-    unsigned QuestionColumn;
-
-    /// \brief Avoid bin packing, i.e. multiple parameters/elements on multiple
-    /// lines, in this context.
-    bool AvoidBinPacking;
-
-    /// \brief Break after the next comma (or all the commas in this context if
-    /// \c AvoidBinPacking is \c true).
-    bool BreakBeforeParameter;
-
-    /// \brief Line breaking in this context would break a formatting rule.
-    bool NoLineBreak;
-
-    /// \brief The position of the colon in an ObjC method declaration/call.
-    unsigned ColonPos;
-
-    /// \brief The start of the most recent function in a builder-type call.
-    unsigned StartOfFunctionCall;
-
-    /// \brief Contains the start of array subscript expressions, so that they
-    /// can be aligned.
-    unsigned StartOfArraySubscripts;
-
-    /// \brief If a nested name specifier was broken over multiple lines, this
-    /// contains the start column of the second line. Otherwise 0.
-    unsigned NestedNameSpecifierContinuation;
-
-    /// \brief If a call expression was broken over multiple lines, this
-    /// contains the start column of the second line. Otherwise 0.
-    unsigned CallContinuation;
-
-    /// \brief The column of the first variable name in a variable declaration.
-    ///
-    /// Used to align further variables if necessary.
-    unsigned VariablePos;
-
-    /// \brief \c true if this \c ParenState already contains a line-break.
-    ///
-    /// The first line break in a certain \c ParenState causes extra penalty so
-    /// that clang-format prefers similar breaks, i.e. breaks in the same
-    /// parenthesis.
-    bool ContainsLineBreak;
-
-    bool operator<(const ParenState &Other) const {
-      if (Indent != Other.Indent)
-        return Indent < Other.Indent;
-      if (LastSpace != Other.LastSpace)
-        return LastSpace < Other.LastSpace;
-      if (FirstLessLess != Other.FirstLessLess)
-        return FirstLessLess < Other.FirstLessLess;
-      if (BreakBeforeClosingBrace != Other.BreakBeforeClosingBrace)
-        return BreakBeforeClosingBrace;
-      if (QuestionColumn != Other.QuestionColumn)
-        return QuestionColumn < Other.QuestionColumn;
-      if (AvoidBinPacking != Other.AvoidBinPacking)
-        return AvoidBinPacking;
-      if (BreakBeforeParameter != Other.BreakBeforeParameter)
-        return BreakBeforeParameter;
-      if (NoLineBreak != Other.NoLineBreak)
-        return NoLineBreak;
-      if (ColonPos != Other.ColonPos)
-        return ColonPos < Other.ColonPos;
-      if (StartOfFunctionCall != Other.StartOfFunctionCall)
-        return StartOfFunctionCall < Other.StartOfFunctionCall;
-      if (StartOfArraySubscripts != Other.StartOfArraySubscripts)
-        return StartOfArraySubscripts < Other.StartOfArraySubscripts;
-      if (CallContinuation != Other.CallContinuation)
-        return CallContinuation < Other.CallContinuation;
-      if (VariablePos != Other.VariablePos)
-        return VariablePos < Other.VariablePos;
-      if (ContainsLineBreak != Other.ContainsLineBreak)
-        return ContainsLineBreak < Other.ContainsLineBreak;
-      return false;
-    }
-  };
-
-  /// \brief The current state when indenting a unwrapped line.
-  ///
-  /// As the indenting tries different combinations this is copied by value.
-  struct LineState {
-    /// \brief The number of used columns in the current line.
-    unsigned Column;
-
-    /// \brief The token that needs to be next formatted.
-    const FormatToken *NextToken;
-
-    /// \brief \c true if this line contains a continued for-loop section.
-    bool LineContainsContinuedForLoopSection;
-
-    /// \brief The level of nesting inside (), [], <> and {}.
-    unsigned ParenLevel;
-
-    /// \brief The \c ParenLevel at the start of this line.
-    unsigned StartOfLineLevel;
-
-    /// \brief The lowest \c ParenLevel on the current line.
-    unsigned LowestLevelOnLine;
-
-    /// \brief The start column of the string literal, if we're in a string
-    /// literal sequence, 0 otherwise.
-    unsigned StartOfStringLiteral;
-
-    /// \brief A stack keeping track of properties applying to parenthesis
-    /// levels.
-    std::vector<ParenState> Stack;
-
-    /// \brief Ignore the stack of \c ParenStates for state comparison.
-    ///
-    /// In long and deeply nested unwrapped lines, the current algorithm can
-    /// be insufficient for finding the best formatting with a reasonable amount
-    /// of time and memory. Setting this flag will effectively lead to the
-    /// algorithm not analyzing some combinations. However, these combinations
-    /// rarely contain the optimal solution: In short, accepting a higher
-    /// penalty early would need to lead to different values in the \c
-    /// ParenState stack (in an otherwise identical state) and these different
-    /// values would need to lead to a significant amount of avoided penalty
-    /// later.
-    ///
-    /// FIXME: Come up with a better algorithm instead.
-    bool IgnoreStackForComparison;
-
-    /// \brief Comparison operator to be able to used \c LineState in \c map.
-    bool operator<(const LineState &Other) const {
-      if (NextToken != Other.NextToken)
-        return NextToken < Other.NextToken;
-      if (Column != Other.Column)
-        return Column < Other.Column;
-      if (LineContainsContinuedForLoopSection !=
-          Other.LineContainsContinuedForLoopSection)
-        return LineContainsContinuedForLoopSection;
-      if (ParenLevel != Other.ParenLevel)
-        return ParenLevel < Other.ParenLevel;
-      if (StartOfLineLevel != Other.StartOfLineLevel)
-        return StartOfLineLevel < Other.StartOfLineLevel;
-      if (LowestLevelOnLine != Other.LowestLevelOnLine)
-        return LowestLevelOnLine < Other.LowestLevelOnLine;
-      if (StartOfStringLiteral != Other.StartOfStringLiteral)
-        return StartOfStringLiteral < Other.StartOfStringLiteral;
-      if (IgnoreStackForComparison || Other.IgnoreStackForComparison)
-        return false;
-      return Stack < Other.Stack;
-    }
-  };
-
-  /// \brief Formats the line starting at \p State, simply keeping all of the
-  /// input's line breaking decisions.
-  void formatWithoutColumnLimit(LineState &State) {
-    while (State.NextToken != NULL) {
-      bool Newline = mustBreak(State) ||
-                     (canBreak(State) && State.NextToken->NewlinesBefore > 0);
-      addTokenToState(Newline, /*DryRun=*/false, State);
-    }
-  }
-
-  /// \brief Appends the next token to \p State and updates information
-  /// necessary for indentation.
-  ///
-  /// Puts the token on the current line if \p Newline is \c false and adds a
-  /// line break and necessary indentation otherwise.
-  ///
-  /// If \p DryRun is \c false, also creates and stores the required
-  /// \c Replacement.
-  unsigned addTokenToState(bool Newline, bool DryRun, LineState &State) {
-    const FormatToken &Current = *State.NextToken;
-    const FormatToken &Previous = *State.NextToken->Previous;
-
-    // Extra penalty that needs to be added because of the way certain line
-    // breaks are chosen.
-    unsigned ExtraPenalty = 0;
-
-    if (State.Stack.size() == 0 || Current.Type == TT_ImplicitStringLiteral) {
-      // FIXME: Is this correct?
-      int WhitespaceLength = SourceMgr.getSpellingColumnNumber(
-                                 State.NextToken->WhitespaceRange.getEnd()) -
-                             SourceMgr.getSpellingColumnNumber(
-                                 State.NextToken->WhitespaceRange.getBegin());
-      State.Column += WhitespaceLength + State.NextToken->CodePointCount;
-      State.NextToken = State.NextToken->Next;
-      return 0;
-    }
-
-    // If we are continuing an expression, we want to indent an extra 4 spaces.
-    unsigned ContinuationIndent =
-        std::max(State.Stack.back().LastSpace, State.Stack.back().Indent) + 4;
-    if (Newline) {
-      // Breaking before the first "<<" is generally not desirable if the LHS is
-      // short.
-      if (Current.is(tok::lessless) && State.Stack.back().FirstLessLess == 0 &&
-          State.Column <= Style.ColumnLimit / 2)
-        ExtraPenalty += Style.PenaltyBreakFirstLessLess;
-
-      State.Stack.back().ContainsLineBreak = true;
-      if (Current.is(tok::r_brace)) {
-        if (Current.BlockKind == BK_BracedInit)
-          State.Column = State.Stack[State.Stack.size() - 2].LastSpace;
-        else
-          State.Column = FirstIndent;
-      } else if (Current.is(tok::string_literal) &&
-                 State.StartOfStringLiteral != 0) {
-        State.Column = State.StartOfStringLiteral;
-        State.Stack.back().BreakBeforeParameter = true;
-      } else if (Current.is(tok::lessless) &&
-                 State.Stack.back().FirstLessLess != 0) {
-        State.Column = State.Stack.back().FirstLessLess;
-      } else if (Current.isOneOf(tok::period, tok::arrow) &&
-                 Current.Type != TT_DesignatedInitializerPeriod) {
-        if (State.Stack.back().CallContinuation == 0) {
-          State.Column = ContinuationIndent;
-          State.Stack.back().CallContinuation = State.Column;
-        } else {
-          State.Column = State.Stack.back().CallContinuation;
-        }
-      } else if (Current.Type == TT_ConditionalExpr) {
-        State.Column = State.Stack.back().QuestionColumn;
-      } else if (Previous.is(tok::comma) &&
-                 State.Stack.back().VariablePos != 0) {
-        State.Column = State.Stack.back().VariablePos;
-      } else if (Previous.ClosesTemplateDeclaration ||
-                 ((Current.Type == TT_StartOfName ||
-                   Current.is(tok::kw_operator)) &&
-                  State.ParenLevel == 0 &&
-                  (!Style.IndentFunctionDeclarationAfterType ||
-                   Line.StartsDefinition))) {
-        State.Column = State.Stack.back().Indent;
-      } else if (Current.Type == TT_ObjCSelectorName) {
-        if (State.Stack.back().ColonPos > Current.CodePointCount) {
-          State.Column = State.Stack.back().ColonPos - Current.CodePointCount;
-        } else {
-          State.Column = State.Stack.back().Indent;
-          State.Stack.back().ColonPos = State.Column + Current.CodePointCount;
-        }
-      } else if (Current.is(tok::l_square) &&
-                 Current.Type != TT_ObjCMethodExpr) {
-        if (State.Stack.back().StartOfArraySubscripts != 0)
-          State.Column = State.Stack.back().StartOfArraySubscripts;
-        else
-          State.Column = ContinuationIndent;
-      } else if (Current.Type == TT_StartOfName ||
-                 Previous.isOneOf(tok::coloncolon, tok::equal) ||
-                 Previous.Type == TT_ObjCMethodExpr) {
-        State.Column = ContinuationIndent;
-      } else if (Current.Type == TT_CtorInitializerColon) {
-        State.Column = FirstIndent + Style.ConstructorInitializerIndentWidth;
-      } else if (Current.Type == TT_CtorInitializerComma) {
-        State.Column = State.Stack.back().Indent;
-      } else {
-        State.Column = State.Stack.back().Indent;
-        // Ensure that we fall back to indenting 4 spaces instead of just
-        // flushing continuations left.
-        if (State.Column == FirstIndent)
-          State.Column += 4;
-      }
-
-      if (Current.is(tok::question))
-        State.Stack.back().BreakBeforeParameter = true;
-      if ((Previous.isOneOf(tok::comma, tok::semi) &&
-           !State.Stack.back().AvoidBinPacking) ||
-          Previous.Type == TT_BinaryOperator)
-        State.Stack.back().BreakBeforeParameter = false;
-      if (Previous.Type == TT_TemplateCloser && State.ParenLevel == 0)
-        State.Stack.back().BreakBeforeParameter = false;
-
-      if (!DryRun) {
-        unsigned NewLines = 1;
-        if (Current.is(tok::comment))
-          NewLines = std::max(
-              NewLines,
-              std::min(Current.NewlinesBefore, Style.MaxEmptyLinesToKeep + 1));
-        Whitespaces.replaceWhitespace(Current, NewLines, State.Column,
-                                      State.Column, Line.InPPDirective);
-      }
-
-      if (!Current.isTrailingComment())
-        State.Stack.back().LastSpace = State.Column;
-      if (Current.isOneOf(tok::arrow, tok::period) &&
-          Current.Type != TT_DesignatedInitializerPeriod)
-        State.Stack.back().LastSpace += Current.CodePointCount;
-      State.StartOfLineLevel = State.ParenLevel;
-      State.LowestLevelOnLine = State.ParenLevel;
-
-      // Any break on this level means that the parent level has been broken
-      // and we need to avoid bin packing there.
-      for (unsigned i = 0, e = State.Stack.size() - 1; i != e; ++i) {
-        State.Stack[i].BreakBeforeParameter = true;
-      }
-      const FormatToken *TokenBefore = Current.getPreviousNonComment();
-      if (TokenBefore && !TokenBefore->isOneOf(tok::comma, tok::semi) &&
-          TokenBefore->Type != TT_TemplateCloser &&
-          TokenBefore->Type != TT_BinaryOperator && !TokenBefore->opensScope())
-        State.Stack.back().BreakBeforeParameter = true;
-
-      // If we break after {, we should also break before the corresponding }.
-      if (Previous.is(tok::l_brace))
-        State.Stack.back().BreakBeforeClosingBrace = true;
-
-      if (State.Stack.back().AvoidBinPacking) {
-        // If we are breaking after '(', '{', '<', this is not bin packing
-        // unless AllowAllParametersOfDeclarationOnNextLine is false.
-        if (!(Previous.isOneOf(tok::l_paren, tok::l_brace) ||
-              Previous.Type == TT_BinaryOperator) ||
-            (!Style.AllowAllParametersOfDeclarationOnNextLine &&
-             Line.MustBeDeclaration))
-          State.Stack.back().BreakBeforeParameter = true;
-      }
-
-    } else {
-      if (Current.is(tok::equal) &&
-          (RootToken->is(tok::kw_for) || State.ParenLevel == 0) &&
-          State.Stack.back().VariablePos == 0) {
-        State.Stack.back().VariablePos = State.Column;
-        // Move over * and & if they are bound to the variable name.
-        const FormatToken *Tok = &Previous;
-        while (Tok && State.Stack.back().VariablePos >= Tok->CodePointCount) {
-          State.Stack.back().VariablePos -= Tok->CodePointCount;
-          if (Tok->SpacesRequiredBefore != 0)
-            break;
-          Tok = Tok->Previous;
-        }
-        if (Previous.PartOfMultiVariableDeclStmt)
-          State.Stack.back().LastSpace = State.Stack.back().VariablePos;
-      }
-
-      unsigned Spaces = State.NextToken->SpacesRequiredBefore;
-
-      if (!DryRun)
-        Whitespaces.replaceWhitespace(Current, 0, Spaces,
-                                      State.Column + Spaces);
-
-      if (Current.Type == TT_ObjCSelectorName &&
-          State.Stack.back().ColonPos == 0) {
-        if (State.Stack.back().Indent + Current.LongestObjCSelectorName >
-            State.Column + Spaces + Current.CodePointCount)
-          State.Stack.back().ColonPos =
-              State.Stack.back().Indent + Current.LongestObjCSelectorName;
-        else
-          State.Stack.back().ColonPos =
-              State.Column + Spaces + Current.CodePointCount;
-      }
-
-      if (Previous.opensScope() && Previous.Type != TT_ObjCMethodExpr &&
-          Current.Type != TT_LineComment)
-        State.Stack.back().Indent = State.Column + Spaces;
-      if (Previous.is(tok::comma) && !Current.isTrailingComment() &&
-          State.Stack.back().AvoidBinPacking)
-        State.Stack.back().NoLineBreak = true;
-
-      State.Column += Spaces;
-      if (Current.is(tok::l_paren) && Previous.isOneOf(tok::kw_if, tok::kw_for))
-        // Treat the condition inside an if as if it was a second function
-        // parameter, i.e. let nested calls have an indent of 4.
-        State.Stack.back().LastSpace = State.Column + 1; // 1 is length of "(".
-      else if (Previous.is(tok::comma))
-        State.Stack.back().LastSpace = State.Column;
-      else if ((Previous.Type == TT_BinaryOperator ||
-                Previous.Type == TT_ConditionalExpr ||
-                Previous.Type == TT_CtorInitializerColon) &&
-               !(Previous.getPrecedence() == prec::Assignment &&
-                 Current.FakeLParens.empty()))
-        // Always indent relative to the RHS of the expression unless this is a
-        // simple assignment without binary expression on the RHS.
-        State.Stack.back().LastSpace = State.Column;
-      else if (Previous.Type == TT_InheritanceColon)
-        State.Stack.back().Indent = State.Column;
-      else if (Previous.opensScope()) {
-        // If a function has multiple parameters (including a single parameter
-        // that is a binary expression) or a trailing call, indent all
-        // parameters from the opening parenthesis. This avoids confusing
-        // indents like:
-        //   OuterFunction(InnerFunctionCall(
-        //       ParameterToInnerFunction),
-        //                 SecondParameterToOuterFunction);
-        bool HasMultipleParameters = !Current.FakeLParens.empty();
-        bool HasTrailingCall = false;
-        if (Previous.MatchingParen) {
-          const FormatToken *Next = Previous.MatchingParen->getNextNonComment();
-          if (Next && Next->isOneOf(tok::period, tok::arrow))
-            HasTrailingCall = true;
-        }
-        if (HasMultipleParameters || HasTrailingCall)
-          State.Stack.back().LastSpace = State.Column;
-      }
-    }
-
-    return moveStateToNextToken(State, DryRun, Newline) + ExtraPenalty;
-  }
-
-  /// \brief Mark the next token as consumed in \p State and modify its stacks
-  /// accordingly.
-  unsigned moveStateToNextToken(LineState &State, bool DryRun, bool Newline) {
-    const FormatToken &Current = *State.NextToken;
-    assert(State.Stack.size());
-
-    if (Current.Type == TT_InheritanceColon)
-      State.Stack.back().AvoidBinPacking = true;
-    if (Current.is(tok::lessless) && State.Stack.back().FirstLessLess == 0)
-      State.Stack.back().FirstLessLess = State.Column;
-    if (Current.is(tok::l_square) &&
-        State.Stack.back().StartOfArraySubscripts == 0)
-      State.Stack.back().StartOfArraySubscripts = State.Column;
-    if (Current.is(tok::question))
-      State.Stack.back().QuestionColumn = State.Column;
-    if (!Current.opensScope() && !Current.closesScope())
-      State.LowestLevelOnLine =
-          std::min(State.LowestLevelOnLine, State.ParenLevel);
-    if (Current.isOneOf(tok::period, tok::arrow) &&
-        Line.Type == LT_BuilderTypeCall && State.ParenLevel == 0)
-      State.Stack.back().StartOfFunctionCall =
-          Current.LastInChainOfCalls ? 0
-                                     : State.Column + Current.CodePointCount;
-    if (Current.Type == TT_CtorInitializerColon) {
-      // Indent 2 from the column, so:
-      // SomeClass::SomeClass()
-      //     : First(...), ...
-      //       Next(...)
-      //       ^ line up here.
-      State.Stack.back().Indent =
-          State.Column +
-          (Style.BreakConstructorInitializersBeforeComma ? 0 : 2);
-      if (Style.ConstructorInitializerAllOnOneLineOrOnePerLine)
-        State.Stack.back().AvoidBinPacking = true;
-      State.Stack.back().BreakBeforeParameter = false;
-    }
-
-    // If return returns a binary expression, align after it.
-    if (Current.is(tok::kw_return) && !Current.FakeLParens.empty())
-      State.Stack.back().LastSpace = State.Column + 7;
-
-    // In ObjC method declaration we align on the ":" of parameters, but we need
-    // to ensure that we indent parameters on subsequent lines by at least 4.
-    if (Current.Type == TT_ObjCMethodSpecifier)
-      State.Stack.back().Indent += 4;
-
-    // Insert scopes created by fake parenthesis.
-    const FormatToken *Previous = Current.getPreviousNonComment();
-    // Don't add extra indentation for the first fake parenthesis after
-    // 'return', assignements or opening <({[. The indentation for these cases
-    // is special cased.
-    bool SkipFirstExtraIndent =
-        Current.is(tok::kw_return) ||
-        (Previous && (Previous->opensScope() ||
-                      Previous->getPrecedence() == prec::Assignment));
-    for (SmallVectorImpl<prec::Level>::const_reverse_iterator
-             I = Current.FakeLParens.rbegin(),
-             E = Current.FakeLParens.rend();
-         I != E; ++I) {
-      ParenState NewParenState = State.Stack.back();
-      NewParenState.ContainsLineBreak = false;
-      NewParenState.Indent =
-          std::max(std::max(State.Column, NewParenState.Indent),
-                   State.Stack.back().LastSpace);
-
-      // Always indent conditional expressions. Never indent expression where
-      // the 'operator' is ',', ';' or an assignment (i.e. *I <=
-      // prec::Assignment) as those have different indentation rules. Indent
-      // other expression, unless the indentation needs to be skipped.
-      if (*I == prec::Conditional ||
-          (!SkipFirstExtraIndent && *I > prec::Assignment &&
-           !Style.BreakBeforeBinaryOperators))
-        NewParenState.Indent += 4;
-      if (Previous && !Previous->opensScope())
-        NewParenState.BreakBeforeParameter = false;
-      State.Stack.push_back(NewParenState);
-      SkipFirstExtraIndent = false;
-    }
-
-    // If we encounter an opening (, [, { or <, we add a level to our stacks to
-    // prepare for the following tokens.
-    if (Current.opensScope()) {
-      unsigned NewIndent;
-      unsigned LastSpace = State.Stack.back().LastSpace;
-      bool AvoidBinPacking;
-      if (Current.is(tok::l_brace)) {
-        NewIndent =
-            LastSpace + (Style.Cpp11BracedListStyle ? 4 : Style.IndentWidth);
-        const FormatToken *NextNoComment = Current.getNextNonComment();
-        AvoidBinPacking = NextNoComment &&
-                          NextNoComment->Type == TT_DesignatedInitializerPeriod;
-      } else {
-        NewIndent =
-            4 + std::max(LastSpace, State.Stack.back().StartOfFunctionCall);
-        AvoidBinPacking = !Style.BinPackParameters ||
-                          (Style.ExperimentalAutoDetectBinPacking &&
-                           (Current.PackingKind == PPK_OnePerLine ||
-                            (!BinPackInconclusiveFunctions &&
-                             Current.PackingKind == PPK_Inconclusive)));
-      }
-
-      State.Stack.push_back(ParenState(NewIndent, LastSpace, AvoidBinPacking,
-                                       State.Stack.back().NoLineBreak));
-      ++State.ParenLevel;
-    }
-
-    // If this '[' opens an ObjC call, determine whether all parameters fit into
-    // one line and put one per line if they don't.
-    if (Current.is(tok::l_square) && Current.Type == TT_ObjCMethodExpr &&
-        Current.MatchingParen != NULL) {
-      if (getLengthToMatchingParen(Current) + State.Column > getColumnLimit())
-        State.Stack.back().BreakBeforeParameter = true;
-    }
-
-    // If we encounter a closing ), ], } or >, we can remove a level from our
-    // stacks.
-    if (Current.isOneOf(tok::r_paren, tok::r_square) ||
-        (Current.is(tok::r_brace) && State.NextToken != RootToken) ||
-        State.NextToken->Type == TT_TemplateCloser) {
-      State.Stack.pop_back();
-      --State.ParenLevel;
-    }
-    if (Current.is(tok::r_square)) {
-      // If this ends the array subscript expr, reset the corresponding value.
-      const FormatToken *NextNonComment = Current.getNextNonComment();
-      if (NextNonComment && NextNonComment->isNot(tok::l_square))
-        State.Stack.back().StartOfArraySubscripts = 0;
-    }
-
-    // Remove scopes created by fake parenthesis.
-    for (unsigned i = 0, e = Current.FakeRParens; i != e; ++i) {
-      unsigned VariablePos = State.Stack.back().VariablePos;
-      State.Stack.pop_back();
-      State.Stack.back().VariablePos = VariablePos;
-    }
-
-    if (Current.is(tok::string_literal) && State.StartOfStringLiteral == 0) {
-      State.StartOfStringLiteral = State.Column;
-    } else if (!Current.isOneOf(tok::comment, tok::identifier, tok::hash,
-                                tok::string_literal)) {
-      State.StartOfStringLiteral = 0;
-    }
-
-    State.Column += Current.CodePointCount;
-
-    State.NextToken = State.NextToken->Next;
-
-    if (!Newline && Style.AlwaysBreakBeforeMultilineStrings &&
-        Current.is(tok::string_literal) && Current.CanBreakBefore)
-      return 0;
-
-    return breakProtrudingToken(Current, State, DryRun);
-  }
-
-  /// \brief If the current token sticks out over the end of the line, break
-  /// it if possible.
-  ///
-  /// \returns An extra penalty if a token was broken, otherwise 0.
-  ///
-  /// The returned penalty will cover the cost of the additional line breaks and
-  /// column limit violation in all lines except for the last one. The penalty
-  /// for the column limit violation in the last line (and in single line
-  /// tokens) is handled in \c addNextStateToQueue.
-  unsigned breakProtrudingToken(const FormatToken &Current, LineState &State,
-                                bool DryRun) {
-    llvm::OwningPtr<BreakableToken> Token;
-    unsigned StartColumn = State.Column - Current.CodePointCount;
-    unsigned OriginalStartColumn =
-        SourceMgr.getSpellingColumnNumber(Current.getStartOfNonWhitespace()) -
-        1;
-
-    if (Current.is(tok::string_literal) &&
-        Current.Type != TT_ImplicitStringLiteral) {
-      // Only break up default narrow strings.
-      if (!Current.TokenText.startswith("\""))
-        return 0;
-      // Don't break string literals with escaped newlines. As clang-format must
-      // not change the string's content, it is unlikely that we'll end up with
-      // a better format.
-      if (Current.TokenText.find("\\\n") != StringRef::npos)
-        return 0;
-      // Exempts unterminated string literals from line breaking. The user will
-      // likely want to terminate the string before any line breaking is done.
-      if (Current.IsUnterminatedLiteral)
-        return 0;
-
-      Token.reset(new BreakableStringLiteral(Current, StartColumn,
-                                             Line.InPPDirective, Encoding));
-    } else if (Current.Type == TT_BlockComment && Current.isTrailingComment()) {
-      Token.reset(new BreakableBlockComment(
-          Style, Current, StartColumn, OriginalStartColumn, !Current.Previous,
-          Line.InPPDirective, Encoding));
-    } else if (Current.Type == TT_LineComment &&
-               (Current.Previous == NULL ||
-                Current.Previous->Type != TT_ImplicitStringLiteral)) {
-      // Don't break line comments with escaped newlines. These look like
-      // separate line comments, but in fact contain a single line comment with
-      // multiple lines including leading whitespace and the '//' markers.
-      //
-      // FIXME: If we want to handle them correctly, we'll need to adjust
-      // leading whitespace in consecutive lines when changing indentation of
-      // the first line similar to what we do with block comments.
-      StringRef::size_type EscapedNewlinePos = Current.TokenText.find("\\\n");
-      if (EscapedNewlinePos != StringRef::npos) {
-        State.Column =
-            StartColumn +
-            encoding::getCodePointCount(
-                Current.TokenText.substr(0, EscapedNewlinePos), Encoding) +
-            1;
-        return 0;
-      }
-
-      Token.reset(new BreakableLineComment(Current, StartColumn,
-                                           Line.InPPDirective, Encoding));
-    } else {
-      return 0;
-    }
-    if (Current.UnbreakableTailLength >= getColumnLimit())
-      return 0;
-
-    unsigned RemainingSpace = getColumnLimit() - Current.UnbreakableTailLength;
-    bool BreakInserted = false;
-    unsigned Penalty = 0;
-    unsigned RemainingTokenColumns = 0;
-    for (unsigned LineIndex = 0, EndIndex = Token->getLineCount();
-         LineIndex != EndIndex; ++LineIndex) {
-      if (!DryRun)
-        Token->replaceWhitespaceBefore(LineIndex, Whitespaces);
-      unsigned TailOffset = 0;
-      RemainingTokenColumns = Token->getLineLengthAfterSplit(
-          LineIndex, TailOffset, StringRef::npos);
-      while (RemainingTokenColumns > RemainingSpace) {
-        BreakableToken::Split Split =
-            Token->getSplit(LineIndex, TailOffset, getColumnLimit());
-        if (Split.first == StringRef::npos) {
-          // The last line's penalty is handled in addNextStateToQueue().
-          if (LineIndex < EndIndex - 1)
-            Penalty += Style.PenaltyExcessCharacter *
-                       (RemainingTokenColumns - RemainingSpace);
-          break;
-        }
-        assert(Split.first != 0);
-        unsigned NewRemainingTokenColumns = Token->getLineLengthAfterSplit(
-            LineIndex, TailOffset + Split.first + Split.second,
-            StringRef::npos);
-        assert(NewRemainingTokenColumns < RemainingTokenColumns);
-        if (!DryRun)
-          Token->insertBreak(LineIndex, TailOffset, Split, Whitespaces);
-        Penalty += Current.is(tok::string_literal) ? Style.PenaltyBreakString
-                                                   : Style.PenaltyBreakComment;
-        unsigned ColumnsUsed =
-            Token->getLineLengthAfterSplit(LineIndex, TailOffset, Split.first);
-        if (ColumnsUsed > getColumnLimit()) {
-          Penalty +=
-              Style.PenaltyExcessCharacter * (ColumnsUsed - getColumnLimit());
-        }
-        TailOffset += Split.first + Split.second;
-        RemainingTokenColumns = NewRemainingTokenColumns;
-        BreakInserted = true;
-      }
-    }
-
-    State.Column = RemainingTokenColumns;
-
-    if (BreakInserted) {
-      // If we break the token inside a parameter list, we need to break before
-      // the next parameter on all levels, so that the next parameter is clearly
-      // visible. Line comments already introduce a break.
-      if (Current.Type != TT_LineComment) {
-        for (unsigned i = 0, e = State.Stack.size(); i != e; ++i)
-          State.Stack[i].BreakBeforeParameter = true;
-      }
-
-      State.Stack.back().LastSpace = StartColumn;
-    }
-    return Penalty;
-  }
-
-  unsigned getColumnLimit() {
-    // In preprocessor directives reserve two chars for trailing " \"
-    return Style.ColumnLimit - (Line.InPPDirective ? 2 : 0);
-  }
-
   /// \brief An edge in the solution space from \c Previous->State to \c State,
   /// inserting a newline dependent on the \c NewLine.
   struct StateNode {
@@ -1173,7 +431,7 @@
                        << (*I)->Previous->State.NextToken->SplitPenalty << "\n";
         }
       });
-      addTokenToState((*I)->NewLine, false, State);
+      Indenter->addTokenToState(State, (*I)->NewLine, false);
     }
   }
 
@@ -1183,9 +441,9 @@
   /// penalty of \p Penalty. Insert a line break if \p NewLine is \c true.
   void addNextStateToQueue(unsigned Penalty, StateNode *PreviousNode,
                            bool NewLine) {
-    if (NewLine && !canBreak(PreviousNode->State))
+    if (NewLine && !Indenter->canBreak(PreviousNode->State))
       return;
-    if (!NewLine && mustBreak(PreviousNode->State))
+    if (!NewLine && Indenter->mustBreak(PreviousNode->State))
       return;
     if (NewLine) {
       if (!PreviousNode->State.Stack.back().ContainsLineBreak)
@@ -1195,9 +453,10 @@
 
     StateNode *Node = new (Allocator.Allocate())
         StateNode(PreviousNode->State, NewLine, PreviousNode);
-    Penalty += addTokenToState(NewLine, true, Node->State);
-    if (Node->State.Column > getColumnLimit()) {
-      unsigned ExcessCharacters = Node->State.Column - getColumnLimit();
+    Penalty += Indenter->addTokenToState(Node->State, NewLine, true);
+    if (Node->State.Column > Indenter->getColumnLimit()) {
+      unsigned ExcessCharacters =
+          Node->State.Column - Indenter->getColumnLimit();
       Penalty += Style.PenaltyExcessCharacter * ExcessCharacters;
     }
 
@@ -1205,137 +464,15 @@
     ++Count;
   }
 
-  /// \brief Returns \c true, if a line break after \p State is allowed.
-  bool canBreak(const LineState &State) {
-    const FormatToken &Current = *State.NextToken;
-    const FormatToken &Previous = *Current.Previous;
-    assert(&Previous == Current.Previous);
-    if (!Current.CanBreakBefore &&
-        !(Current.is(tok::r_brace) &&
-          State.Stack.back().BreakBeforeClosingBrace))
-      return false;
-    // The opening "{" of a braced list has to be on the same line as the first
-    // element if it is nested in another braced init list or function call.
-    if (!Current.MustBreakBefore && Previous.is(tok::l_brace) &&
-        Previous.Previous &&
-        Previous.Previous->isOneOf(tok::l_brace, tok::l_paren, tok::comma))
-      return false;
-    // This prevents breaks like:
-    //   ...
-    //   SomeParameter, OtherParameter).DoSomething(
-    //   ...
-    // As they hide "DoSomething" and are generally bad for readability.
-    if (Previous.opensScope() &&
-        State.LowestLevelOnLine < State.StartOfLineLevel)
-      return false;
-    return !State.Stack.back().NoLineBreak;
-  }
-
-  /// \brief Returns \c true, if a line break after \p State is mandatory.
-  bool mustBreak(const LineState &State) {
-    const FormatToken &Current = *State.NextToken;
-    const FormatToken &Previous = *Current.Previous;
-    if (Current.MustBreakBefore || Current.Type == TT_InlineASMColon)
-      return true;
-    if (!Style.Cpp11BracedListStyle && Current.is(tok::r_brace) &&
-        State.Stack.back().BreakBeforeClosingBrace)
-      return true;
-    if (Previous.is(tok::semi) && State.LineContainsContinuedForLoopSection)
-      return true;
-    if (Style.BreakConstructorInitializersBeforeComma) {
-      if (Previous.Type == TT_CtorInitializerComma)
-        return false;
-      if (Current.Type == TT_CtorInitializerComma)
-        return true;
-    }
-    if ((Previous.isOneOf(tok::comma, tok::semi) || Current.is(tok::question) ||
-         (Current.Type == TT_ConditionalExpr &&
-          !(Current.is(tok::colon) && Previous.is(tok::question)))) &&
-        State.Stack.back().BreakBeforeParameter &&
-        !Current.isTrailingComment() &&
-        !Current.isOneOf(tok::r_paren, tok::r_brace))
-      return true;
-    if (Style.AlwaysBreakBeforeMultilineStrings &&
-        State.Column > State.Stack.back().Indent &&
-        Current.is(tok::string_literal) && Previous.isNot(tok::lessless) &&
-        Previous.Type != TT_InlineASMColon &&
-        ((Current.getNextNonComment() &&
-          Current.getNextNonComment()->is(tok::string_literal)) ||
-         (Current.TokenText.find("\\\n") != StringRef::npos)))
-      return true;
-
-    if (!Style.BreakBeforeBinaryOperators) {
-      // If we need to break somewhere inside the LHS of a binary expression, we
-      // should also break after the operator. Otherwise, the formatting would
-      // hide the operator precedence, e.g. in:
-      //   if (aaaaaaaaaaaaaa ==
-      //           bbbbbbbbbbbbbb && c) {..
-      // For comparisons, we only apply this rule, if the LHS is a binary
-      // expression itself as otherwise, the line breaks seem superfluous.
-      // We need special cases for ">>" which we have split into two ">" while
-      // lexing in order to make template parsing easier.
-      //
-      // FIXME: We'll need something similar for styles that break before binary
-      // operators.
-      bool IsComparison = (Previous.getPrecedence() == prec::Relational ||
-                           Previous.getPrecedence() == prec::Equality) &&
-                          Previous.Previous && Previous.Previous->Type !=
-                                                   TT_BinaryOperator; // For >>.
-      bool LHSIsBinaryExpr =
-          Previous.Previous && Previous.Previous->FakeRParens > 0;
-      if (Previous.Type == TT_BinaryOperator &&
-          (!IsComparison || LHSIsBinaryExpr) &&
-          Current.Type != TT_BinaryOperator && // For >>.
-          !Current.isTrailingComment() &&
-          !Previous.isOneOf(tok::lessless, tok::question) &&
-          Previous.getPrecedence() != prec::Assignment &&
-          State.Stack.back().BreakBeforeParameter)
-        return true;
-    }
-
-    // Same as above, but for the first "<<" operator.
-    if (Current.is(tok::lessless) && State.Stack.back().BreakBeforeParameter &&
-        State.Stack.back().FirstLessLess == 0)
-      return true;
-
-    // FIXME: Comparing LongestObjCSelectorName to 0 is a hacky way of finding
-    // out whether it is the first parameter. Clean this up.
-    if (Current.Type == TT_ObjCSelectorName &&
-        Current.LongestObjCSelectorName == 0 &&
-        State.Stack.back().BreakBeforeParameter)
-      return true;
-    if ((Current.Type == TT_CtorInitializerColon ||
-         (Previous.ClosesTemplateDeclaration && State.ParenLevel == 0)))
-      return true;
-
-    if ((Current.Type == TT_StartOfName || Current.is(tok::kw_operator)) &&
-        Line.MightBeFunctionDecl && State.Stack.back().BreakBeforeParameter &&
-        State.ParenLevel == 0)
-      return true;
-    return false;
-  }
-
-  // Returns the total number of columns required for the remaining tokens.
-  unsigned getRemainingLength(const LineState &State) {
-    if (State.NextToken && State.NextToken->Previous)
-      return Line.Last->TotalLength - State.NextToken->Previous->TotalLength;
-    return 0;
-  }
-
+  ContinuationIndenter *Indenter;
   FormatStyle Style;
-  SourceManager &SourceMgr;
   const AnnotatedLine &Line;
-  const unsigned FirstIndent;
-  const FormatToken *RootToken;
-  WhitespaceManager &Whitespaces;
 
   llvm::SpecificBumpPtrAllocator<StateNode> Allocator;
   QueueType Queue;
   // Increasing count of \c StateNode items we have created. This is used
   // to create a deterministic order independent of the container.
   unsigned Count;
-  encoding::Encoding Encoding;
-  bool BinPackInconclusiveFunctions;
 };
 
 class FormatTokenLexer {
@@ -1549,10 +686,28 @@
               SourceMgr.getSpellingColumnNumber(FirstTok->Tok.getLocation()) -
               1;
         }
-        UnwrappedLineFormatter Formatter(Style, SourceMgr, TheLine, Indent,
-                                         TheLine.First, Whitespaces, Encoding,
-                                         BinPackInconclusiveFunctions);
-        Formatter.format(I + 1 != E ? &*(I + 1) : NULL);
+        ContinuationIndenter Indenter(Style, SourceMgr, TheLine, Indent,
+                                      Whitespaces, Encoding,
+                                      BinPackInconclusiveFunctions);
+
+        // If everything fits on a single line, just put it there.
+        unsigned ColumnLimit = Style.ColumnLimit;
+        if ((I + 1) != E && (I + 1)->InPPDirective &&
+            !(I + 1)->First->HasUnescapedNewline)
+          ColumnLimit = Indenter.getColumnLimit();
+
+        if (I->Last->TotalLength + Indent <= ColumnLimit) {
+          LineState State = Indenter.getInitialState();
+          while (State.NextToken != NULL)
+            Indenter.addTokenToState(State, false, false);
+        } else if (Style.ColumnLimit == 0) {
+          NoColumnLimitFormatter Formatter(&Indenter);
+          Formatter.format();
+        } else {
+          UnwrappedLineFormatter Formatter(&Indenter, Style, TheLine);
+          Formatter.format();
+        }
+
         IndentForLevel[TheLine.Level] = LevelIndent;
         PreviousLineWasTouched = true;
       } else {
