// 
// Decompiled by Procyon v0.6.0
// 

package it.unimi.dsi.fastutil.shorts;

import java.util.Spliterator;
import it.unimi.dsi.fastutil.BigListIterator;
import java.io.ObjectInputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import it.unimi.dsi.fastutil.BigList;
import java.util.NoSuchElementException;
import java.util.Iterator;
import it.unimi.dsi.fastutil.BigArrays;
import java.util.Collection;
import it.unimi.dsi.fastutil.Size64;
import java.io.Serializable;
import java.util.RandomAccess;

public class ShortBigArrayBigList extends AbstractShortBigList implements RandomAccess, Cloneable, Serializable
{
    private static final long serialVersionUID = -7046029254386353130L;
    public static final int DEFAULT_INITIAL_CAPACITY = 10;
    protected transient short[][] a;
    protected long size;
    
    protected ShortBigArrayBigList(final short[][] a, final boolean dummy) {
        this.a = a;
    }
    
    public ShortBigArrayBigList(final long capacity) {
        if (capacity < 0L) {
            throw new IllegalArgumentException("Initial capacity (" + capacity + ") is negative");
        }
        if (capacity == 0L) {
            this.a = ShortBigArrays.EMPTY_BIG_ARRAY;
        }
        else {
            this.a = ShortBigArrays.newBigArray(capacity);
        }
    }
    
    public ShortBigArrayBigList() {
        this.a = ShortBigArrays.DEFAULT_EMPTY_BIG_ARRAY;
    }
    
    public ShortBigArrayBigList(final ShortCollection c) {
        this(Size64.sizeOf(c));
        if (c instanceof ShortBigList) {
            ((ShortBigList)c).getElements(0L, this.a, 0L, this.size = Size64.sizeOf(c));
        }
        else {
            final ShortIterator i = c.iterator();
            while (i.hasNext()) {
                this.add(i.nextShort());
            }
        }
    }
    
    public ShortBigArrayBigList(final ShortBigList l) {
        this(l.size64());
        l.getElements(0L, this.a, 0L, this.size = l.size64());
    }
    
    public ShortBigArrayBigList(final short[][] a) {
        this(a, 0L, BigArrays.length(a));
    }
    
    public ShortBigArrayBigList(final short[][] a, final long offset, final long length) {
        this(length);
        BigArrays.copy(a, offset, this.a, 0L, length);
        this.size = length;
    }
    
    public ShortBigArrayBigList(final Iterator<? extends Short> i) {
        this();
        while (i.hasNext()) {
            this.add((short)i.next());
        }
    }
    
    public ShortBigArrayBigList(final ShortIterator i) {
        this();
        while (i.hasNext()) {
            this.add(i.nextShort());
        }
    }
    
    public short[][] elements() {
        return this.a;
    }
    
    public static ShortBigArrayBigList wrap(final short[][] a, final long length) {
        if (length > BigArrays.length(a)) {
            throw new IllegalArgumentException("The specified length (" + length + ") is greater than the array size (" + BigArrays.length(a) + ")");
        }
        final ShortBigArrayBigList l = new ShortBigArrayBigList(a, false);
        l.size = length;
        return l;
    }
    
    public static ShortBigArrayBigList wrap(final short[][] a) {
        return wrap(a, BigArrays.length(a));
    }
    
    public static ShortBigArrayBigList of() {
        return new ShortBigArrayBigList();
    }
    
    public static ShortBigArrayBigList of(final short... init) {
        return wrap(BigArrays.wrap(init));
    }
    
    public void ensureCapacity(final long capacity) {
        if (capacity <= BigArrays.length(this.a) || this.a == ShortBigArrays.DEFAULT_EMPTY_BIG_ARRAY) {
            return;
        }
        this.a = BigArrays.forceCapacity(this.a, capacity, this.size);
        assert this.size <= BigArrays.length(this.a);
    }
    
