static List<Block> mergeBlocks(List<Block> originalBlocks, List<? extends Block> blocksToMerge, TextRange range)
    throws FragmentedTemplateException {
    if (blocksToMerge.isEmpty()) return originalBlocks;
    List<Block> result = new ArrayList<>();
    if (originalBlocks.isEmpty()) {
      for (Block mergeCandidate : blocksToMerge) {
        if (range.contains(mergeCandidate.getTextRange())) {
          result.add(mergeCandidate);
        }
      }
      return result;
    }
    List<TextRange> originalRanges = new ArrayList<>();
    for (Block originalBlock : originalBlocks) {
      originalRanges.add(originalBlock.getTextRange());
    }
    int lastOffset = range.getStartOffset();
    for (Iterator<Block> originalBlockIterator = originalBlocks.iterator(); originalBlockIterator.hasNext();) {
      Block originalBlock = originalBlockIterator.next();
      int startOffset = originalBlock.getTextRange().getStartOffset();
      if (lastOffset < startOffset) {
        lastOffset = fillGap(originalRanges, blocksToMerge, result, lastOffset, startOffset);
        if (lastOffset < startOffset) {
          lastOffset = fillGap(originalRanges, originalBlocks, result, lastOffset, startOffset);
        }
      }
      Block mergeableBlock = getBlockContaining(blocksToMerge, originalRanges, originalBlock.getTextRange());
      if (mergeableBlock != null) {
        if (mergeableBlock.getTextRange().getStartOffset() >= lastOffset) {
          result.add(mergeableBlock);
          lastOffset = mergeableBlock.getTextRange().getEndOffset();
        }
      }
      else {
        if (startOffset >= lastOffset) {
          result.add(originalBlock);
          originalBlockIterator.remove();
          lastOffset = originalBlock.getTextRange().getEndOffset();
        }
      }
    }
    if (lastOffset < range.getEndOffset()) {
      lastOffset = fillGap(originalRanges, blocksToMerge, result, lastOffset, range.getEndOffset());
      if (lastOffset < range.getEndOffset()) {
        fillGap(originalRanges, originalBlocks, result, lastOffset, range.getEndOffset());
      }
    }
    return result;
  }
static List<Block> mergeBlocks(List<Block> originalBlocks, List<? extends Block> blocksToMerge, TextRange range)