@Override
 public Boolean caseRichStringLiteral(RichStringLiteral object) {
   String value = object.getValue();
   List<TextLine> lines = TextLines.splitString(value);
   if (lines.isEmpty()) {
     Literal literal = factory.createLiteral();
     literal.setLength(0);
     literal.setOffset(0);
     literal.setLiteral(object);
     addToCurrentLine(literal);
   } else {
     for (TextLine textLine : lines) {
       Literal literal = factory.createLiteral();
       literal.setLength(textLine.length());
       literal.setOffset(textLine.getRelativeOffset());
       literal.setLiteral(object);
       addToCurrentLine(literal);
       if (textLine.hasTrailingLineBreak()) {
         LineBreak lineBreak = factory.createLineBreak();
         lineBreak.setLength(textLine.getDelimiterLength());
         lineBreak.setOffset(textLine.getRelativeOffset() + textLine.length());
         lineBreak.setLiteral(object);
         addToCurrentLine(lineBreak);
         currentLine = null;
       }
     }
   }
   return Boolean.TRUE;
 }
 @Override
 public Boolean caseLiteral(Literal object) {
   if (announced == null || announced != object.getLiteral()) {
     acceptor.announceNextLiteral(object.getLiteral());
     announced = object.getLiteral();
   }
   Line line = object.getLine();
   TextLine textLine =
       new TextLine(
           Strings.emptyIfNull(object.getLiteral().getValue()),
           object.getOffset(),
           object.getLength(),
           0);
   CharSequence ws = textLine.getLeadingWhiteSpace();
   ProcessedRichString string = line.getRichString();
   boolean firstOrLast =
       string.getLines().get(0) == line
           || string.getLines().get(string.getLines().size() - 1) == line;
   if (isTemplateLine(line)) {
     if (line.getParts().get(0) == object) {
       if (!firstOrLast) {
         boolean followedByOpening = false;
         if (line.getParts().size() >= 2) {
           LinePart next = line.getParts().get(1);
           if (next instanceof ForLoopStart || next instanceof IfConditionStart) {
             followedByOpening = true;
           }
         }
         if (!followedByOpening) {
           pushSemanticIndentation(indentationHandler.getTotalIndentation());
         } else {
           pushSemanticIndentation(ws);
         }
       }
     }
     announceTemplateText(textLine, object.getLiteral());
   } else {
     if (skipCount <= 1) {
       firstOrLast = false;
       if (skipCount == 0 && line.getParts().get(0) == object) {
         if (textLine.length() == ws.length()) {
           for (int i = 1; i < line.getParts().size(); i++) {
             if (line.getParts().get(i) instanceof Literal
                 && !(line.getParts().get(i) instanceof LineBreak)) {
               Literal nextLiteralInSameLine = (Literal) line.getParts().get(i);
               TextLine nextLiteralLine =
                   new TextLine(
                       nextLiteralInSameLine.getLiteral().getValue(),
                       nextLiteralInSameLine.getOffset(),
                       nextLiteralInSameLine.getLength(),
                       0);
               CharSequence nextLeading = nextLiteralLine.getLeadingWhiteSpace();
               if (nextLeading.length() > 0) {
                 ws = ws.toString() + nextLeading;
               }
               skipCount++;
               if (nextLeading.length() != nextLiteralLine.length()) {
                 break;
               }
             } else {
               break;
             }
           }
           if (skipCount != 0) {
             pushSemanticIndentation(ws);
           } else {
             pushSemanticIndentation(ws);
             announceIndentation();
             announceSemanticText(
                 textLine.subSequence(ws.length(), textLine.length()), object.getLiteral());
           }
         } else {
           pushSemanticIndentation(ws);
           announceIndentation();
           announceSemanticText(
               textLine.subSequence(ws.length(), textLine.length()), object.getLiteral());
         }
       } else {
         if (skipCount == 1) {
           skipCount--;
           announceIndentation();
           announceSemanticText(
               textLine.subSequence(ws.length(), textLine.length()), object.getLiteral());
         } else {
           announceSemanticText(textLine, object.getLiteral());
         }
       }
     } else {
       skipCount--;
     }
   }
   if (!firstOrLast && line.getParts().get(line.getParts().size() - 1) == object) {
     popIndentation();
   }
   computeNextPart(object);
   return Boolean.TRUE;
 }