class CharSubSequence extends BasedSequenceImpl {
    final private char[] baseChars;
    final private CharSubSequence base;
    final private int startOffset;
    final private int endOffset;

    private CharSubSequence(char[] chars, int hash) {
        super(hash);

        int iMax = chars.length;
        base = this;
        baseChars = chars;
        startOffset = 0;
        endOffset = baseChars.length;
    }

    private CharSubSequence(CharSubSequence baseSeq, int startIndex, int endIndex) {
        super(0);

        assert startIndex >= 0 && endIndex >= startIndex && endIndex <= baseSeq.baseChars.length : String.format("CharSubSequence must have (startIndex > 0 || endIndex < %d) && endIndex >= startIndex, got startIndex:%d, endIndex: %d", baseSeq.baseChars.length, startIndex, endIndex);
        assert (startIndex > 0 || endIndex < baseSeq.baseChars.length) : String.format("CharSubSequence must be proper subsequences [1, %d) got startIndex:%d, endIndex: %d", Math.max(0, baseSeq.baseChars.length - 1), startIndex, endIndex);

        base = baseSeq;
        baseChars = baseSeq.baseChars;
        startOffset = base.startOffset + startIndex;
        endOffset = base.startOffset + endIndex;
    }

    @Override
    public int getOptionFlags() {
        return 0;
    }

    @Override
    public boolean allOptions(int options) {
        return false;
    }

    @Override
    public boolean anyOptions(int options) {
        return false;
    }

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

    @Override
    public @Nullable DataHolder getOptions() {
        return null;
    }

    @NotNull
    @Override
    public CharSubSequence getBaseSequence() {
        return base;
    }

    @NotNull
    @Override
    public char[] getBase() {
        return baseChars;
    }

    public int getStartOffset() {
        return startOffset;
    }

    public int getEndOffset() {
        return endOffset;
    }

    @Override
    public int length() {
        return endOffset - startOffset;
    }

    @NotNull
    @Override
    public Range getSourceRange() {
        return Range.of(startOffset, endOffset);
    }

    @Override
    public int getIndexOffset(int index) {
        SequenceUtils.validateIndexInclusiveEnd(index, length());
        return startOffset + index;
    }

    @Override
    public char charAt(int index) {<FILL_FUNCTION_BODY>}

    @NotNull
    @Override
    public CharSubSequence subSequence(int startIndex, int endIndex) {
        SequenceUtils.validateStartEnd(startIndex, endIndex, length());
        return base.baseSubSequence(startOffset + startIndex, startOffset + endIndex);
    }

    @NotNull
    @Override
    public CharSubSequence baseSubSequence(int startIndex, int endIndex) {
        SequenceUtils.validateStartEnd(startIndex, endIndex, baseChars.length);
        return startIndex == startOffset && endIndex == endOffset ? this : base != this ? base.baseSubSequence(startIndex, endIndex) : new CharSubSequence(base, startIndex, endIndex);
    }

    public static CharSubSequence of(CharSequence charSequence) {
        return of(charSequence, 0, charSequence.length());
    }

    public static CharSubSequence of(CharSequence charSequence, int startIndex) {
        assert startIndex <= charSequence.length();
        return of(charSequence, startIndex, charSequence.length());
    }

    /**
     * @param chars      char array
     * @param startIndex start index in array
     * @param endIndex   end index in array
     * @return CharSubSequence based sequence of array
     * @deprecated NOTE: use BasedSequence.of() for creating based sequences
     */
    @Deprecated
    public static CharSubSequence of(char[] chars, int startIndex, int endIndex) {
        assert startIndex >= 0 && startIndex <= endIndex && endIndex <= chars.length;

        char[] useChars = new char[chars.length];
        System.arraycopy(chars, 0, useChars, 0, chars.length);
        return startIndex == 0 && endIndex == chars.length ? new CharSubSequence(useChars, 0) : new CharSubSequence(useChars, 0).subSequence(startIndex, endIndex);
    }

    /**
     * @param charSequence char sequence
     * @param startIndex   start index in sequence
     * @param endIndex     end index in sequence
     * @return char based sequence
     */
    private static CharSubSequence of(CharSequence charSequence, int startIndex, int endIndex) {
        assert startIndex >= 0 && startIndex <= endIndex && endIndex <= charSequence.length();

        CharSubSequence charSubSequence;

        if (charSequence instanceof CharSubSequence) {
            charSubSequence = ((CharSubSequence) charSequence);
        } else if (charSequence instanceof String) {
            charSubSequence = new CharSubSequence(((String) charSequence).toCharArray(), ((String) charSequence).hashCode());
        } else if (charSequence instanceof StringBuilder) {
            char[] chars = new char[charSequence.length()];
            ((StringBuilder) charSequence).getChars(0, charSequence.length(), chars, 0);
            charSubSequence = new CharSubSequence(chars, 0);
        } else {
            charSubSequence = new CharSubSequence(charSequence.toString().toCharArray(), 0);
        }

        if (startIndex == 0 && endIndex == charSequence.length()) {
            return charSubSequence;
        } else {
            return charSubSequence.subSequence(startIndex, endIndex);
        }
    }
}

        SequenceUtils.validateIndex(index, length());
        char c = baseChars[index + startOffset];
        return c == SequenceUtils.NUL ? SequenceUtils.ENC_NUL : c;
    
<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>