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

package it.unimi.dsi.fastutil.ints;

import java.util.function.IntFunction;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Supplier;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.stream.Stream;
import java.util.stream.IntStream;
import java.io.Serializable;
import java.util.Iterator;
import java.util.Spliterator;
import java.util.function.IntPredicate;
import java.util.function.IntConsumer;
import java.util.Objects;
import java.util.function.Predicate;
import java.util.function.Consumer;
import java.util.Collection;
import it.unimi.dsi.fastutil.objects.ObjectArrays;

public final class IntCollections
{
    private IntCollections() {
    }
    
    public static IntCollection synchronize(final IntCollection c) {
        return new SynchronizedCollection(c);
    }
    
    public static IntCollection synchronize(final IntCollection c, final Object sync) {
        return new SynchronizedCollection(c, sync);
    }
    
    public static IntCollection unmodifiable(final IntCollection c) {
        return new UnmodifiableCollection(c);
    }
    
    public static IntCollection asCollection(final IntIterable iterable) {
        if (iterable instanceof IntCollection) {
            return (IntCollection)iterable;
        }
        return new IterableCollection(iterable);
    }
    
    public abstract static class EmptyCollection extends AbstractIntCollection
    {
        protected EmptyCollection() {
        }
        
        @Override
        public boolean contains(final int k) {
            return false;
        }
        
        @Override
        public Object[] toArray() {
            return ObjectArrays.EMPTY_ARRAY;
        }
        
        @Override
        public <T> T[] toArray(final T[] array) {
            if (array.length > 0) {
                array[0] = null;
            }
            return array;
        }
        
        @Override
        public IntBidirectionalIterator iterator() {
            return IntIterators.EMPTY_ITERATOR;
        }
        
        @Override
        public IntSpliterator spliterator() {
            return IntSpliterators.EMPTY_SPLITERATOR;
        }
        
        @Override
        public int size() {
            return 0;
        }
        
        @Override
        public void clear() {
        }
        
        @Override
        public int hashCode() {
            return 0;
        }
        
        @Override
        public boolean equals(final Object o) {
            return o == this || (o instanceof Collection && ((Collection)o).isEmpty());
        }
        
        @Deprecated
        @Override
        public void forEach(final Consumer<? super Integer> action) {
        }
        
        @Override
        public boolean containsAll(final Collection<?> c) {
            return c.isEmpty();
        }
        
        @Override
        public boolean addAll(final Collection<? extends Integer> c) {
            throw new UnsupportedOperationException();
        }
        
        @Override
        public boolean removeAll(final Collection<?> c) {
            throw new UnsupportedOperationException();
        }
        
        @Override
        public boolean retainAll(final Collection<?> c) {
            throw new UnsupportedOperationException();
        }
        
        @Deprecated
        @Override
        public boolean removeIf(final Predicate<? super Integer> filter) {
            Objects.requireNonNull(filter);
            return false;
        }
        
        @Override
        public int[] toIntArray() {
            return IntArrays.EMPTY_ARRAY;
        }
        
        @Deprecated
        @Override
        public int[] toIntArray(final int[] a) {
            return a;
        }
        
        @Override
        public void forEach(final IntConsumer action) {
        }
        
        @Override
        public boolean containsAll(final IntCollection c) {
            return c.isEmpty();
        }
        
        @Override
        public boolean addAll(final IntCollection c) {
            throw new UnsupportedOperationException();
        }
        
        @Override
        public boolean removeAll(final IntCollection c) {
            throw new UnsupportedOperationException();
        }
        
        @Override
        public boolean retainAll(final IntCollection c) {
            throw new UnsupportedOperationException();
        }
        
        @Override
        public boolean removeIf(final IntPredicate filter) {
            Objects.requireNonNull(filter);
            return false;
        }
    }
    
    static class SynchronizedCollection implements IntCollection, Serializable
    {
        private static final long serialVersionUID = -7046029254386353129L;
        protected final IntCollection collection;
        protected final Object sync;
        
        protected SynchronizedCollection(final IntCollection c, final Object sync) {
            this.collection = Objects.requireNonNull(c);
            this.sync = sync;
        }
        
        protected SynchronizedCollection(final IntCollection c) {
            this.collection = Objects.requireNonNull(c);
            this.sync = this;
        }
        
        @Override
        public boolean add(final int k) {
            synchronized (this.sync) {
                return this.collection.add(k);
            }
        }
        
        @Override
        public boolean contains(final int k) {
            synchronized (this.sync) {
                return this.collection.contains(k);
            }
        }
        
        @Override
        public boolean rem(final int k) {
            synchronized (this.sync) {
                return this.collection.rem(k);
            }
        }
        
        @Override
        public int size() {
            synchronized (this.sync) {
                return this.collection.size();
            }
        }
        
        @Override
        public boolean isEmpty() {
            synchronized (this.sync) {
                return this.collection.isEmpty();
            }
        }
        
        @Override
        public int[] toIntArray() {
            synchronized (this.sync) {
                return this.collection.toIntArray();
            }
        }
        
