@Override
  public TextRange replaceWhiteSpace(TextRange textRange, ASTNode nodeAfter, String whiteSpace) {
    if (myOriginalFormattingModel instanceof FormattingModelWithShiftIndentInsideDocumentRange) {
      whiteSpace = ((FormattingModelWithShiftIndentInsideDocumentRange)myOriginalFormattingModel).adjustWhiteSpaceInsideDocument(
        nodeAfter,
        whiteSpace);
    }

    boolean removesStartMarker;
    String marker;

    // When processing injection in cdata / comment we need not remove start / end markers that present as whitespace during check in
    // com.intellij.formatting.WhiteSpace and during building formatter model = blocks in e.g. com.intellij.psi.formatter.xml.XmlTagBlock
    if ((removesStartMarker = removesPattern(textRange, whiteSpace, marker = "<![CDATA[") ||
        removesPattern(textRange, whiteSpace, marker ="<!--[")) ||
        removesPattern(textRange, whiteSpace, marker = "]]>") ||
        removesPattern(textRange, whiteSpace, marker = "]-->")
      ) {
      String newWs = null;

      if (removesStartMarker) {    // TODO once we reformat comments we will need to handle their markers as well
        int at = CharArrayUtil.indexOf(myDocument.getCharsSequence(), marker, textRange.getStartOffset(), textRange.getEndOffset() + 1);
        String ws = myDocument.getCharsSequence().subSequence(textRange.getStartOffset(), textRange.getEndOffset()).toString();
        newWs = mergeWsWithCdataMarker(whiteSpace, ws, at - textRange.getStartOffset());

        if (removesPattern(textRange, newWs != null ? newWs: whiteSpace, marker = "]]>")) {
          int i;
          if (newWs != null && (i = newWs.lastIndexOf('\n')) > 0) {
            int cdataStart = newWs.indexOf("<![CDATA[");
            int i2 = newWs.lastIndexOf('\n', cdataStart);
            String cdataIndent = i2 != -1 ? newWs.substring(i2 + 1, cdataStart):"";
            newWs = newWs.substring(0, i) + cdataIndent + marker + newWs.substring(i);
          }
        }
      }

      if (newWs == null) return textRange;
      whiteSpace = newWs;
    }

    CharSequence whiteSpaceToUse = getDocumentModel().adjustWhiteSpaceIfNecessary(
      whiteSpace, textRange.getStartOffset(), textRange.getEndOffset(), nodeAfter, false
    );

    myDocument.replaceString(textRange.getStartOffset(),
                           textRange.getEndOffset(),
                           whiteSpaceToUse);

    return new TextRange(textRange.getStartOffset(), textRange.getStartOffset() + whiteSpaceToUse.length());
  }
@Override
  public TextRange replaceWhiteSpace(TextRange textRange, ASTNode nodeAfter, String whiteSpace)