    private void grow(long capacity) {
        final long oldLength = BigArrays.length(this.a);
        if (capacity <= oldLength) {
            return;
        }
        if (this.a != ShortBigArrays.DEFAULT_EMPTY_BIG_ARRAY) {
            capacity = Math.max(oldLength + (oldLength >> 1), capacity);
        }
        else if (capacity < 10L) {
            capacity = 10L;
        }
        this.a = BigArrays.forceCapacity(this.a, capacity, this.size);
        assert this.size <= BigArrays.length(this.a);
    }
    
    @Override
    public void add(final long index, final short k) {
        this.ensureIndex(index);
        this.grow(this.size + 1L);
        if (index != this.size) {
            BigArrays.copy(this.a, index, this.a, index + 1L, this.size - index);
        }
        BigArrays.set(this.a, index, k);
        ++this.size;
        assert this.size <= BigArrays.length(this.a);
    }
    
    @Override
    public boolean add(final short k) {
        this.grow(this.size + 1L);
        BigArrays.set(this.a, this.size++, k);
        assert this.size <= BigArrays.length(this.a);
        return true;
    }
    
    @Override
    public short getShort(final long index) {
        if (index >= this.size) {
            throw new IndexOutOfBoundsException("Index (" + index + ") is greater than or equal to list size (" + this.size + ")");
        }
        return BigArrays.get(this.a, index);
    }
    
    @Override
    public long indexOf(final short k) {
        for (long i = 0L; i < this.size; ++i) {
            if (k == BigArrays.get(this.a, i)) {
                return i;
            }
        }
        return -1L;
    }
    
    @Override
    public long lastIndexOf(final short k) {
        long i = this.size;
        while (i-- != 0L) {
            if (k == BigArrays.get(this.a, i)) {
                return i;
            }
        }
        return -1L;
    }
    
    @Override
    public short removeShort(final long index) {
        if (index >= this.size) {
            throw new IndexOutOfBoundsException("Index (" + index + ") is greater than or equal to list size (" + this.size + ")");
        }
        final short old = BigArrays.get(this.a, index);
        --this.size;
        if (index != this.size) {
            BigArrays.copy(this.a, index + 1L, this.a, index, this.size - index);
        }
        assert this.size <= BigArrays.length(this.a);
        return old;
    }
    
    @Override
    public boolean rem(final short k) {
        final long index = this.indexOf(k);
        if (index == -1L) {
            return false;
        }
        this.removeShort(index);
        assert this.size <= BigArrays.length(this.a);
        return true;
    }
    
    @Override
    public short set(final long index, final short k) {
        if (index >= this.size) {
            throw new IndexOutOfBoundsException("Index (" + index + ") is greater than or equal to list size (" + this.size + ")");
        }
        final short old = BigArrays.get(this.a, index);
        BigArrays.set(this.a, index, k);
        return old;
    }
    
    @Override
    public boolean removeAll(final ShortCollection c) {
        short[] s = null;
        short[] d = null;
        int ss = -1;
        int sd = 134217728;
        int ds = -1;
        int dd = 134217728;
        for (long i = 0L; i < this.size; ++i) {
            if (sd == 134217728) {
                sd = 0;
                s = this.a[++ss];
            }
            if (!c.contains(s[sd])) {
                if (dd == 134217728) {
                    d = this.a[++ds];
                    dd = 0;
                }
                d[dd++] = s[sd];
            }
            ++sd;
        }
        final long j = BigArrays.index(ds, dd);
        final boolean modified = this.size != j;
        this.size = j;
        return modified;
    }
    
    @Override
    public boolean removeAll(final Collection<?> c) {
        short[] s = null;
        short[] d = null;
        int ss = -1;
        int sd = 134217728;
        int ds = -1;
        int dd = 134217728;
        for (long i = 0L; i < this.size; ++i) {
            if (sd == 134217728) {
                sd = 0;
                s = this.a[++ss];
            }
            if (!c.contains(s[sd])) {
                if (dd == 134217728) {
                    d = this.a[++ds];
                    dd = 0;
                }
                d[dd++] = s[sd];
            }
            ++sd;
        }
        final long j = BigArrays.index(ds, dd);
        final boolean modified = this.size != j;
        this.size = j;
        return modified;
    }
    
