<commit_before>import com.google.common.collect {
    GuavaImmutableList=ImmutableList {
        GILBuilder=Builder
    }
}

shared final
class ImmutableList<out Element>
        (GuavaImmutableList<out Element>|{Element*} elements)
        satisfies List<Element>
        given Element satisfies Object {

    shared
    GuavaImmutableList<out Element> delegate;

    if (is {Element*} elements) {
        value builder = GILBuilder<Element>();
        for (element in elements) {
            builder.add(element);
        }
        delegate = builder.build();
    }
    else {
        delegate = elements;
    }

    shared actual
    Element? getFromFirst(Integer index)
        =>  if (0 <= index < delegate.size())
            then delegate.get(index)
            else null;

    shared actual
    Integer size
        =>  delegate.size();

    shared actual
    Integer? lastIndex
        =>  let (index = size - 1)
            (index >= 0 then index);

    shared actual
    ImmutableList<Element> clone()
        =>  this;

    shared actual
    Boolean equals(Object that)
        =>  (super of List<Element>).equals(that);

    shared actual
    Integer hash
        =>  (super of List<Element>).hash;
}<commit_msg>additional methods for ImmutableList<commit_after>import com.google.common.collect {
    GuavaImmutableList=ImmutableList {
        GILBuilder=Builder
    }
}

shared final
class ImmutableList<out Element>
        (GuavaImmutableList<out Element>|{Element*} elements)
        satisfies List<Element>
        given Element satisfies Object {

    shared
    GuavaImmutableList<out Element> delegate;

    if (is {Element*} elements) {
        value builder = GILBuilder<Element>();
        for (element in elements) {
            builder.add(element);
        }
        delegate = builder.build();
    }
    else {
        delegate = elements;
    }

    // TODO trim, trimtrailing, trimleading, slice, initial, terminal, keys

    shared actual
    Element? getFromFirst(Integer index)
        =>  if (0 <= index < delegate.size())
            then delegate.get(index)
            else null;

    shared actual
    Integer size
        =>  delegate.size();

    shared actual
    Integer? lastIndex
        =>  let (index = size - 1)
            (index >= 0 then index);

    shared actual
    ImmutableList<Element> span(Integer from, Integer to)
        =>  if (size > 0) then
                let (end = size - 1)
                if (from <= to) then
                    if (from <= 0 && to >= end) then
                        this
                    else if (to >= 0 && from <= end) then
                        ImmutableList(delegate.subList(
                                largerInteger(from, 0),
                                smallerInteger(to + 1, size)))
                    else
                        emptyImmutableList
                else
                    if (end <= 0 && from >= end) then
                        this.reversed
                    else if (from >= 0 && to <= end) then
                        ImmutableList(delegate.subList(
                                largerInteger(to, 0),
                                smallerInteger(from + 1, size))
                                .reverse())
                    else
                        emptyImmutableList
            else
                emptyImmutableList;

    shared actual
    ImmutableList<Element> spanFrom(Integer from)
        =>  if (from < size)
            then span(from, size - 1)
            else emptyImmutableList;

    shared actual
    ImmutableList<Element> spanTo(Integer to)
        =>  if (to >= 0)
            then span(0, to)
            else emptyImmutableList;

    shared actual
    ImmutableList<Element> measure(Integer from, Integer length)
        =>  if (length > 0)
            then span(from, from + length - 1)
            else emptyImmutableList;

    shared actual
    List<Integer> keys
        =>  0:size;

    shared actual
    ImmutableList<Element> clone()
        =>  this;

    shared actual
    ImmutableList<Element> coalesced
        =>  this;

    shared actual
    ImmutableList<Element> reversed
        =>  ImmutableList(delegate.reverse());

    shared actual
    Boolean equals(Object that)
        =>  (super of List<Element>).equals(that);

    shared actual
    Integer hash
        =>  (super of List<Element>).hash;
}

ImmutableList<Nothing> emptyImmutableList = ImmutableList({});

Integer smallerInteger(Integer x, Integer y)
    =>  if (x < y) then x else y;

Integer largerInteger(Integer x, Integer y)
    =>  if (x > y) then x else y;
{'fraction_non_alphanumeric': 0.09152027759705053, 'fraction_numerical': 0.004771199306007373, 'mean_word_length': 1.7065727699530517, 'pattern_counts': {'":': 0, '<': 38, '<?xml version=': 0, '>': 58, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6959482', 'n_tokens_mistral': 1248, 'n_tokens_neox': 1183, 'n_words': 342}