        @Override
        public Object[] toArray() {
            synchronized (this.sync) {
                return this.collection.toArray();
            }
        }
        
        @Deprecated
        @Override
        public int[] toIntArray(final int[] a) {
            return this.toArray(a);
        }
        
        @Override
        public int[] toArray(final int[] a) {
            synchronized (this.sync) {
                return this.collection.toArray(a);
            }
        }
        
        @Override
        public boolean addAll(final IntCollection c) {
            synchronized (this.sync) {
                return this.collection.addAll(c);
            }
        }
        
        @Override
        public boolean containsAll(final IntCollection c) {
            synchronized (this.sync) {
                return this.collection.containsAll(c);
            }
        }
        
        @Override
        public boolean removeAll(final IntCollection c) {
            synchronized (this.sync) {
                return this.collection.removeAll(c);
            }
        }
        
        @Override
        public boolean retainAll(final IntCollection c) {
            synchronized (this.sync) {
                return this.collection.retainAll(c);
            }
        }
        
        @Deprecated
        @Override
        public boolean add(final Integer k) {
            synchronized (this.sync) {
                return this.collection.add(k);
            }
        }
        
        @Deprecated
        @Override
        public boolean contains(final Object k) {
            synchronized (this.sync) {
                return this.collection.contains(k);
            }
        }
        
        @Deprecated
        @Override
        public boolean remove(final Object k) {
            synchronized (this.sync) {
                return this.collection.remove(k);
            }
        }
        
        @Override
        public IntIterator intIterator() {
            return this.collection.intIterator();
        }
        
        @Override
        public IntSpliterator intSpliterator() {
            return this.collection.intSpliterator();
        }
        
        @Override
        public IntStream intStream() {
            return this.collection.intStream();
        }
        
        @Override
        public IntStream intParallelStream() {
            return this.collection.intParallelStream();
        }
        
        @Override
        public <T> T[] toArray(final T[] a) {
            synchronized (this.sync) {
                return this.collection.toArray(a);
            }
        }
        
        @Override
        public IntIterator iterator() {
            return this.collection.iterator();
        }
        
        @Override
        public IntSpliterator spliterator() {
            return this.collection.spliterator();
        }
        
        @Deprecated
        @Override
        public Stream<Integer> stream() {
            return this.collection.stream();
        }
        
        @Deprecated
        @Override
        public Stream<Integer> parallelStream() {
            return this.collection.parallelStream();
        }
        
        @Override
        public void forEach(final IntConsumer action) {
            synchronized (this.sync) {
                this.collection.forEach(action);
            }
        }
        
        @Override
        public boolean addAll(final Collection<? extends Integer> c) {
            synchronized (this.sync) {
                return this.collection.addAll(c);
            }
        }
        
        @Override
        public boolean containsAll(final Collection<?> c) {
            synchronized (this.sync) {
                return this.collection.containsAll(c);
            }
        }
        
        @Override
        public boolean removeAll(final Collection<?> c) {
            synchronized (this.sync) {
                return this.collection.removeAll(c);
            }
        }
        
        @Override
        public boolean retainAll(final Collection<?> c) {
            synchronized (this.sync) {
                return this.collection.retainAll(c);
            }
        }
        
        @Override
        public boolean removeIf(final IntPredicate filter) {
            synchronized (this.sync) {
                return this.collection.removeIf(filter);
            }
        }
        
        @Override
        public void clear() {
            synchronized (this.sync) {
                this.collection.clear();
            }
        }
        
        @Override
        public String toString() {
            synchronized (this.sync) {
                return this.collection.toString();
            }
        }
        
        @Override
        public int hashCode() {
            synchronized (this.sync) {
                return this.collection.hashCode();
            }
        }
        
        @Override
        public boolean equals(final Object o) {
            if (o == this) {
                return true;
            }
            synchronized (this.sync) {
                return this.collection.equals(o);
            }
        }
        
        private void writeObject(final ObjectOutputStream s) throws IOException {
            synchronized (this.sync) {
                s.defaultWriteObject();
            }
        }
    }
    
    static class UnmodifiableCollection implements IntCollection, Serializable
    {
        private static final long serialVersionUID = -7046029254386353129L;
        protected final IntCollection collection;
        
        protected UnmodifiableCollection(final IntCollection c) {
            this.collection = Objects.requireNonNull(c);
        }
        
        @Override
        public boolean add(final int k) {
            throw new UnsupportedOperationException();
        }
        
        @Override
        public boolean rem(final int k) {
            throw new UnsupportedOperationException();
        }
        
        @Override
        public int size() {
            return this.collection.size();
        }
        
        @Override
        public boolean isEmpty() {
            return this.collection.isEmpty();
        }
        
        @Override
        public boolean contains(final int o) {
            return this.collection.contains(o);
        }
        
        @Override
        public IntIterator iterator() {
            return IntIterators.unmodifiable(this.collection.iterator());
        }
        
        @Override
        public IntSpliterator spliterator() {
            return this.collection.spliterator();
        }
        
