class SegmentedSequence extends BasedSequenceImpl implements ReplacedBasedSequence {
    protected final BasedSequence baseSeq;    // base sequence
    protected final int startOffset;          // this sequence's start offset in base
    protected final int endOffset;            // this sequence's end offset in base
    protected final int length;               // length of this sequence

    protected SegmentedSequence(BasedSequence baseSeq, int startOffset, int endOffset, int length) {
        super(0);
        assert baseSeq == baseSeq.getBaseSequence();

        if (startOffset < 0 && endOffset < 0) {
            // NOTE: segmented sequence with no based segments in it gets both offsets as -1
            startOffset = 0;
            endOffset = 0;
        }

        assert startOffset >= 0 : "startOffset: " + startOffset;
        assert endOffset >= startOffset && endOffset <= baseSeq.length() : "endOffset: " + endOffset;

        this.baseSeq = baseSeq;
        this.startOffset = startOffset;
        this.endOffset = endOffset;
        this.length = length;
    }

    @NotNull
    @Override
    final public Object getBase() {
        return baseSeq.getBase();
    }

    @NotNull
    @Override
    final public BasedSequence getBaseSequence() {
        return baseSeq;
    }

    /**
     * Get the start in the base sequence for this segmented sequence.
     * <p>
     * NOTE: this is the startOffset determined when the sequence was built from segments and may differ from
     * the startOffset of the first based segment in this sequence
     *
     * @return start in base sequence
     */
    final public int getStartOffset() {
        return startOffset;
    }

    /**
     * Get the end offset in the base sequence
     * <p>
     * NOTE: this is the endOffset determined when the sequence was built from segments and may differ from
     * the endOffset of the last based segment in this sequence
     *
     * @return end in base sequence
     */
    final public int getEndOffset() {
        return endOffset;
    }

    @Override
    final public int getOptionFlags() {
        return getBaseSequence().getOptionFlags();
    }

    @Override
    final public boolean allOptions(int options) {
        return getBaseSequence().allOptions(options);
    }

    @Override
    final public boolean anyOptions(int options) {
        return getBaseSequence().anyOptions(options);
    }

    @Override
    final public <T> T getOption(DataKeyBase<T> dataKey) {
        return getBaseSequence().getOption(dataKey);
    }

    @Override
    final public @Nullable DataHolder getOptions() {
        return getBaseSequence().getOptions();
    }

    @Override
    final public int length() {
        return length;
    }

    @NotNull
    @Override
    final public Range getSourceRange() {
        return Range.of(getStartOffset(), getEndOffset());
    }

    @NotNull
    @Override
    final public BasedSequence baseSubSequence(int startIndex, int endIndex) {
        SequenceUtils.validateStartEnd(startIndex, endIndex, baseSeq.length());
        return baseSeq.baseSubSequence(startIndex, endIndex);
    }

    /**
     * Use {@link BasedSequence#getBuilder()} and then {@link SequenceBuilder#addAll(Iterable)} or
     * if you know which are based segments vs. out of base Strings then use {@link BasedSegmentBuilder}
     * to construct segments directly.
     * <p>
     * Use only if you absolutely need to use this old method because it calls the builder.addAll() for all the segments
     * anyway.
     * <p>
     * If you need the location where content would have been use the FencedCodeBlock.getOpeningMarker().getEndOffset() + 1
     *
     * @param basedSequence base sequence for the segments
     * @param segments      list of based sequences to put into a based sequence
     * @return based sequence of segments. Result is a sequence which looks like
     *         all the segments were concatenated, while still maintaining
     *         the original offset for each character when using {@link #getIndexOffset(int)}(int index)
     */
    public static BasedSequence create(BasedSequence basedSequence, @NotNull Iterable<? extends BasedSequence> segments) {
        return create(basedSequence.getBuilder().addAll(segments));
    }

    public static BasedSequence create(BasedSequence... segments) {
        return segments.length == 0 ? BasedSequence.NULL : create(segments[0], new ArrayIterable<>(segments));
    }

    public static BasedSequence create(SequenceBuilder builder) {<FILL_FUNCTION_BODY>}

    /**
     * @param basedSequence base sequence for the segments
     * @param segments      list of based sequences to put into a based sequence
     * @return based sequence of segments. Result is a sequence which looks like
     *         all the segments were concatenated, while still maintaining
     *         the original offset for each character when using {@link #getIndexOffset(int)}(int index)
     * @deprecated use {@link BasedSequence#getBuilder()} and then {@link SequenceBuilder#addAll(Iterable)} or if you know which are based segments vs. out of base Strings then use {@link BasedSegmentBuilder} to construct segments directly.
     *         If you absolutely need to use the old method then use {@link SegmentedSequence#create(BasedSequence, Iterable)}
     */
    @Deprecated
    public static BasedSequence of(BasedSequence basedSequence, @NotNull Iterable<? extends BasedSequence> segments) {
        return create(basedSequence, segments);
    }