    @Override
    public boolean addAll(long index, final ShortCollection c) {
        if (c instanceof ShortList) {
            return this.addAll(index, (ShortList)c);
        }
        if (c instanceof ShortBigList) {
            return this.addAll(index, (ShortBigList)c);
        }
        this.ensureIndex(index);
        int n = c.size();
        if (n == 0) {
            return false;
        }
        this.grow(this.size + n);
        BigArrays.copy(this.a, index, this.a, index + n, this.size - index);
        final ShortIterator i = c.iterator();
        this.size += n;
        assert this.size <= BigArrays.length(this.a);
        while (n-- != 0) {
            BigArrays.set(this.a, index++, i.nextShort());
        }
        return true;
    }
    
    @Override
    public boolean addAll(final long index, final ShortBigList list) {
        this.ensureIndex(index);
        final long n = list.size64();
        if (n == 0L) {
            return false;
        }
        this.grow(this.size + n);
        BigArrays.copy(this.a, index, this.a, index + n, this.size - index);
        list.getElements(0L, this.a, index, n);
        this.size += n;
        assert this.size <= BigArrays.length(this.a);
        return true;
    }
    
    @Override
    public boolean addAll(final long index, final ShortList list) {
        this.ensureIndex(index);
        int n = list.size();
        if (n == 0) {
            return false;
        }
        this.grow(this.size + n);
        BigArrays.copy(this.a, index, this.a, index + n, this.size - index);
        this.size += n;
        assert this.size <= BigArrays.length(this.a);
        int segment = BigArrays.segment(index);
        int displ = BigArrays.displacement(index);
        int pos = 0;
        while (n > 0) {
            final int l = Math.min(this.a[segment].length - displ, n);
            list.getElements(pos, this.a[segment], displ, l);
            if ((displ += l) == 134217728) {
                displ = 0;
                ++segment;
            }
            pos += l;
            n -= l;
        }
        return true;
    }
    
    @Override
    public void clear() {
        this.size = 0L;
        assert this.size <= BigArrays.length(this.a);
    }
    
    @Override
    public long size64() {
        return this.size;
    }
    
    @Override
    public void size(final long size) {
        if (size > BigArrays.length(this.a)) {
            this.a = BigArrays.forceCapacity(this.a, size, this.size);
        }
        if (size > this.size) {
            BigArrays.fill(this.a, this.size, size, (short)0);
        }
        this.size = size;
    }
    
    @Override
    public boolean isEmpty() {
        return this.size == 0L;
    }
    
    public void trim() {
        this.trim(0L);
    }
    
    public void trim(final long n) {
        final long arrayLength = BigArrays.length(this.a);
        if (n >= arrayLength || this.size == arrayLength) {
            return;
        }
        this.a = BigArrays.trim(this.a, Math.max(n, this.size));
        assert this.size <= BigArrays.length(this.a);
    }
    
    @Override
    public ShortBigList subList(final long from, final long to) {
        if (from == 0L && to == this.size64()) {
            return this;
        }
        this.ensureIndex(from);
        this.ensureIndex(to);
        if (from > to) {
            throw new IndexOutOfBoundsException("Start index (" + from + ") is greater than end index (" + to + ")");
        }
        return new SubList(from, to);
    }
    
    @Override
    public void getElements(final long from, final short[][] a, final long offset, final long length) {
        BigArrays.copy(this.a, from, a, offset, length);
    }
    
    @Override
    public void getElements(final long from, final short[] a, final int offset, final int length) {
        BigArrays.copyFromBig(this.a, from, a, offset, length);
    }
    
    @Override
    public void removeElements(final long from, final long to) {
        BigArrays.ensureFromTo(this.size, from, to);
        BigArrays.copy(this.a, to, this.a, from, this.size - to);
        this.size -= to - from;
    }
    