        @Deprecated
        @Override
        public Stream<Integer> stream() {
            return this.collection.stream();
        }
        
        @Deprecated
        @Override
        public Stream<Integer> parallelStream() {
            return this.collection.parallelStream();
        }
        
        @Override
        public void clear() {
            throw new UnsupportedOperationException();
        }
        
        @Override
        public <T> T[] toArray(final T[] a) {
            return this.collection.toArray(a);
        }
        
        @Override
        public Object[] toArray() {
            return this.collection.toArray();
        }
        
        @Override
        public void forEach(final IntConsumer action) {
            this.collection.forEach(action);
        }
        
        @Override
        public boolean containsAll(final Collection<?> c) {
            return this.collection.containsAll(c);
        }
        
        @Override
        public boolean addAll(final Collection<? extends Integer> c) {
            throw new UnsupportedOperationException();
        }
        
        @Override
        public boolean removeAll(final Collection<?> c) {
            throw new UnsupportedOperationException();
        }
        
        @Override
        public boolean retainAll(final Collection<?> c) {
            throw new UnsupportedOperationException();
        }
        
        @Override
        public boolean removeIf(final IntPredicate filter) {
            throw new UnsupportedOperationException();
        }
        
        @Deprecated
        @Override
        public boolean add(final Integer k) {
            throw new UnsupportedOperationException();
        }
        
        @Deprecated
        @Override
        public boolean contains(final Object k) {
            return this.collection.contains(k);
        }
        
        @Deprecated
        @Override
        public boolean remove(final Object k) {
            throw new UnsupportedOperationException();
        }
        
        @Override
        public int[] toIntArray() {
            return this.collection.toIntArray();
        }
        
        @Deprecated
        @Override
        public int[] toIntArray(final int[] a) {
            return this.toArray(a);
        }
        
        @Override
        public int[] toArray(final int[] a) {
            return this.collection.toArray(a);
        }
        
        @Override
        public boolean containsAll(final IntCollection c) {
            return this.collection.containsAll(c);
        }
        
        @Override
        public boolean addAll(final IntCollection c) {
            throw new UnsupportedOperationException();
        }
        
        @Override
        public boolean removeAll(final IntCollection c) {
            throw new UnsupportedOperationException();
        }
        
        @Override
        public boolean retainAll(final IntCollection c) {
            throw new UnsupportedOperationException();
        }
        
        @Override
        public IntIterator intIterator() {
            return this.collection.intIterator();
        }
        
        @Override
        public IntSpliterator intSpliterator() {
            return this.collection.intSpliterator();
        }
        
        @Override
        public IntStream intStream() {
            return this.collection.intStream();
        }
        
        @Override
        public IntStream intParallelStream() {
            return this.collection.intParallelStream();
        }
        
        @Override
        public String toString() {
            return this.collection.toString();
        }
        
        @Override
        public int hashCode() {
            return this.collection.hashCode();
        }
        
        @Override
        public boolean equals(final Object o) {
            return o == this || this.collection.equals(o);
        }
    }
    
    public static class IterableCollection extends AbstractIntCollection implements Serializable
    {
        private static final long serialVersionUID = -7046029254386353129L;
        protected final IntIterable iterable;
        
        protected IterableCollection(final IntIterable iterable) {
            this.iterable = Objects.requireNonNull(iterable);
        }
        
        @Override
        public int size() {
            final long size = this.iterable.spliterator().getExactSizeIfKnown();
            if (size >= 0L) {
                return (int)Math.min(2147483647L, size);
            }
            int c = 0;
            final IntIterator iterator = this.iterator();
            while (iterator.hasNext()) {
                iterator.nextInt();
                ++c;
            }
            return c;
        }
        
        @Override
        public boolean isEmpty() {
            return !this.iterable.iterator().hasNext();
        }
        
        @Override
        public IntIterator iterator() {
            return this.iterable.iterator();
        }
        
        @Override
        public IntSpliterator spliterator() {
            return this.iterable.spliterator();
        }
        
        @Override
        public IntIterator intIterator() {
            return this.iterable.intIterator();
        }
        
        @Override
        public IntSpliterator intSpliterator() {
            return this.iterable.intSpliterator();
        }
    }
    
    static class SizeDecreasingSupplier<C extends IntCollection> implements Supplier<C>
    {
        static final int RECOMMENDED_MIN_SIZE = 8;
        final AtomicInteger suppliedCount;
        final int expectedFinalSize;
        final IntFunction<C> builder;
        
        SizeDecreasingSupplier(final int expectedFinalSize, final IntFunction<C> builder) {
            this.suppliedCount = new AtomicInteger(0);
            this.expectedFinalSize = expectedFinalSize;
            this.builder = builder;
        }
        
        @Override
        public C get() {
            int expectedNeededNextSize = 1 + (this.expectedFinalSize - 1) / this.suppliedCount.incrementAndGet();
            if (expectedNeededNextSize < 0) {
                expectedNeededNextSize = 8;
            }
            return this.builder.apply(expectedNeededNextSize);
        }
    }
}
