int (@Nullable HighlightInfo info, StringBuilder sb, CharSequence sequence, int offset, ArrayList<HighlightInfo> infos) { if (info == null || !infos.isEmpty() && getMaxEnd(infos) < info.getStartOffset()) { if (infos.size() == 1) { HighlightInfo cur = infos.remove(0); sb.append(sequence.subSequence(offset, cur.getStartOffset())); appendTag(sb, cur, true); sb.append(sequence.subSequence(cur.getStartOffset(), cur.getEndOffset())); appendTag(sb, cur, false); offset = cur.getEndOffset(); } else { // process overlapped LinkedList<HighlightInfo> stack = new LinkedList<>(); for (HighlightInfo cur : infos) { offset = processStack(stack, sb, sequence, offset, cur.getStartOffset()); sb.append(sequence.subSequence(offset, cur.getStartOffset())); offset = cur.getStartOffset(); appendTag(sb, cur, true); stack.addLast(cur); } offset = processStack(stack, sb, sequence, offset, sequence.length()); infos.clear(); } } if (info != null) { boolean found = false; for (HighlightInfo cur : infos) { if (cur.getStartOffset() == info.getStartOffset() && cur.getEndOffset() == info.getEndOffset() && cur.getSeverity() == info.getSeverity()) { found = true; break; } } if (!found) infos.add(info); } return offset; }