    @Override
    public void addElements(final long index, final short[][] a, final long offset, final long length) {
        this.ensureIndex(index);
        BigArrays.ensureOffsetLength(a, offset, length);
        this.grow(this.size + length);
        BigArrays.copy(this.a, index, this.a, index + length, this.size - index);
        BigArrays.copy(a, offset, this.a, index, length);
        this.size += length;
    }
    
    @Override
    public void setElements(final long index, final short[][] a, final long offset, final long length) {
        BigArrays.copy(a, offset, this.a, index, length);
    }
    
    @Override
    public void forEach(final ShortConsumer action) {
        for (long i = 0L; i < this.size; ++i) {
            action.accept(BigArrays.get(this.a, i));
        }
    }
    
    @Override
    public ShortBigListIterator listIterator(final long index) {
        this.ensureIndex(index);
        return new ShortBigListIterator() {
            long pos = index;
            long last = -1L;
            
            @Override
            public boolean hasNext() {
                return this.pos < ShortBigArrayBigList.this.size;
            }
            
            @Override
            public boolean hasPrevious() {
                return this.pos > 0L;
            }
            
            @Override
            public short nextShort() {
                if (!this.hasNext()) {
                    throw new NoSuchElementException();
                }
                final short[][] a = ShortBigArrayBigList.this.a;
                final long n = this.pos++;
                this.last = n;
                return BigArrays.get(a, n);
            }
            
            @Override
            public short previousShort() {
                if (!this.hasPrevious()) {
                    throw new NoSuchElementException();
                }
                final short[][] a = ShortBigArrayBigList.this.a;
                final long index = this.pos - 1L;
                this.pos = index;
                this.last = index;
                return BigArrays.get(a, index);
            }
            
            @Override
            public long nextIndex() {
                return this.pos;
            }
            
            @Override
            public long previousIndex() {
                return this.pos - 1L;
            }
            
            @Override
            public void add(final short k) {
                ShortBigArrayBigList.this.add(this.pos++, k);
                this.last = -1L;
            }
            
            @Override
            public void set(final short k) {
                if (this.last == -1L) {
                    throw new IllegalStateException();
                }
                ShortBigArrayBigList.this.set(this.last, k);
            }
            
            @Override
            public void remove() {
                if (this.last == -1L) {
                    throw new IllegalStateException();
                }
                ShortBigArrayBigList.this.removeShort(this.last);
                if (this.last < this.pos) {
                    --this.pos;
                }
                this.last = -1L;
            }
            
            @Override
            public void forEachRemaining(final ShortConsumer action) {
                while (this.pos < ShortBigArrayBigList.this.size) {
                    final short[][] a = ShortBigArrayBigList.this.a;
                    final long n = this.pos++;
                    this.last = n;
                    action.accept(BigArrays.get(a, n));
                }
            }
            
            @Override
            public long back(long n) {
                if (n < 0L) {
                    throw new IllegalArgumentException("Argument must be nonnegative: " + n);
                }
                final long remaining = ShortBigArrayBigList.this.size - this.pos;
                if (n < remaining) {
                    this.pos -= n;
                }
                else {
                    n = remaining;
                    this.pos = 0L;
                }
                this.last = this.pos;
                return n;
            }
            
            @Override
            public long skip(long n) {
                if (n < 0L) {
                    throw new IllegalArgumentException("Argument must be nonnegative: " + n);
                }
                final long remaining = ShortBigArrayBigList.this.size - this.pos;
                if (n < remaining) {
                    this.pos += n;
                }
                else {
                    n = remaining;
                    this.pos = ShortBigArrayBigList.this.size;
                }
                this.last = this.pos - 1L;
                return n;
            }
        };
    }
    
    @Override
    public ShortSpliterator spliterator() {
        return new Spliterator();
    }
    