    @Deprecated
    public static BasedSequence of(BasedSequence... segments) {
        return create(segments);
    }
}

        BasedSequence baseSubSequence = builder.getSingleBasedSequence();
        if (baseSubSequence != null) {
            return baseSubSequence;
        } else if (!builder.isEmpty()) {
            BasedSequence baseSequence = builder.getBaseSequence();
            if (baseSequence.anyOptions(F_FULL_SEGMENTED_SEQUENCES)) {
                return SegmentedSequenceFull.create(baseSequence, builder.getSegmentBuilder());
            } else if (baseSequence.anyOptions(F_TREE_SEGMENTED_SEQUENCES)) {
                return SegmentedSequenceTree.create(baseSequence, builder.getSegmentBuilder());
            } else {
                // Can decide based on segments and length but tree based is not slower and much more efficient
//                return SegmentedSequenceFull.create(baseSequence, builder.getSegmentBuilder());
                return SegmentedSequenceTree.create(baseSequence, builder.getSegmentBuilder());
            }
        }
        return BasedSequence.NULL;
    
<methods>public void <init>(int) ,public void addSegments(@NotNull IBasedSegmentBuilder<?>) ,public int baseColumnAtEnd() ,public int baseColumnAtIndex(int) ,public int baseColumnAtStart() ,public int baseEndOfLine(int) ,public int baseEndOfLine() ,public int baseEndOfLineAnyEOL(int) ,public int baseEndOfLineAnyEOL() ,public @NotNull Pair<Integer,Integer> baseLineColumnAtEnd() ,public @NotNull Pair<Integer,Integer> baseLineColumnAtIndex(int) ,public @NotNull Pair<Integer,Integer> baseLineColumnAtStart() ,public @NotNull Range baseLineRangeAtEnd() ,public @NotNull Range baseLineRangeAtIndex(int) ,public @NotNull Range baseLineRangeAtStart() ,public int baseStartOfLine(int) ,public int baseStartOfLine() ,public int baseStartOfLineAnyEOL(int) ,public int baseStartOfLineAnyEOL() ,public final @NotNull BasedSequence baseSubSequence(int) ,public @NotNull BasedSequence baseSubSequence(int, int) ,public boolean containsAllOf(@NotNull BasedSequence) ,public boolean containsOnlyIn(@NotNull CharPredicate) ,public boolean containsOnlyNotIn(@NotNull CharPredicate) ,public boolean containsSomeIn(@NotNull CharPredicate) ,public boolean containsSomeNotIn(@NotNull CharPredicate) ,public boolean containsSomeOf(@NotNull BasedSequence) ,public @NotNull BasedSequence [] emptyArray() ,public @NotNull BasedSequence extendByAny(@NotNull CharPredicate) ,public @NotNull BasedSequence extendByAny(@NotNull CharPredicate, int) ,public @NotNull BasedSequence extendByAnyNot(@NotNull CharPredicate) ,public @NotNull BasedSequence extendByAnyNot(@NotNull CharPredicate, int) ,public @NotNull BasedSequence extendByOneOfAny(@NotNull CharPredicate) ,public @NotNull BasedSequence extendByOneOfAnyNot(@NotNull CharPredicate) ,public final @NotNull BasedSequence extendToEndOfLine(@NotNull CharPredicate) ,public final @NotNull BasedSequence extendToEndOfLine(boolean) ,public final @NotNull BasedSequence extendToEndOfLine() ,public final @NotNull BasedSequence extendToEndOfLine(@NotNull CharPredicate, boolean) ,public final @NotNull BasedSequence extendToStartOfLine(@NotNull CharPredicate) ,public final @NotNull BasedSequence extendToStartOfLine(boolean) ,public final @NotNull BasedSequence extendToStartOfLine() ,public @NotNull BasedSequence extendToStartOfLine(@NotNull CharPredicate, boolean) ,public static transient com.vladsch.flexmark.util.sequence.BasedSequence firstNonNull(com.vladsch.flexmark.util.sequence.BasedSequence[]) ,public @NotNull SequenceBuilder getBuilder() ,public @NotNull BasedSequence getEmptyPrefix() ,public @NotNull BasedSequence getEmptySuffix() ,public @NotNull SegmentTree getSegmentTree() ,public @NotNull BasedSequence intersect(@NotNull BasedSequence) ,public boolean isBaseCharAt(int, @NotNull CharPredicate) ,public boolean isContinuationOf(@NotNull BasedSequence) ,public boolean isContinuedBy(@NotNull BasedSequence) ,public @NotNull BasedSequence normalizeEOL(@NotNull ReplacedTextMapper) ,public @NotNull BasedSequence normalizeEndWithEOL(@NotNull ReplacedTextMapper) ,public @NotNull BasedSequence nullSequence() ,public @NotNull BasedSequence prefixOf(@NotNull BasedSequence) ,public @NotNull BasedSequence prefixWith(@Nullable CharSequence) ,public final @NotNull BasedSequence prefixWithIndent() ,public @NotNull BasedSequence prefixWithIndent(int) ,public char safeBaseCharAt(int) ,public char safeCharAt(int) ,public @NotNull BasedSequence sequenceOf(@Nullable CharSequence, int, int) ,public @NotNull BasedSequence spliceAtEnd(@NotNull BasedSequence) ,public @NotNull BasedSequence suffixOf(@NotNull BasedSequence) ,public @NotNull BasedSequence toMapped(com.vladsch.flexmark.util.sequence.mappers.CharMapper) ,public @Nullable String toStringOrNull() ,public @NotNull String unescape() ,public @NotNull BasedSequence unescape(@NotNull ReplacedTextMapper) ,public @NotNull String unescapeNoEntities() <variables>