    public ShortBigArrayBigList clone() {
        ShortBigArrayBigList c;
        if (this.getClass() == ShortBigArrayBigList.class) {
            c = new ShortBigArrayBigList(this.size);
            c.size = this.size;
        }
        else {
            try {
                c = (ShortBigArrayBigList)super.clone();
            }
            catch (final CloneNotSupportedException e) {
                throw new InternalError(e);
            }
            c.a = ShortBigArrays.newBigArray(this.size);
        }
        BigArrays.copy(this.a, 0L, c.a, 0L, this.size);
        return c;
    }
    
    public boolean equals(final ShortBigArrayBigList l) {
        if (l == this) {
            return true;
        }
        long s = this.size64();
        if (s != l.size64()) {
            return false;
        }
        final short[][] a1 = this.a;
        final short[][] a2 = l.a;
        if (a1 == a2) {
            return true;
        }
        while (s-- != 0L) {
            if (BigArrays.get(a1, s) != BigArrays.get(a2, s)) {
                return false;
            }
        }
        return true;
    }
    
    @Override
    public boolean equals(final Object o) {
        if (o == this) {
            return true;
        }
        if (o == null) {
            return false;
        }
        if (!(o instanceof BigList)) {
            return false;
        }
        if (o instanceof ShortBigArrayBigList) {
            return this.equals((ShortBigArrayBigList)o);
        }
        if (o instanceof SubList) {
            return ((SubList)o).equals(this);
        }
        return super.equals(o);
    }
    
    public int compareTo(final ShortBigArrayBigList l) {
        final long s1 = this.size64();
        final long s2 = l.size64();
        final short[][] a1 = this.a;
        final short[][] a2 = l.a;
        if (a1 == a2 && s1 == s2) {
            return 0;
        }
        int i;
        for (i = 0; i < s1 && i < s2; ++i) {
            final short e1 = BigArrays.get(a1, i);
            final short e2 = BigArrays.get(a2, i);
            final int r;
            if ((r = Short.compare(e1, e2)) != 0) {
                return r;
            }
        }
        return (i < s2) ? -1 : ((i < s1) ? 1 : 0);
    }
    
    @Override
    public int compareTo(final BigList<? extends Short> l) {
        if (l instanceof ShortBigArrayBigList) {
            return this.compareTo((ShortBigArrayBigList)l);
        }
        if (l instanceof SubList) {
            return -((SubList)l).compareTo(this);
        }
        return super.compareTo(l);
    }
    
    private void writeObject(final ObjectOutputStream s) throws IOException {
        s.defaultWriteObject();
        for (int i = 0; i < this.size; ++i) {
            s.writeShort(BigArrays.get(this.a, i));
        }
    }
    
    private void readObject(final ObjectInputStream s) throws IOException, ClassNotFoundException {
        s.defaultReadObject();
        this.a = ShortBigArrays.newBigArray(this.size);
        for (int i = 0; i < this.size; ++i) {
            BigArrays.set(this.a, i, s.readShort());
        }
    }
    
    private class SubList extends ShortRandomAccessSubList
    {
        private static final long serialVersionUID = -3185226345314976296L;
        
        protected SubList(final long from, final long to) {
            super(ShortBigArrayBigList.this, from, to);
        }
        
        private short[][] getParentArray() {
            return ShortBigArrayBigList.this.a;
        }
        
        @Override
        public short getShort(final long i) {
            this.ensureRestrictedIndex(i);
            return BigArrays.get(ShortBigArrayBigList.this.a, i + this.from);
        }
        
        @Override
        public ShortBigListIterator listIterator(final long index) {
            return new SubListIterator(index);
        }
        
        @Override
        public ShortSpliterator spliterator() {
            return new SubListSpliterator();
        }
        
        boolean contentsEquals(final short[][] otherA, final long otherAFrom, final long otherATo) {
            if (ShortBigArrayBigList.this.a == otherA && this.from == otherAFrom && this.to == otherATo) {
                return true;
            }
            if (otherATo - otherAFrom != this.size64()) {
                return false;
            }
            long pos = this.to;
            long otherPos = otherATo;
            while (--pos >= this.from) {
                if (BigArrays.get(ShortBigArrayBigList.this.a, pos) != BigArrays.get(otherA, --otherPos)) {
                    return false;
                }
            }
            return true;
        }
        
        @Override
        public boolean equals(final Object o) {
            if (o == this) {
                return true;
            }
            if (o == null) {
                return false;
            }
            if (!(o instanceof BigList)) {
                return false;
            }
            if (o instanceof ShortBigArrayBigList) {
                final ShortBigArrayBigList other = (ShortBigArrayBigList)o;
                return this.contentsEquals(other.a, 0L, other.size64());
            }
            if (o instanceof SubList) {
                final SubList other2 = (SubList)o;
                return this.contentsEquals(other2.getParentArray(), other2.from, other2.to);
            }
            return super.equals(o);
        }
        
        int contentsCompareTo(final short[][] otherA, final long otherAFrom, final long otherATo) {
            if (ShortBigArrayBigList.this.a == otherA && this.from == otherAFrom && this.to == otherATo) {
                return 0;
            }
            long i = this.from;
            for (long j = otherAFrom; i < this.to && i < otherATo; ++i, ++j) {
                final short e1 = BigArrays.get(ShortBigArrayBigList.this.a, i);
                final short e2 = BigArrays.get(otherA, j);
                final int r;
                if ((r = Short.compare(e1, e2)) != 0) {
                    return r;
                }
            }
            return (i < otherATo) ? -1 : ((i < this.to) ? 1 : 0);
        }
        
        @Override
        public int compareTo(final BigList<? extends Short> l) {
            if (l instanceof ShortBigArrayBigList) {
                final ShortBigArrayBigList other = (ShortBigArrayBigList)l;
                return this.contentsCompareTo(other.a, 0L, other.size64());
            }
            if (l instanceof SubList) {
                final SubList other2 = (SubList)l;
                return this.contentsCompareTo(other2.getParentArray(), other2.from, other2.to);
            }
            return super.compareTo(l);
        }
        
        private final class SubListIterator extends ShortBigListIterators.AbstractIndexBasedBigListIterator
        {
            SubListIterator(final long index) {
                super(0L, index);
            }
            
            @Override
            protected final short get(final long i) {
                return BigArrays.get(ShortBigArrayBigList.this.a, SubList.this.from + i);
            }
            
            @Override
            protected final void add(final long i, final short k) {
                SubList.this.add(i, k);
            }
            
            @Override
            protected final void set(final long i, final short k) {
                SubList.this.set(i, k);
            }
            
            @Override
            protected final void remove(final long i) {
                SubList.this.removeShort(i);
            }
            
            @Override
            protected final long getMaxPos() {
                return SubList.this.to - SubList.this.from;
            }
            
            @Override
            public short nextShort() {
                if (!this.hasNext()) {
                    throw new NoSuchElementException();
                }
                final short[][] a = ShortBigArrayBigList.this.a;
                final long from = SubList.this.from;
                final long lastReturned = this.pos++;
                this.lastReturned = lastReturned;
                return BigArrays.get(a, from + lastReturned);
            }
            
            @Override
            public short previousShort() {
                if (!this.hasPrevious()) {
                    throw new NoSuchElementException();
                }
                final short[][] a = ShortBigArrayBigList.this.a;
                final long from = SubList.this.from;
                final long n = this.pos - 1L;
                this.pos = n;
                this.lastReturned = n;
                return BigArrays.get(a, from + n);
            }
            
            @Override
            public void forEachRemaining(final ShortConsumer action) {
                final long max = SubList.this.to - SubList.this.from;
                while (this.pos < max) {
                    final short[][] a = ShortBigArrayBigList.this.a;
                    final long from = SubList.this.from;
                    final long lastReturned = this.pos++;
                    this.lastReturned = lastReturned;
                    action.accept(BigArrays.get(a, from + lastReturned));
                }
            }
        }
        
        private final class SubListSpliterator extends ShortBigSpliterators.LateBindingSizeIndexBasedSpliterator
        {
            SubListSpliterator() {
                super(SubList.this.from);
            }
            
            private SubListSpliterator(final long pos, final long maxPos) {
                super(pos, maxPos);
            }
            
            @Override
            protected final long getMaxPosFromBackingStore() {
                return SubList.this.to;
            }
            
            @Override
            protected final short get(final long i) {
                return BigArrays.get(ShortBigArrayBigList.this.a, i);
            }
            
            @Override
            protected final SubListSpliterator makeForSplit(final long pos, final long maxPos) {
                return new SubListSpliterator(pos, maxPos);
            }
            
            @Override
            protected final long computeSplitPoint() {
                final long defaultSplit = super.computeSplitPoint();
                return BigArrays.nearestSegmentStart(defaultSplit, this.pos + 1L, this.getMaxPos() - 1L);
            }
            
            @Override
            public boolean tryAdvance(final ShortConsumer action) {
                if (this.pos >= this.getMaxPos()) {
                    return false;
                }
                action.accept(BigArrays.get(ShortBigArrayBigList.this.a, this.pos++));
                return true;
            }
            
            @Override
            public void forEachRemaining(final ShortConsumer action) {
                final long max = this.getMaxPos();
                while (this.pos < max) {
                    action.accept(BigArrays.get(ShortBigArrayBigList.this.a, this.pos++));
                }
            }
        }
    }
    
    private final class Spliterator implements ShortSpliterator
    {
        boolean hasSplit;
        long pos;
        long max;
        
        public Spliterator(final ShortBigArrayBigList list) {
            this(list, 0L, list.size, false);
        }
        
        private Spliterator(final long pos, final long max, final boolean hasSplit) {
            this.hasSplit = false;
            assert pos <= max : "pos " + pos + " must be <= max " + max;
            this.pos = pos;
            this.max = max;
            this.hasSplit = hasSplit;
        }
        
        private long getWorkingMax() {
            return this.hasSplit ? this.max : ShortBigArrayBigList.this.size;
        }
        
        @Override
        public int characteristics() {
            return 16720;
        }
        
        @Override
        public long estimateSize() {
            return this.getWorkingMax() - this.pos;
        }
        
        @Override
        public boolean tryAdvance(final ShortConsumer action) {
            if (this.pos >= this.getWorkingMax()) {
                return false;
            }
            action.accept(BigArrays.get(ShortBigArrayBigList.this.a, this.pos++));
            return true;
        }
        
        @Override
        public void forEachRemaining(final ShortConsumer action) {
            final long max = this.getWorkingMax();
            while (this.pos < max) {
                action.accept(BigArrays.get(ShortBigArrayBigList.this.a, this.pos));
                ++this.pos;
            }
        }
        
        @Override
        public long skip(long n) {
            if (n < 0L) {
                throw new IllegalArgumentException("Argument must be nonnegative: " + n);
            }
            final long max = this.getWorkingMax();
            if (this.pos >= max) {
                return 0L;
            }
            final long remaining = max - this.pos;
            if (n < remaining) {
                this.pos += n;
                return n;
            }
            n = remaining;
            this.pos = max;
            return n;
        }
        
        @Override
        public ShortSpliterator trySplit() {
            final long max = this.getWorkingMax();
            final long retLen = max - this.pos >> 1;
            if (retLen <= 1L) {
                return null;
            }
            this.max = max;
            long myNewPos = this.pos + retLen;
            final long retMax;
            myNewPos = (retMax = BigArrays.nearestSegmentStart(myNewPos, this.pos + 1L, max - 1L));
            final long oldPos = this.pos;
            this.pos = myNewPos;
            this.hasSplit = true;
            return new Spliterator(oldPos, retMax, true);
        }
    }
}
