Ranides Atterwim 4 лет назад
Родитель
Сommit
81f82dacbe

+ 5 - 0
assira.core/src/main/java/net/ranides/assira/annotations/Meta.java

@@ -63,6 +63,10 @@ public final class Meta {
     @Documented
     @Documented
     public @interface Immutable {
     public @interface Immutable {
 
 
+        /**
+         * Mark this class as immutable, but not thread-safe
+         * @return bool
+         */
         boolean threadsafe() default true;
         boolean threadsafe() default true;
 
 
     }
     }
@@ -169,6 +173,7 @@ public final class Meta {
     public @interface Dynamic {
     public @interface Dynamic {
         /**
         /**
          * List of runtime systems using annotated method or field.
          * List of runtime systems using annotated method or field.
+         * @return strings
          */
          */
         String[] system() default {""};
         String[] system() default {""};
     }
     }

+ 12 - 1
assira.core/src/main/java/net/ranides/assira/collection/BlockCollection.java

@@ -9,6 +9,11 @@ package net.ranides.assira.collection;
 import java.util.Collection;
 import java.util.Collection;
 
 
 /**
 /**
+ * Collections implementing this interface stores data inside one memory block.
+ * Altough it isn't so relevant from memory locality perspective (because JVM uses managed heap),
+ * it is if we want make assumptions about potential reallocations inside collections.
+ *
+ * Offers few methods for space management: we can check allocated capacity, reserve memory or free unused.
  *
  *
  * @author Ranides Atterwim {@literal <ranides@gmail.com>}
  * @author Ranides Atterwim {@literal <ranides@gmail.com>}
  */
  */
@@ -21,7 +26,13 @@ public interface BlockCollection<T> extends Collection<T> {
      * @return true if there was enough memory to reallocate the collection.
      * @return true if there was enough memory to reallocate the collection.
      */
      */
     boolean reserve(int capacity);
     boolean reserve(int capacity);
-    
+
+    /**
+     * Returns size of block allocated by collection.
+     * Collection shouldn't reallocate on next insertions as long as "size" is lower than "capacity"
+     *
+     * @return int
+     */
     int capacity();
     int capacity();
 
 
     /**
     /**

+ 103 - 13
assira.core/src/main/java/net/ranides/assira/collection/CollectionUtils.java

@@ -7,6 +7,7 @@
 
 
 package net.ranides.assira.collection;
 package net.ranides.assira.collection;
 
 
+import lombok.experimental.UtilityClass;
 import net.ranides.assira.collection.iterators.IteratorUtils;
 import net.ranides.assira.collection.iterators.IteratorUtils;
 import net.ranides.assira.functional.covariant.ProjectionFunction;
 import net.ranides.assira.functional.covariant.ProjectionFunction;
 
 
@@ -15,31 +16,79 @@ import java.util.function.Function;
 import java.util.function.Predicate;
 import java.util.function.Predicate;
 
 
 /**
 /**
+ * Static methods working with Collection interface.
  *
  *
  * @author Ranides Atterwim {@literal <ranides@gmail.com>}
  * @author Ranides Atterwim {@literal <ranides@gmail.com>}
  */
  */
+@UtilityClass
 public final class CollectionUtils {
 public final class CollectionUtils {
-	
-	private CollectionUtils() {
-		/* utility class */
-	}
-	
+
+	/**
+	 * Returns first element inside collection, or none if collection is empty.
+	 * It uses iterator, so it respects ordering.
+	 *
+	 * @param values values
+	 * @param <T> T
+	 * @return optional
+	 */
 	public static <T> Optional<T> first(Collection<? extends T> values) {
 	public static <T> Optional<T> first(Collection<? extends T> values) {
 		return IteratorUtils.first(values.iterator());
 		return IteratorUtils.first(values.iterator());
 	}
 	}
-	
+
+	/**
+	 * Returns first element inside collection which satisfies predicate.
+	 * Returns none if collection is empty or no element was accepted by predicate.
+	 * It uses iterator, so it respects ordering.
+	 *
+	 * @param values values
+	 * @param predicate predicate
+	 * @param <T> T
+	 * @return optional
+	 */
 	public static <T> Optional<T> first(Collection<? extends T> values, Predicate<? super T> predicate) {
 	public static <T> Optional<T> first(Collection<? extends T> values, Predicate<? super T> predicate) {
 		return IteratorUtils.first(values.iterator(), predicate);
 		return IteratorUtils.first(values.iterator(), predicate);
 	}
 	}
-	
+
+	/**
+	 * Returns last element inside collection, or none if collection is empty.
+	 * It uses iterator, so it respects order, but it must traverse whole collection.
+	 * If you can, lets try ListUtils.
+	 *
+	 * @param values values
+	 * @param <T> T
+	 * @return optional
+	 */
 	public static <T> Optional<T> last(Collection<? extends T> values) {
 	public static <T> Optional<T> last(Collection<? extends T> values) {
 		return IteratorUtils.last(values.iterator());
 		return IteratorUtils.last(values.iterator());
 	}
 	}
-	
+
+	/**
+	 * Returns last element inside collection which satisfies predicate.
+	 * Returns none if collection is empty or no element was accepted by predicate.
+	 * It uses iterator, so it respects order, but it must traverse whole collection.
+	 * If you can, lets try ListUtils.
+	 *
+	 * @param values values
+	 * @param predicate predicate
+	 * @param <T> T
+	 * @return optional
+	 */
 	public static <T> Optional<T> last(Collection<? extends T> values, Predicate<? super T> predicate) {
 	public static <T> Optional<T> last(Collection<? extends T> values, Predicate<? super T> predicate) {
 		return IteratorUtils.last(values.iterator(), predicate);
 		return IteratorUtils.last(values.iterator(), predicate);
 	}
 	}
-	
+
+	/**
+	 * Returns filtered read-only view of provided collection.
+	 * Changes introduced to source collection are visible in view.
+	 *
+	 * It is implemented on top of iterator, so it respects order.
+	 * It has effective implementation of {@code contains}, so it can be used to filter  Sets.
+	 *
+	 * @param values values
+	 * @param predicate predicate
+	 * @param <T> T
+	 * @return view
+	 */
     @SuppressWarnings("unchecked")
     @SuppressWarnings("unchecked")
 	public static <T> Collection<T> filter(Collection<? extends T> values, Predicate<? super T> predicate) {
 	public static <T> Collection<T> filter(Collection<? extends T> values, Predicate<? super T> predicate) {
 		return new ACollection<T>() {
 		return new ACollection<T>() {
@@ -59,7 +108,20 @@ public final class CollectionUtils {
 			}
 			}
 		};
 		};
 	}
 	}
-	
+
+	/**
+	 * Returns read-only view which maps every element using provided function.
+	 * Changes introduced to source collection are visible in view.
+	 *
+	 * It is implemented on top of iterator, so it respects order.
+	 * It does not provide effective implementation of {@code contains} method.
+	 *
+	 * @param values values
+	 * @param function function
+	 * @param <S> source type
+	 * @param <T> target type
+	 * @return view
+	 */
 	public static <S,T> Collection<T> map(Collection<? extends S> values, Function<? super S,? extends T> function) {
 	public static <S,T> Collection<T> map(Collection<? extends S> values, Function<? super S,? extends T> function) {
         return new ACollection<T>() {
         return new ACollection<T>() {
 			@Override
 			@Override
@@ -72,8 +134,22 @@ public final class CollectionUtils {
 			}
 			}
 		};
 		};
     }
     }
-    
-    public static <S,T> Collection<T> map(Collection<S> values, ProjectionFunction<S,T> function) {
+
+	/**
+	 * Returns mutable view which maps every element using provided projection.
+	 * Changes introduced to source collection are visible in view and vice versa.
+	 *
+	 * It is implemented on top of iterator, so it respects order.
+	 * It has effective implementation of {@code contains}, so it can be used to filter Sets.
+	 * It allows removing and adding new elements.
+	 *
+	 * @param values values
+	 * @param function function
+	 * @return view
+	 * @param <S> source type
+	 * @param <T> target type
+	 */
+	public static <S,T> Collection<T> map(Collection<S> values, ProjectionFunction<S,T> function) {
         return new ACollection<T>() {
         return new ACollection<T>() {
 			@Override
 			@Override
 			public Iterator<T> iterator() {
 			public Iterator<T> iterator() {
@@ -115,7 +191,21 @@ public final class CollectionUtils {
             
             
 		};
 		};
     }
     }
-    
+
+	/**
+	 * Checks if provided collections contain equal elements.
+	 * Ignores order of elements.
+	 * It tries to avoid O(N*N) comparisons.
+	 * It uses {@code containsAll} if one of collection is Set.
+	 *
+     * It converts collections to sorted arrays in general case.
+	 * It uses natural sort, which means that T must be Comparable if none collection is Set.
+	 *
+	 * @param a a
+	 * @param b b
+	 * @param <T> T
+	 * @return bool
+	 */
     public static <T> boolean equivalent(Collection<? extends T> a, Collection<? extends T> b) {
     public static <T> boolean equivalent(Collection<? extends T> a, Collection<? extends T> b) {
 		if( a.size() != b.size() ){
 		if( a.size() != b.size() ){
             return false;
             return false;

+ 137 - 11
assira.core/src/main/java/net/ranides/assira/collection/IntCollectionUtils.java

@@ -8,38 +8,94 @@
 package net.ranides.assira.collection;
 package net.ranides.assira.collection;
 
 
 import java.util.Arrays;
 import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
 import java.util.Set;
 import java.util.Set;
 import java.util.function.IntPredicate;
 import java.util.function.IntPredicate;
 import java.util.function.IntUnaryOperator;
 import java.util.function.IntUnaryOperator;
+
+import lombok.experimental.UtilityClass;
 import net.ranides.assira.collection.iterators.IntIterator;
 import net.ranides.assira.collection.iterators.IntIterator;
 import net.ranides.assira.collection.iterators.IntIteratorUtils;
 import net.ranides.assira.collection.iterators.IntIteratorUtils;
+import net.ranides.assira.collection.iterators.IteratorUtils;
+import net.ranides.assira.functional.covariant.IntProjectionFunction;
+import net.ranides.assira.functional.covariant.ProjectionFunction;
 
 
 /**
 /**
+ * Static methods working with IntCollection interface.
+ * Generally, empty result is signalled by throwing exception because
+ * we try to avoid boxing operations or OptionalInt wrappers.
  *
  *
  * @author Ranides Atterwim {@literal <ranides@gmail.com>}
  * @author Ranides Atterwim {@literal <ranides@gmail.com>}
  */
  */
+@UtilityClass
 public final class IntCollectionUtils {
 public final class IntCollectionUtils {
-	
-	private IntCollectionUtils() {
-		/* utility class */
-	}
-	
+
+	/**
+	 * Returns first element inside collection, or throws if collection is empty.
+	 * It uses iterator, so it respects ordering.
+	 *
+	 * @param values values
+	 * @return int
+	 * @throws java.util.NoSuchElementException if no result
+	 */
 	public static int first(IntCollection values) {
 	public static int first(IntCollection values) {
 		return IntIteratorUtils.first(values.iterator());
 		return IntIteratorUtils.first(values.iterator());
 	}
 	}
-	
+
+	/**
+	 * Returns first element inside collection which satisfies predicate.
+	 * Throws if collection is empty or no element was accepted by predicate.
+	 * It uses iterator, so it respects ordering.
+	 *
+	 * @param values values
+	 * @param predicate predicate
+	 * @return int
+	 * @throws java.util.NoSuchElementException if no result
+	 */
 	public static int first(IntCollection values, IntPredicate predicate) {
 	public static int first(IntCollection values, IntPredicate predicate) {
 		return IntIteratorUtils.first(values.iterator(), predicate);
 		return IntIteratorUtils.first(values.iterator(), predicate);
 	}
 	}
-	
+
+	/**
+	 * Returns last element inside collection, or throws if collection is empty.
+	 * It uses iterator, so it respects order, but it must traverse whole collection.
+	 * If you can, lets try IntListUtils.
+	 *
+	 * @param values values
+	 * @return int
+	 * @throws java.util.NoSuchElementException if no result
+	 */
 	public static int last(IntCollection values) {
 	public static int last(IntCollection values) {
 		return IntIteratorUtils.last(values.iterator());
 		return IntIteratorUtils.last(values.iterator());
 	}
 	}
-	
+
+	/**
+	 * Returns last element inside collection which satisfies predicate.
+	 * Throws if collection is empty or no element was accepted by predicate.
+	 * It uses iterator, so it respects order, but it must traverse whole collection.
+	 * If you can, lets try IntListUtils.
+	 *
+	 * @param values values
+	 * @param predicate predicate
+	 * @return int
+	 * @throws java.util.NoSuchElementException if no result
+	 */
 	public static int last(IntCollection values, IntPredicate predicate) {
 	public static int last(IntCollection values, IntPredicate predicate) {
 		return IntIteratorUtils.last(values.iterator(), predicate);
 		return IntIteratorUtils.last(values.iterator(), predicate);
 	}
 	}
-	
+
+	/**
+	 * Returns filtered read-only view of provided IntCollection.
+	 * Changes introduced to source collection are visible in view.
+	 *
+	 * It is implemented on top of IntIterator, so it respects order.
+	 * It has effective implementation of {@code contains}, so it can be used to filter IntSets.
+	 *
+	 * @param values values
+	 * @param predicate predicate
+	 * @return view
+	 */
 	public static IntCollection filter(IntCollection values, IntPredicate predicate) {
 	public static IntCollection filter(IntCollection values, IntPredicate predicate) {
 		return new AIntCollection() {
 		return new AIntCollection() {
 			@Override
 			@Override
@@ -58,8 +114,22 @@ public final class IntCollectionUtils {
 			}
 			}
 		};
 		};
 	}
 	}
-	
-    public static <S,T> IntCollection map(IntCollection values, IntUnaryOperator function) {
+
+	/**
+	 * Returns read-only view which maps every element using provided function.
+	 * Changes introduced to source collection are visible in view.
+	 *
+	 * It is implemented on top of iterator, so it respects order.
+	 * It does not provide effective implementation of {@code contains} method.
+	 *
+	 * Please note, that it allows only mapping preserving type "int".
+	 * If you want to map to objects, please use CollectionUtils.
+	 *
+	 * @param values values
+	 * @param function function
+	 * @return view
+	 */
+	public static IntCollection map(IntCollection values, IntUnaryOperator function) {
         return new AIntCollection() {
         return new AIntCollection() {
 			@Override
 			@Override
 			public int size() {
 			public int size() {
@@ -72,6 +142,62 @@ public final class IntCollectionUtils {
 		};
 		};
     }
     }
 
 
+	/**
+	 * Returns mutable view which maps every element using provided projection.
+	 * Changes introduced to source collection are visible in view and vice versa.
+	 *
+	 * It is implemented on top of iterator, so it respects order.
+	 * It has effective implementation of {@code contains}, so it can be used to filter Sets.
+	 * It allows removing and adding new elements.
+	 *
+	 * Please note, that it allows only mapping preserving type "int".
+	 * If you want to map to objects, please use CollectionUtils.
+	 *
+	 * @param values values
+	 * @param function function
+	 * @return view
+	 */
+	public static IntCollection map(IntCollection values, IntProjectionFunction function) {
+		return new AIntCollection() {
+			@Override
+			public IntIterator iterator() {
+				return IntIteratorUtils.map(values.iterator(), function::applyAsInt);
+			}
+			@Override
+			public int size() {
+				return values.size();
+			}
+
+			@Override
+			public boolean rem(int value) {
+				return values.rem(function.invert(value));
+			}
+
+			@Override
+			public boolean add(int value) {
+				return values.add(function.invert(value));
+			}
+
+			@Override
+			public boolean contains(int value) {
+				return values.contains(function.invert(value));
+			}
+
+		};
+	}
+
+	/**
+	 * Checks if provided collections contain equal elements.
+	 * Ignores order of elements.
+	 * It tries to avoid O(N*N) comparisons.
+	 * It uses {@code containsAll} if one of collection is Set.
+	 *
+	 * It converts collections to sorted arrays in general case.
+	 *
+	 * @param a a
+	 * @param b b
+	 * @return bool
+	 */
 	public static boolean equivalent(IntCollection a, IntCollection b) {
 	public static boolean equivalent(IntCollection a, IntCollection b) {
 		if( a.size() != b.size() ){
 		if( a.size() != b.size() ){
             return false;
             return false;

+ 18 - 0
assira.core/src/main/java/net/ranides/assira/collection/arrays/ArrayUtils.java

@@ -40,6 +40,9 @@ public final class ArrayUtils {
      * @param begin the first element of the array to be returned.
      * @param begin the first element of the array to be returned.
      * @param end the maximum number of elements to collect.
      * @param end the maximum number of elements to collect.
      * @return the number of elements unwrapped.
      * @return the number of elements unwrapped.
+     *
+     * @param <A> array
+     * @param <T> component
      */
      */
     public static <A,T> int collect(Iterator<? extends T> iterator, A target, int begin, int end) {
     public static <A,T> int collect(Iterator<? extends T> iterator, A target, int begin, int end) {
         if($isint(target)) {
         if($isint(target)) {
@@ -64,6 +67,9 @@ public final class ArrayUtils {
      * @param iterator a type-specific iterator.
      * @param iterator a type-specific iterator.
      * @param target an array to contain the output of the iterator.
      * @param target an array to contain the output of the iterator.
      * @return the number of elements unwrapped.
      * @return the number of elements unwrapped.
+     *
+     * @param <A> array
+     * @param <T> component
      */
      */
     public static <A,T> int collect(Iterator<? extends T> iterator, A target) {
     public static <A,T> int collect(Iterator<? extends T> iterator, A target) {
         if($isint(target)) {
         if($isint(target)) {
@@ -91,6 +97,9 @@ public final class ArrayUtils {
      *
      *
      * @param array an array.
      * @param array an array.
      * @param value the new value for all elements of the array.
      * @param value the new value for all elements of the array.
+     *
+     * @param <A> array
+     * @param <T> component
      */
      */
     public static <A,T> void fill(A array, T value) {
     public static <A,T> void fill(A array, T value) {
         NativeArrayUtils.fill(NativeArray.wrap(array), value);
         NativeArrayUtils.fill(NativeArray.wrap(array), value);
@@ -109,6 +118,9 @@ public final class ArrayUtils {
      * @param end the end index of the portion to fill (exclusive).
      * @param end the end index of the portion to fill (exclusive).
      * @param value the new value for all elements of the specified portion of
      * @param value the new value for all elements of the specified portion of
      * the array.
      * the array.
+     *
+     * @param <A> array
+     * @param <T> component
      */
      */
     public static <A,T> void fill(A array, int begin, int end, T value) {
     public static <A,T> void fill(A array, int begin, int end, T value) {
         NativeArrayUtils.fill(NativeArray.wrap(array), begin, end, value);
         NativeArrayUtils.fill(NativeArray.wrap(array), begin, end, value);
@@ -121,6 +133,8 @@ public final class ArrayUtils {
      * @param begin begin
      * @param begin begin
      * @param end end
      * @param end end
      * @return {@code a}.
      * @return {@code a}.
+     *
+     * @param <A> array
      */
      */
     public static <A> A reverse(A array, int begin, int end){
     public static <A> A reverse(A array, int begin, int end){
         NativeArrayUtils.reverse(NativeArray.wrap(array), begin, end);
         NativeArrayUtils.reverse(NativeArray.wrap(array), begin, end);
@@ -132,6 +146,8 @@ public final class ArrayUtils {
      *
      *
      * @param array the array to be reversed.
      * @param array the array to be reversed.
      * @return {@code a}.
      * @return {@code a}.
+     *
+     * @param <A> inferred type of array
      */
      */
     public static <A> A reverse(A array) {
     public static <A> A reverse(A array) {
         NativeArrayUtils.reverse(NativeArray.wrap(array));
         NativeArrayUtils.reverse(NativeArray.wrap(array));
@@ -145,6 +161,8 @@ public final class ArrayUtils {
      * @param array2 another array.
      * @param array2 another array.
      * @return true if the two arrays are of the same length, and their elements
      * @return true if the two arrays are of the same length, and their elements
      * are equal.
      * are equal.
+     *
+     * @param <A> inferred type of array
      */
      */
     public static <A> boolean equals(A array1, A array2) {
     public static <A> boolean equals(A array1, A array2) {
         return NativeArrayUtils.equals(NativeArray.wrap(array1), NativeArray.wrap(array2));
         return NativeArrayUtils.equals(NativeArray.wrap(array1), NativeArray.wrap(array2));

+ 241 - 24
assira.core/src/main/java/net/ranides/assira/collection/iterators/IntIteratorUtils.java

@@ -19,6 +19,9 @@ import net.ranides.assira.collection.IntComparator;
 import net.ranides.assira.functional.special.IntBiPredicate;
 import net.ranides.assira.functional.special.IntBiPredicate;
 
 
 /**
 /**
+ * Static methods working with IntIterator interface.
+ * Generally, empty result is signalled by throwing exception because
+ * we try to avoid boxing operations or OptionalInt wrappers.
  *
  *
  * @author Ranides Atterwim {@literal <ranides@gmail.com>}
  * @author Ranides Atterwim {@literal <ranides@gmail.com>}
  */
  */
@@ -27,11 +30,27 @@ public final class IntIteratorUtils {
     private IntIteratorUtils() {
     private IntIteratorUtils() {
         /* utility class */
         /* utility class */
     }
     }
-    
+
+    /**
+     * Returns first element for iterator, or throws if iterator is empty.
+     *
+     * @param iterator iterator
+     * @return int
+     * @throws java.util.NoSuchElementException if no result
+     */
     public static int first(IntIterator iterator) {
     public static int first(IntIterator iterator) {
-		return iterator.next();
+		return iterator.nextInt();
     }
     }
-    
+
+    /**
+     * Returns first element for iterator which satisfies predicate.
+     * Throws if iterator is empty or no element was accepted by predicate.
+     *
+     * @param iterator iterator
+     * @param predicate predicate
+     * @return int
+     * @throws java.util.NoSuchElementException if no result
+     */
     public static int first(IntIterator iterator, IntPredicate predicate) {
     public static int first(IntIterator iterator, IntPredicate predicate) {
 		while(iterator.hasNext()) {
 		while(iterator.hasNext()) {
             int v = iterator.nextInt();
             int v = iterator.nextInt();
@@ -41,7 +60,16 @@ public final class IntIteratorUtils {
         }
         }
         throw new NoSuchElementException();
         throw new NoSuchElementException();
     }
     }
-    
+
+    /**
+     * Returns last element for iterator, or throws if iterator is empty.
+     * It must traverse whole collection.
+     * If you can, lets try IntListUtils.
+     *
+     * @param iterator iterator
+     * @return int
+     * @throws java.util.NoSuchElementException if no result
+     */
     public static int last(IntIterator iterator) {
     public static int last(IntIterator iterator) {
         int result;
         int result;
 		do {
 		do {
@@ -50,7 +78,18 @@ public final class IntIteratorUtils {
         return result;
         return result;
 		
 		
     }
     }
-    
+
+    /**
+     * Returns last element for iterator which satisfies predicate.
+     * Throws if iterator is empty or no element was accepted by predicate.
+     * It must traverse whole collection.
+     * If you can, lets try IntListUtils.
+     *
+     * @param iterator iterator
+     * @param predicate predicate
+     * @return int
+     * @throws java.util.NoSuchElementException if no result
+     */
     public static int last(IntIterator iterator, IntPredicate predicate) {
     public static int last(IntIterator iterator, IntPredicate predicate) {
         Integer result = null;
         Integer result = null;
         while(iterator.hasNext()) { 
         while(iterator.hasNext()) { 
@@ -65,6 +104,17 @@ public final class IntIteratorUtils {
         return result;
         return result;
     }
     }
 
 
+    /**
+     * Returns element at specified position.
+     * Throws if iterator contains less elements.
+     * It must traverse through all previous elements.
+     * If you can, lets try IntListUtils.
+     *
+     * @param iterator iterator
+     * @param index index
+     * @return int
+     * @throws java.util.NoSuchElementException if no result
+     */
     public static int at(IntIterator iterator, int index) {
     public static int at(IntIterator iterator, int index) {
         for(int i=0; i<index; i++) {
         for(int i=0; i<index; i++) {
             if(!iterator.hasNext()) {
             if(!iterator.hasNext()) {
@@ -77,7 +127,14 @@ public final class IntIteratorUtils {
         }
         }
         return iterator.nextInt();
         return iterator.nextInt();
     }
     }
-    
+
+    /**
+     * Counts number of elements for specified iterator.
+     * It must iterate through all elements, if you can, check collection size directly.
+     *
+     * @param iterator iterator
+     * @return int
+     */
     public static int size(IntIterator iterator) {
     public static int size(IntIterator iterator) {
 		if(iterator==null) {
 		if(iterator==null) {
 			return 0;
 			return 0;
@@ -90,61 +147,179 @@ public final class IntIteratorUtils {
         return c;
         return c;
     }
     }
 
 
+    /**
+     * Returns filtered view of provided IntIterator.
+     *
+     * @param iterator iterator
+     * @param predicate predicate
+     * @return iterator view
+     */
     public static IntIterator filter(IntIterator iterator, IntPredicate predicate) {
     public static IntIterator filter(IntIterator iterator, IntPredicate predicate) {
         return new FilterIterator(iterator, predicate, false);
         return new FilterIterator(iterator, predicate, false);
     }
     }
-	
+
+    /**
+     * Returns filtered read-only view of provided IntIterator.
+     * Returned iterator supports backward iteration, but it does not allow modifications.
+     *
+     * @param iterator iterator
+     * @param predicate predicate
+     * @return iterator view
+     */
 	public static IntListIterator filter(IntListIterator iterator, IntPredicate predicate) {
 	public static IntListIterator filter(IntListIterator iterator, IntPredicate predicate) {
         return new FilterListIterator(iterator, predicate, false);
         return new FilterListIterator(iterator, predicate, false);
     }
     }
-    
+
+    /**
+     * Returns read-only view of provided IntIterator.
+     * Limited iterator stops at first unmatched element.
+     *
+     * @param iterator iterator
+     * @param predicate predicate
+     * @return iterator view
+     */
     public static IntIterator limit(IntIterator iterator, IntPredicate predicate) {
     public static IntIterator limit(IntIterator iterator, IntPredicate predicate) {
         return new FilterIterator(iterator, predicate, true);
         return new FilterIterator(iterator, predicate, true);
     }
     }
-	
+
+    /**
+     * Returns read-only view of provided IntIterator.
+     * Limited iterator stops at first unmatched element.
+     * Returned iterator supports backward iteration, but it does not allow modifications.
+     *
+     * @param iterator iterator
+     * @param predicate predicate
+     * @return iterator view
+     */
 	public static IntListIterator limit(IntListIterator iterator, IntPredicate predicate) {
 	public static IntListIterator limit(IntListIterator iterator, IntPredicate predicate) {
         return new FilterListIterator(iterator, predicate, true);
         return new FilterListIterator(iterator, predicate, true);
     }
     }
-	
+
+    /**
+     * Returns read-only view of iterator which maps every element using provided function.
+     *
+     * Please note, that it allows mapping to any object.
+     *
+     * @param iterator iterator
+     * @param function function
+     * @param <T> target
+     * @return iterator view
+     */
 	public static <T> Iterator<T> map(IntIterator iterator, IntFunction<T> function) {
 	public static <T> Iterator<T> map(IntIterator iterator, IntFunction<T> function) {
         return new Adapter<>(iterator, function);
         return new Adapter<>(iterator, function);
     }
     }
-    
+
+    /**
+     * Returns read-only view of iterator which maps every element using provided function.
+     *
+     * Please note, that it allows only mapping preserving type "int".
+     *
+     * @param iterator iterator
+     * @param function function
+     * @return iterator view
+     */
     public static IntIterator map(IntIterator iterator, IntUnaryOperator function) {
     public static IntIterator map(IntIterator iterator, IntUnaryOperator function) {
         return new IntAdapter(iterator, function);
         return new IntAdapter(iterator, function);
     }
     }
-    
+
+    /**
+     * Returns read-only view of iterator which maps every element using provided function.
+     * Returned iterator supports backward iteration, but it does not allow modifications.
+     *
+     * Please note, that it allows mapping to any object.
+     *
+     * @param iterator iterator
+     * @param function function
+     * @param <T> target
+     * @return iterator view
+     */
     public static <T> ListIterator<T> map(IntListIterator iterator, IntFunction<T> function) {
     public static <T> ListIterator<T> map(IntListIterator iterator, IntFunction<T> function) {
         return new ListAdapter<>(iterator, function);
         return new ListAdapter<>(iterator, function);
     }
     }
 
 
+    /**
+     * Returns read-only view of iterator which maps every element using provided function.
+     * Returned iterator supports backward iteration, but it does not allow modifications.
+     *
+     * Please note, that it allows only mapping preserving type "int".
+     *
+     * @param iterator iterator
+     * @param function function
+     * @return iterator view
+     */
     public static IntListIterator map(IntListIterator iterator, IntUnaryOperator function) {
     public static IntListIterator map(IntListIterator iterator, IntUnaryOperator function) {
         return new IntListAdapter(iterator, function);
         return new IntListAdapter(iterator, function);
     }
     }
-    
+
+    /**
+     * Returns view which lazily expands all nested IntIterators and merges into one iterator.
+     * Flat iterators move forward only as much as necessary (which means one element at time).
+     *
+     * @param iterator iterator
+     * @return iterator view
+     */
     public static IntIterator flat(Iterator<IntIterator> iterator) {
     public static IntIterator flat(Iterator<IntIterator> iterator) {
         return new IntFlatIterator(iterator);
         return new IntFlatIterator(iterator);
     }
     }
-    
+
+    /**
+     * Creates sequential IntStream from provided iterator.
+     *
+     * @param iterator iterator
+     * @return stream
+     */
     public static IntStream stream(IntIterator iterator) {
     public static IntStream stream(IntIterator iterator) {
 		return StreamSupport.intStream(new IntSpliterator(iterator), false);
 		return StreamSupport.intStream(new IntSpliterator(iterator), false);
 	}
 	}
 
 
+    /**
+     * Returns view which lazily expands all provided IntIterators and merges into one iterator.
+     * Flat iterators move forward only as much as necessary (which means one element at time).
+     *      
+     * @param iterators iterators 
+     * @return iterator
+     * @see #flat
+     */
     public static IntIterator concat(IntIterator... iterators) {
     public static IntIterator concat(IntIterator... iterators) {
         return flat(Arrays.asList(iterators).iterator());
         return flat(Arrays.asList(iterators).iterator());
     }
     }
-    
+
+    /**
+     * Inserts all elements returned by iterator into provided collection.
+     *
+     * @param iterator iterator
+     * @param target target
+     * @param <C> C
+     * @return target
+     */
     public static <C extends IntCollection> C collect(IntIterator iterator, C target) {
     public static <C extends IntCollection> C collect(IntIterator iterator, C target) {
         while(iterator.hasNext()) {
         while(iterator.hasNext()) {
             target.add(iterator.next());
             target.add(iterator.next());
         }
         }
         return target;
         return target;
 	}
 	}
-    
+
+    /**
+     * Creates mutable iterator which runs in reversed order.
+     * It supports removing elements.
+     *
+     * Please note, that input iterator must be correctly rewinded before use.
+     *
+     * @param iterator iterator
+     * @return iterator view
+     */
     public static IntIterator reverse(IntListIterator iterator) {
     public static IntIterator reverse(IntListIterator iterator) {
 		return new IntIteratorUtils.ReverseIterator(iterator);
 		return new IntIteratorUtils.ReverseIterator(iterator);
 	}
 	}
-    
+
+    /**
+     * Tries to skip "count" elements.
+     * Returns number of successfully skipped elements.
+     *
+     * @param iterator iterator
+     * @param count count
+     * @return int
+     */
 	public static int next(IntIterator iterator, int count) {
 	public static int next(IntIterator iterator, int count) {
 		int i=0;
 		int i=0;
 		for(; i<count && iterator.hasNext(); i++) {
 		for(; i<count && iterator.hasNext(); i++) {
@@ -152,11 +327,28 @@ public final class IntIteratorUtils {
 		}
 		}
 		return i;
 		return i;
 	}
 	}
-    
+
+    /**
+     * Checks if provided iterators contain equal elements.
+     * Order of elements is important.
+     *
+     * @param a a
+     * @param b b
+     * @return bool
+     */
     public static boolean equals(IntIterator a, IntIterator b) {
     public static boolean equals(IntIterator a, IntIterator b) {
         return equals(a, b, (p,q) -> p==q);
         return equals(a, b, (p,q) -> p==q);
     }
     }
-    
+
+    /**
+     * Checks if provided iterators contain equal elements using provided comparison function.
+     * Order of elements is important.
+     *
+     * @param a a
+     * @param b b
+     * @param predicate predicate
+     * @return bool
+     */
     public static boolean equals(IntIterator a, IntIterator b, IntBiPredicate predicate) {
     public static boolean equals(IntIterator a, IntIterator b, IntBiPredicate predicate) {
         while(a.hasNext() && b.hasNext()) {
         while(a.hasNext() && b.hasNext()) {
             if( !predicate.test(a.nextInt(), b.nextInt())) {
             if( !predicate.test(a.nextInt(), b.nextInt())) {
@@ -165,12 +357,31 @@ public final class IntIteratorUtils {
         }
         }
         return !a.hasNext() && !b.hasNext();
         return !a.hasNext() && !b.hasNext();
     }
     }
-    
-    public static <T> int compare(IntIterator a, IntIterator b) {
+
+    /**
+     * Checks if provided iterators contain equal elements.
+     * Order of elements is important.
+     * It is three-value version, which returns +1, 0, -1
+     *
+     * @param a a
+     * @param b b
+     * @return int
+     */
+    public static int compare(IntIterator a, IntIterator b) {
         return compare(a, b, Integer::compare);
         return compare(a, b, Integer::compare);
     }
     }
-    
-    public static <T> int compare(IntIterator a, IntIterator b, IntComparator cmp) {
+
+    /**
+     * Checks if provided iterators contain equal elements using provided comparison function.
+     * Order of elements is important.
+     * It is three-value version, which returns +1, 0, -1
+     *
+     * @param a a
+     * @param b b
+     * @param cmp cmp
+     * @return int
+     */
+    public static int compare(IntIterator a, IntIterator b, IntComparator cmp) {
         while(a.hasNext() && b.hasNext()) {
         while(a.hasNext() && b.hasNext()) {
             int icmp = cmp.compare(a.nextInt(), b.nextInt());
             int icmp = cmp.compare(a.nextInt(), b.nextInt());
             if(icmp !=0) {
             if(icmp !=0) {
@@ -179,7 +390,13 @@ public final class IntIteratorUtils {
         }
         }
         return a.hasNext() ? +1 : b.hasNext() ? -1 : 0;
         return a.hasNext() ? +1 : b.hasNext() ? -1 : 0;
     }
     }
-    
+
+    /**
+     * Iterates through all values and removes every element which is matched by predicate.
+     *
+     * @param iterator iterator
+     * @param predicate predicate
+     */
     public static void remove(IntIterator iterator, IntPredicate predicate) {
     public static void remove(IntIterator iterator, IntPredicate predicate) {
         while(iterator.hasNext()) {
         while(iterator.hasNext()) {
             int v = iterator.next();
             int v = iterator.next();

+ 256 - 16
assira.core/src/main/java/net/ranides/assira/collection/iterators/IterableUtils.java

@@ -6,6 +6,7 @@
  */
  */
 package net.ranides.assira.collection.iterators;
 package net.ranides.assira.collection.iterators;
 
 
+import lombok.experimental.UtilityClass;
 import net.ranides.assira.functional.Functions.EachFunction;
 import net.ranides.assira.functional.Functions.EachFunction;
 import net.ranides.assira.functional.checked.CheckedSupplier;
 import net.ranides.assira.functional.checked.CheckedSupplier;
 import net.ranides.assira.generic.CompareUtils;
 import net.ranides.assira.generic.CompareUtils;
@@ -21,105 +22,344 @@ import java.util.stream.Stream;
  *
  *
  * @author Ranides Atterwim {@literal <ranides@gmail.com>}
  * @author Ranides Atterwim {@literal <ranides@gmail.com>}
  */
  */
+@UtilityClass
 public final class IterableUtils {
 public final class IterableUtils {
 
 
-    private IterableUtils() {
-        /* utility class */
-    }
-    
+    /**
+     * Returns first element inside collection, or none if collection is empty.
+     *
+     * @param values values
+     * @param <T> T
+     * @return optional
+     */
     public static <T> Optional<T> first(Iterable<? extends T> values) {
     public static <T> Optional<T> first(Iterable<? extends T> values) {
         return IteratorUtils.first(values.iterator());
         return IteratorUtils.first(values.iterator());
     }
     }
-    
+
+    /**
+     * Returns first element inside collection which satisfies predicate.
+     * Returns none if collection is empty or no element was accepted by predicate.
+     *
+     * @param values values
+     * @param predicate predicate
+     * @param <T> T
+     * @return optional
+     */
     public static <T> Optional<T> first(Iterable<? extends T> values, Predicate<? super T> predicate) {
     public static <T> Optional<T> first(Iterable<? extends T> values, Predicate<? super T> predicate) {
         return IteratorUtils.first(values.iterator(), predicate);
         return IteratorUtils.first(values.iterator(), predicate);
     }
     }
-    
+
+    /**
+     * Returns last element inside collection, or none if collection is empty.
+     * It uses iterator, so it respects order, but it must traverse whole collection.
+     * If you can, lets try ListUtils.
+     *
+     * @param values values
+     * @param <T> T
+     * @return optional
+     */
     public static <T> Optional<T> last(Iterable<? extends T> values) {
     public static <T> Optional<T> last(Iterable<? extends T> values) {
         return IteratorUtils.last(values.iterator());
         return IteratorUtils.last(values.iterator());
     }
     }
 
 
+    /**
+     * Returns element at specified position or none if collection contains less elements.
+     * It must traverse through all previous elements.
+     * If you can, lets try ListUtils.
+     *
+     * @param values values
+     * @param index index
+     * @param <T> T
+     * @return optional
+     */
     public static <T> Optional<T> at(Iterable<? extends T> values, int index) {
     public static <T> Optional<T> at(Iterable<? extends T> values, int index) {
         return IteratorUtils.at(values.iterator(), index);
         return IteratorUtils.at(values.iterator(), index);
     }
     }
-    
+
+    /**
+     * Returns last element inside collection which satisfies predicate.
+     * Returns none if collection is empty or no element was accepted by predicate.
+     * It uses iterator, so it respects order, but it must traverse whole collection.
+     * If you can, lets try ListUtils.
+     *
+     * @param values values
+     * @param predicate predicate
+     * @param <T> T
+     * @return optional
+     */
     public static <T> Optional<T> last(Iterable<? extends T> values, Predicate<? super T> predicate) {
     public static <T> Optional<T> last(Iterable<? extends T> values, Predicate<? super T> predicate) {
         return IteratorUtils.last(values.iterator(), predicate);
         return IteratorUtils.last(values.iterator(), predicate);
     }
     }
-    
+
+    /**
+     * Counts number of elements for specified collection.
+     * It must iterate through all elements, so if you can, check collection size directly.
+     *
+     * @param values values
+     * @return int
+     */
     public static int size(Iterable<?> values) {
     public static int size(Iterable<?> values) {
         return IteratorUtils.size(values.iterator());
         return IteratorUtils.size(values.iterator());
     }
     }
 
 
+    /**
+     * Returns filtered view of provided collection.
+     * Changes introduced to source collection are visible in view.
+     *
+     * @param values values
+     * @param predicate predicate
+     * @param <T> T
+     * @return view
+     */
     public static <T> Iterable<T> filter(Iterable<? extends T> values, Predicate<? super T> predicate) {
     public static <T> Iterable<T> filter(Iterable<? extends T> values, Predicate<? super T> predicate) {
         return () -> IteratorUtils.filter(values.iterator(), predicate);
         return () -> IteratorUtils.filter(values.iterator(), predicate);
     }
     }
 
 
+    /**
+     * Returns limited view of provided collection.
+     * Limited iterable stops at first unmatched element.
+     *
+     * @param values values
+     * @param predicate predicate
+     * @param <T> T
+     * @return view
+     */
     public static <T> Iterable<T> limit(Iterable<? extends T> values, Predicate<? super T> predicate) {
     public static <T> Iterable<T> limit(Iterable<? extends T> values, Predicate<? super T> predicate) {
         return () -> IteratorUtils.limit(values.iterator(), predicate);
         return () -> IteratorUtils.limit(values.iterator(), predicate);
     }
     }
 
 
+    /**
+     * Returns limited view of provided collection.
+     * Limited iterable returns no more than "limit" elements.
+     *
+     * @param values values
+     * @param limit limit
+     * @param <T> T
+     * @return view
+     */
     public static <T> Iterable<T> limit(Iterable<T> values, int limit) {
     public static <T> Iterable<T> limit(Iterable<T> values, int limit) {
         return () -> IteratorUtils.limit(values.iterator(), limit);
         return () -> IteratorUtils.limit(values.iterator(), limit);
     }
     }
 
 
+    /**
+     * Returns view which maps every element using provided function.
+     * Changes introduced to source collection are visible in view.
+     *
+     * @param values values
+     * @param function function
+     * @param <S> source type
+     * @param <T> target type
+     * @return view
+     */
     public static <S,T> Iterable<T> map(Iterable<? extends S> values, EachFunction<? super S,? extends T> function) {
     public static <S,T> Iterable<T> map(Iterable<? extends S> values, EachFunction<? super S,? extends T> function) {
         return () -> IteratorUtils.map(values.iterator(), function);
         return () -> IteratorUtils.map(values.iterator(), function);
     }
     }
-	
-	public static <S,T> Iterable<T> map(Iterable<? extends S> values, Function<? super S,? extends T> function) {
+
+    /**
+     * Returns view which maps every element using provided function.
+     * Changes introduced to source collection are visible in view.
+     *
+     * @param values values
+     * @param function function
+     * @param <S> source type
+     * @param <T> target type
+     * @return view
+     */
+    public static <S,T> Iterable<T> map(Iterable<? extends S> values, Function<? super S,? extends T> function) {
         return () -> IteratorUtils.map(values.iterator(), function);
         return () -> IteratorUtils.map(values.iterator(), function);
     }
     }
 
 
+    /**
+     * Returns view which lazily expands all nested Iterable and merges into one.
+     * Flat iterators move forward only as much as necessary (which means one element at time).
+     *
+     * @param values values
+     * @param <T> T
+     * @return view
+     */
     public static <T> Iterable<T> flat(Iterable<? extends Iterable<? extends T>> values) {
     public static <T> Iterable<T> flat(Iterable<? extends Iterable<? extends T>> values) {
         return () -> IteratorUtils.flat(map(values, Iterable::iterator).iterator());
         return () -> IteratorUtils.flat(map(values, Iterable::iterator).iterator());
     }
     }
 
 
+    /**
+     * Returns view which lazily expands all nested Iterable and merges into one.
+     * Flat iterators move forward only as much as necessary (which means one element at time).
+     *
+     * @param values values
+     * @param <T> T
+     * @return view
+     */
     @SafeVarargs
     @SafeVarargs
     public static <T> Iterable<T> concat(Iterable<? extends T>... values) {
     public static <T> Iterable<T> concat(Iterable<? extends T>... values) {
         return flat(Arrays.asList(values));
         return flat(Arrays.asList(values));
     }
     }
-    
+
+    /**
+     * Creates new sequential Stream from provided iterable.
+     *
+     * @param values values
+     * @param <T> T
+     * @return stream
+     */
 	public static <T> Stream<T> stream(Iterable<? extends T> values) {
 	public static <T> Stream<T> stream(Iterable<? extends T> values) {
         return IteratorUtils.stream(values.iterator());
         return IteratorUtils.stream(values.iterator());
 	}
 	}
-    
+
+    /**
+     * Inserts all elements from iterable into provided collection.
+     *
+     * @param values values
+     * @param target target
+     * @param <T> T
+     * @param <C> C
+     * @return target
+     */
     public static <T, C extends Collection<? super T>> C collect(Iterable<? extends T> values, C target) {
     public static <T, C extends Collection<? super T>> C collect(Iterable<? extends T> values, C target) {
         return IteratorUtils.collect(values.iterator(), target);
         return IteratorUtils.collect(values.iterator(), target);
 	}
 	}
 
 
+    /**
+     * Checks if provided collections contain equal elements.
+     * Order of elements is important.
+     *
+     * @param a a
+     * @param b b
+     * @param <T> T
+     * @return bool
+     */
     public static <T> boolean equals(Iterable<? extends T> a, Iterable<? extends T> b) {
     public static <T> boolean equals(Iterable<? extends T> a, Iterable<? extends T> b) {
         return equals(a, b, CompareUtils::equals);
         return equals(a, b, CompareUtils::equals);
     }
     }
-    
+
+    /**
+     * Checks if provided collections contain equal elements using provided comparison function.
+     * Order of elements is important.
+     *
+     * @param a a
+     * @param b b
+     * @param predicate predicate
+     * @param <T> T
+     * @return bool
+     */
     public static <T> boolean equals(Iterable<? extends T> a, Iterable<? extends T> b, BiPredicate<? super T,? super T> predicate) {
     public static <T> boolean equals(Iterable<? extends T> a, Iterable<? extends T> b, BiPredicate<? super T,? super T> predicate) {
         return IteratorUtils.equals(a.iterator(), b.iterator(), predicate);
         return IteratorUtils.equals(a.iterator(), b.iterator(), predicate);
     }
     }
-    
+
+    /**
+     * Checks if provided collections contain equal elements.
+     * Order of elements is important.
+     * It is three-value version, which returns +1, 0, -1
+     *
+     * @param a a
+     * @param b b
+     * @param <T> T
+     * @return int
+     */
     public static <T> int compare(Iterable<? extends T> a, Iterable<? extends T> b) {
     public static <T> int compare(Iterable<? extends T> a, Iterable<? extends T> b) {
         return compare(a, b, CompareUtils.comparator());
         return compare(a, b, CompareUtils.comparator());
     }
     }
-    
+
+    /**
+     * Checks if provided collections contain equal elements using provided comparison function.
+     * Order of elements is important.
+     * It is three-value version, which returns +1, 0, -1
+     *
+     * @param a a
+     * @param b b
+     * @param cmp cmp
+     * @param <T> T
+     * @return int
+     */
     public static <T> int compare(Iterable<? extends T> a, Iterable<? extends T> b, Comparator<? super T> cmp) {
     public static <T> int compare(Iterable<? extends T> a, Iterable<? extends T> b, Comparator<? super T> cmp) {
         return IteratorUtils.compare(a.iterator(), b.iterator(), cmp);
         return IteratorUtils.compare(a.iterator(), b.iterator(), cmp);
     }
     }
-    
+
+    /**
+     * Iterates through all values and removes every element which is matched by predicate.
+     *
+     * @param values values
+     * @param predicate predicate
+     * @param <T> T
+     */
     public static <T> void remove(Iterable<? extends T> values, Predicate<? super T> predicate) {
     public static <T> void remove(Iterable<? extends T> values, Predicate<? super T> predicate) {
         IteratorUtils.remove(values.iterator(), predicate);
         IteratorUtils.remove(values.iterator(), predicate);
     }
     }
 
 
+    /**
+     * Creates new collection which returns values generated by provided supplier.
+     * Iterator stops when generator returns "Optional.empty"
+     *
+     * Rethrows all unchecked exceptions from generator.
+     * Wraps by RuntimeException all checked exceptions from generator.
+     *
+     * Probably supplier must be statefull.
+     *
+     * @param generator generator
+     * @param <T> T
+     * @return iterable
+     */
     public static <T> Iterable<T> iterable(CheckedSupplier<Optional<T>, ?> generator) {
     public static <T> Iterable<T> iterable(CheckedSupplier<Optional<T>, ?> generator) {
         return () -> IteratorUtils.finite(generator);
         return () -> IteratorUtils.finite(generator);
     }
     }
 
 
+    /**
+     * Creates safe view of collection which will never throw any exception except NoSuchElementException.
+     * All exceptions are silently ignored.
+     * Behaviour of iterator methods in such case:
+     *  - "hasNext" returns false
+     *  - "next" throws NoSuchElementException
+     *  - "remove" does nothing
+     *
+     * @param values values
+     * @param <T> T
+     * @return iterable
+     */
     public static <T> Iterable<T> safe(Iterable<T> values) {
     public static <T> Iterable<T> safe(Iterable<T> values) {
         return safe(values, Exception.class, e -> {});
         return safe(values, Exception.class, e -> {});
     }
     }
 
 
+    /**
+     * Creates safe view of collection which will never throw exception of specified "type".
+     * Exceptions of "type" are silently ignored.
+     * Behaviour of iterator methods in such case:
+     *   - "hasNext" returns false
+     *   - "next" throws NoSuchElementException
+     *   - "remove" does nothing
+     *
+     * Please note, that other exceptions still will be propagated without change.
+     *
+     * Please note, that NoSuchElementException will be thrown as usuall.
+     *
+     * @param values values
+     * @param type exception to ignore
+     * @param <T> T
+     * @param <E> E
+     * @return iterable
+     */
     public static <T, E extends Throwable> Iterable<T> safe(Iterable<T> values, Class<E> type) {
     public static <T, E extends Throwable> Iterable<T> safe(Iterable<T> values, Class<E> type) {
         return safe(values, type, e -> {});
         return safe(values, type, e -> {});
     }
     }
 
 
+    /**
+     * Creates safe view of collection which will never throw exception of specified "type".
+     * Exceptions of "type" are sent to handler.
+     *
+     * Behaviour of iterator methods in such case:
+     *   - "hasNext" returns false
+     *   - "next" throws NoSuchElementException
+     *   - "remove" does nothing
+     *
+     * Please note, that other exceptions still will be propagated without change.
+     *
+     * Please note, that NoSuchElementException will be thrown as usuall.
+     *
+     * @param values values
+     * @param type exception to ignore
+     * @param handler handler
+     * @param <T> T
+     * @param <E> E
+     * @return iterable
+     */
     public static <T, E extends Throwable> Iterable<T> safe(Iterable<T> values, Class<E> type, Consumer<E> handler) {
     public static <T, E extends Throwable> Iterable<T> safe(Iterable<T> values, Class<E> type, Consumer<E> handler) {
         return () -> IteratorUtils.safe(values.iterator(), type, handler);
         return () -> IteratorUtils.safe(values.iterator(), type, handler);
     }
     }

+ 410 - 83
assira.core/src/main/java/net/ranides/assira/collection/iterators/IteratorUtils.java

@@ -19,6 +19,7 @@ import net.ranides.assira.generic.Wrapper;
 import net.ranides.assira.trace.ExceptionUtils;
 import net.ranides.assira.trace.ExceptionUtils;
 
 
 /**
 /**
+ * Static methods working with Iterator interface.
  *
  *
  * @author Ranides Atterwim {@literal <ranides@gmail.com>}
  * @author Ranides Atterwim {@literal <ranides@gmail.com>}
  */
  */
@@ -27,14 +28,30 @@ public final class IteratorUtils {
     private IteratorUtils() {
     private IteratorUtils() {
         /* utility class */
         /* utility class */
     }
     }
-    
+
+    /**
+     * Returns first element for iterator, or none if iterator is empty.
+     *
+     * @param iterator
+     * @param <T> T
+     * @return optional
+     */
     public static <T> Optional<T> first(Iterator<? extends T> iterator) {
     public static <T> Optional<T> first(Iterator<? extends T> iterator) {
 		if(iterator.hasNext()) {
 		if(iterator.hasNext()) {
 			return Optional.of(iterator.next());
 			return Optional.of(iterator.next());
 		}
 		}
         return Optional.empty();
         return Optional.empty();
     }
     }
-    
+
+    /**
+     * Returns first element for iterator which satisfies predicate.
+     * Returns none if iterator is empty or no element was accepted by predicate.
+     *
+     * @param iterator iterator
+     * @param predicate predicate
+     * @param <T> T
+     * @return optional
+     */
     public static <T> Optional<T> first(Iterator<? extends T> iterator, Predicate<? super T> predicate) {
     public static <T> Optional<T> first(Iterator<? extends T> iterator, Predicate<? super T> predicate) {
         while(iterator.hasNext()) {
         while(iterator.hasNext()) {
             T v = iterator.next();
             T v = iterator.next();
@@ -44,7 +61,16 @@ public final class IteratorUtils {
         }
         }
         return Optional.empty();
         return Optional.empty();
     }
     }
-    
+
+    /**
+     * Returns last element for iterator, or none if iterator is empty.
+     * It must traverse whole collection.
+     * If you can, lets try ListUtils.
+     *
+     * @param iterator iterator
+     * @param <T> T
+     * @return optional
+     */
     public static <T> Optional<T> last(Iterator<? extends T> iterator) {
     public static <T> Optional<T> last(Iterator<? extends T> iterator) {
 		if(!iterator.hasNext()) {
 		if(!iterator.hasNext()) {
 			return Optional.empty();
 			return Optional.empty();
@@ -56,6 +82,16 @@ public final class IteratorUtils {
         return Optional.of(result);
         return Optional.of(result);
     }
     }
 
 
+    /**
+     * Returns element at specified position or none if iterator contains less elements.
+     * It must traverse through all previous elements.
+     * If you can, lets try ListUtils.
+     *
+     * @param iterator iterator
+     * @param index index
+     * @param <T> T
+     * @return optional
+     */
     public static <T> Optional<T> at(Iterator<? extends T> iterator, int index) {
     public static <T> Optional<T> at(Iterator<? extends T> iterator, int index) {
         for(int i=0; i<index; i++) {
         for(int i=0; i<index; i++) {
             if(!iterator.hasNext()) {
             if(!iterator.hasNext()) {
@@ -65,12 +101,23 @@ public final class IteratorUtils {
         }
         }
         return iterator.hasNext() ? Optional.of(iterator.next()) : Optional.empty();
         return iterator.hasNext() ? Optional.of(iterator.next()) : Optional.empty();
     }
     }
-    
+
+    /**
+     * Returns last element for iterator which satisfies predicate.
+     * Returns none if iterator is empty or no element was accepted by predicate.
+     * It must traverse whole collection.
+     * If you can, lets try ListUtils.
+     *
+     * @param iterator iterator
+     * @param predicate predicate
+     * @param <T> T
+     * @return optional
+     */
     public static <T> Optional<T> last(Iterator<? extends T> iterator, Predicate<? super T> predicate) {
     public static <T> Optional<T> last(Iterator<? extends T> iterator, Predicate<? super T> predicate) {
         boolean found = false;
         boolean found = false;
 		T result = null;
 		T result = null;
-        while(iterator.hasNext()) { 
-            T v = iterator.next(); 
+        while(iterator.hasNext()) {
+            T v = iterator.next();
             if(predicate.test(v)) {
             if(predicate.test(v)) {
                 result = v;
                 result = v;
 				found = true;
 				found = true;
@@ -81,7 +128,14 @@ public final class IteratorUtils {
 		}
 		}
         return Optional.of(result);
         return Optional.of(result);
     }
     }
-    
+
+    /**
+     * Counts number of elements for specified iterator.
+     * It must iterate through all elements, if you can, check collection size directly.
+     *
+     * @param iterator iterator
+     * @return int
+     */
     public static int size(Iterator<?> iterator) {
     public static int size(Iterator<?> iterator) {
 		if(iterator==null) {
 		if(iterator==null) {
 			return 0;
 			return 0;
@@ -94,112 +148,319 @@ public final class IteratorUtils {
         return c;
         return c;
     }
     }
 
 
+    /**
+     * Returns filtered view of provided IntIterator.
+     *
+     * @param iterator iterator
+     * @param predicate predicate
+     * @param <T> T
+     * @return iterator view
+     */
     public static <T> Iterator<T> filter(Iterator<? extends T> iterator, Predicate<? super T> predicate) {
     public static <T> Iterator<T> filter(Iterator<? extends T> iterator, Predicate<? super T> predicate) {
         return new FilterIterator<>(iterator, predicate, false);
         return new FilterIterator<>(iterator, predicate, false);
     }
     }
-	
-	public static <T> ListIterator<T> filter(ListIterator<? extends T> iterator, Predicate<? super T> predicate) {
+
+    /**
+     * Returns filtered read-only view of provided IntIterator.
+     * Returned iterator supports backward iteration, but it does not allow modifications.
+     *
+     * @param iterator iterator
+     * @param predicate predicate
+     * @param <T> T
+     * @return iterator view
+     */
+    public static <T> ListIterator<T> filter(ListIterator<? extends T> iterator, Predicate<? super T> predicate) {
         return new FilterListIterator<>(iterator, predicate, false);
         return new FilterListIterator<>(iterator, predicate, false);
     }
     }
 
 
+    /**
+     * Returns filtered view of provided IntIterator.
+     *
+     * @param iterator iterator
+     * @param predicate predicate
+     * @param <T> T
+     * @return iterator view
+     */
     public static <T> Iterator<T> filterEach(Iterator<? extends T> iterator, EachPredicate<? super T> predicate) {
     public static <T> Iterator<T> filterEach(Iterator<? extends T> iterator, EachPredicate<? super T> predicate) {
         return new FilterIterator<>(iterator, predicate, false);
         return new FilterIterator<>(iterator, predicate, false);
     }
     }
 
 
+    /**
+     * Returns filtered read-only view of provided IntIterator.
+     * Returned iterator supports backward iteration, but it does not allow modifications.
+     *
+     * @param iterator iterator
+     * @param predicate predicate
+     * @param <T> T
+     * @return iterator view
+     */
     public static <T> ListIterator<T> filterEach(ListIterator<? extends T> iterator, EachPredicate<? super T> predicate) {
     public static <T> ListIterator<T> filterEach(ListIterator<? extends T> iterator, EachPredicate<? super T> predicate) {
         return new FilterListIterator<>(iterator, predicate, false);
         return new FilterListIterator<>(iterator, predicate, false);
     }
     }
-    
+
+    /**
+     * Returns read-only view of provided Iterator.
+     * Limited iterator stops at first unmatched element.
+     *
+     * @param iterator iterator
+     * @param predicate predicate
+     * @param <T> T
+     * @return iterator view
+     */
     public static <T> Iterator<T> limit(Iterator<? extends T> iterator, Predicate<? super T> predicate) {
     public static <T> Iterator<T> limit(Iterator<? extends T> iterator, Predicate<? super T> predicate) {
         return new FilterIterator<>(iterator, predicate, true);
         return new FilterIterator<>(iterator, predicate, true);
     }
     }
-	
-	public static <T> ListIterator<T> limit(ListIterator<? extends T> iterator, Predicate<? super T> predicate) {
+
+    /**
+     * Returns read-only view of provided Iterator.
+     * Limited iterator stops at first unmatched element.
+     * Returned iterator supports backward iteration, but it does not allow modifications.
+     *
+     * @param iterator iterator
+     * @param predicate predicate
+     * @param <T> T
+     * @return iterator view
+     */
+    public static <T> ListIterator<T> limit(ListIterator<? extends T> iterator, Predicate<? super T> predicate) {
         return new FilterListIterator<>(iterator, predicate, true);
         return new FilterListIterator<>(iterator, predicate, true);
     }
     }
 
 
+    /**
+     * Returns read-only view of provided Iterator.
+     * Limited iterator returns no more than "limit" elements.
+     *
+     * @param iterator iterator
+     * @param limit limit
+     * @param <T> T
+     * @return iterator view
+     */
     public static <T> Iterator<T> limit(Iterator<T> iterator, int limit) {
     public static <T> Iterator<T> limit(Iterator<T> iterator, int limit) {
         return new LimitIterator<>(iterator, limit);
         return new LimitIterator<>(iterator, limit);
     }
     }
 
 
+    /**
+     * Returns read-only view of provided Iterator.
+     * Limited iterator returns no more than "limit" elements.
+     * Returned iterator supports backward iteration, but it does not allow modifications.
+     *
+     * @param iterator iterator
+     * @param limit limit
+     * @param <T> T
+     * @return iterator view
+     */
     public static <T> ListIterator<T> limit(ListIterator<T> iterator, int limit) {
     public static <T> ListIterator<T> limit(ListIterator<T> iterator, int limit) {
         return new LimitListIterator<>(iterator, limit);
         return new LimitListIterator<>(iterator, limit);
     }
     }
 
 
+    /**
+     * Returns read-only view of provided Iterator.
+     * Limited iterator returns elements at most from specified range.
+     * It means: it skips first "begin" elements and then stops after reaching "end".
+     *
+     * @param iterator iterator
+     * @param begin begin
+     * @param end end
+     * @param <T> T
+     * @return iterator view
+     */
     public static <T> Iterator<T> limit(Iterator<T> iterator, int begin, int end) {
     public static <T> Iterator<T> limit(Iterator<T> iterator, int begin, int end) {
         next(iterator, begin);
         next(iterator, begin);
         return new LimitIterator<>(iterator, end-begin);
         return new LimitIterator<>(iterator, end-begin);
     }
     }
 
 
+    /**
+     * Returns read-only view of provided Iterator.
+     * Limited iterator returns elements at most from specified range.
+     * It means: it skips first "begin" elements and then stops after reaching "end".
+     * Returned iterator supports backward iteration, but it does not allow modifications.
+     *
+     * @param iterator iterator
+     * @param begin begin
+     * @param end end
+     * @param <T> T
+     * @return iterator view
+     */
     public static <T> ListIterator<T> limit(ListIterator<T> iterator, int begin, int end) {
     public static <T> ListIterator<T> limit(ListIterator<T> iterator, int begin, int end) {
         next(iterator, begin);
         next(iterator, begin);
         return new LimitListIterator<>(iterator, end-begin);
         return new LimitListIterator<>(iterator, end-begin);
     }
     }
-    
+
+    /**
+     * Returns read-only view of iterator which maps every element using provided function.
+     *
+     * @param iterator iterator
+     * @param function function
+     * @param <T> T
+     * @param <S> S
+     * @return iterator view
+     */
     public static <S,T> Iterator<T> map(Iterator<? extends S> iterator, EachFunction<? super S,? extends T> function) {
     public static <S,T> Iterator<T> map(Iterator<? extends S> iterator, EachFunction<? super S,? extends T> function) {
         return new EachAdapter<>(iterator, function);
         return new EachAdapter<>(iterator, function);
     }
     }
-	
-	public static <S,T> Iterator<T> map(Iterator<? extends S> iterator, Function<? super S,? extends T> function) {
+
+    /**
+     * Returns read-only view of iterator which maps every element using provided function.
+     *
+     * @param iterator iterator
+     * @param function function
+     * @param <T> T
+     * @param <S> S
+     * @return iterator view
+     */
+    public static <S,T> Iterator<T> map(Iterator<? extends S> iterator, Function<? super S,? extends T> function) {
         return new Adapter<>(iterator, function);
         return new Adapter<>(iterator, function);
     }
     }
-    
+
+    /**
+     * Returns read-only view of iterator which maps every element using provided function.
+     * Returned iterator supports backward iteration, but it does not allow modifications.
+     *
+     * @param iterator iterator
+     * @param function function
+     * @param <T> T
+     * @param <S> S
+     * @return iterator view
+     */
     public static <S,T> ListIterator<T> map(ListIterator<? extends S> iterator, EachFunction<S,T> function) {
     public static <S,T> ListIterator<T> map(ListIterator<? extends S> iterator, EachFunction<S,T> function) {
         return new EachListAdapter<>(iterator, function);
         return new EachListAdapter<>(iterator, function);
     }
     }
-    
+
+    /**
+     * Returns read-only view of iterator which maps every element using provided function.
+     * Returned iterator supports backward iteration, but it does not allow modifications.
+     *
+     * @param iterator iterator
+     * @param function function
+     * @param <T> T
+     * @param <S> S
+     * @return iterator view
+     */
     public static <S,T> ListIterator<T> map(ListIterator<? extends S> iterator, Function<? super S,? extends T> function) {
     public static <S,T> ListIterator<T> map(ListIterator<? extends S> iterator, Function<? super S,? extends T> function) {
         return new ListAdapter<>(iterator, function);
         return new ListAdapter<>(iterator, function);
     }
     }
-    
+
+    /**
+     * Returns view which lazily expands all nested Iterators and merges into one iterator.
+     * Flat iterators move forward only as much as necessary (which means one element at time).
+     *
+     * @param iterator iterator
+     * @param <T> T
+     * @return iterator view
+     */
     public static <T> Iterator<T> flat(Iterator<? extends Iterator<? extends T>> iterator) {
     public static <T> Iterator<T> flat(Iterator<? extends Iterator<? extends T>> iterator) {
         return new FlatIterator<>(iterator);
         return new FlatIterator<>(iterator);
     }
     }
 
 
+    /**
+     * Returns view which lazily expands all provided Iterators and merges into one iterator.
+     * Flat iterators move forward only as much as necessary (which means one element at time).
+     *
+     * @param iterators iterators
+     * @param <T> T
+     * @return iterator
+     * @see #flat
+     */
     @SafeVarargs
     @SafeVarargs
     public static <T> Iterator<T> concat(Iterator<? extends T>... iterators) {
     public static <T> Iterator<T> concat(Iterator<? extends T>... iterators) {
         return flat(Arrays.asList(iterators).iterator());
         return flat(Arrays.asList(iterators).iterator());
     }
     }
-    
-	public static <T> Stream<T> stream(Iterator<? extends T> iterator) {
+
+    /**
+     * Creates new sequential Stream from provided iterator.
+     *
+     * @param iterator iterator
+     * @param <T> T
+     * @return stream
+     */
+    public static <T> Stream<T> stream(Iterator<? extends T> iterator) {
 		return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, 0), false);
 		return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, 0), false);
 	}
 	}
-    
+
+    /**
+     * Inserts all elements returned by iterator into provided collection.
+     *
+     * @param iterator iterator
+     * @param target target
+     * @param <T> T
+     * @param <C> C
+     * @return target
+     */
     public static <T, C extends Collection<? super T>> C collect(Iterator<? extends T> iterator, C target) {
     public static <T, C extends Collection<? super T>> C collect(Iterator<? extends T> iterator, C target) {
         while(iterator.hasNext()) {
         while(iterator.hasNext()) {
             target.add(iterator.next());
             target.add(iterator.next());
         }
         }
         return target;
         return target;
 	}
 	}
-	
+
     /**
     /**
-     * Nie da się stworzyć odwróconego ListIterator ponieważ indeksowanie się położy, operacja
-     * #add będzie wstawiać na nieprawidłowej pozycji. Operacja #set w zasadzie ma szanse działać. 
-     * Ale to za mało, żeby zwracać interfejs, którego kontraktu w 90% nie dotrzymujemy.
+     * Creates mutable iterator which runs in reversed order.
+     * It supports removing elements.
+     *
+     * Please note, that input iterator must be correctly rewinded before use.
+     *
+     * @param iterator iterator
      * @param <T>
      * @param <T>
-     * @param iterator
-     * @return 
+     * @return iterator view
      */
      */
 	public static <T> Iterator<T> reverse(ListIterator<? extends T> iterator) {
 	public static <T> Iterator<T> reverse(ListIterator<? extends T> iterator) {
 		return new ReverseIterator<>(iterator);
 		return new ReverseIterator<>(iterator);
 	}
 	}
 
 
+    /**
+     * It creates read-only iterator which offers limited backward iteration.
+     * It buffers last "max" results and allows to read back them.
+     *
+     * It does not support any modifications, including "remove".
+     *
+     * @param iterator iterator
+     * @param max max
+     * @param <T> T
+     * @return iterator
+     */
 	public static <T> ListIterator<T> buffered(Iterator<? extends T> iterator, int max) {
 	public static <T> ListIterator<T> buffered(Iterator<? extends T> iterator, int max) {
         return new BufferedIterator<>(iterator, max);
         return new BufferedIterator<>(iterator, max);
     }
     }
-	
-	public static <T> int next(Iterator<? extends T> iterator, int count) {
+
+    /**
+     * Tries to skip "count" elements.
+     * Returns number of successfully skipped elements.
+     *
+     * @param iterator iterator
+     * @param count count
+     * @param <T> T
+     * @return int
+     */
+    public static <T> int next(Iterator<? extends T> iterator, int count) {
 		int i=0;
 		int i=0;
 		for(; i<count && iterator.hasNext(); i++) {
 		for(; i<count && iterator.hasNext(); i++) {
 			iterator.next();
 			iterator.next();
 		}
 		}
 		return i;
 		return i;
 	}
 	}
-    
+
+    /**
+     * Checks if provided iterators contain equal elements.
+     * Order of elements is important.
+     *
+     * @param a a
+     * @param b b
+     * @param <T> T
+     * @return bool
+     */
     public static <T> boolean equals(Iterator<? extends T> a, Iterator<? extends T> b) {
     public static <T> boolean equals(Iterator<? extends T> a, Iterator<? extends T> b) {
         return equals(a, b, CompareUtils::equals);
         return equals(a, b, CompareUtils::equals);
     }
     }
-    
+
+    /**
+     * Checks if provided iterators contain equal elements using provided comparison function.
+     * Order of elements is important.
+     *
+     * @param a a
+     * @param b b
+     * @param predicate predicate
+     * @param <T> T
+     * @return bool
+     */
     public static <T> boolean equals(Iterator<? extends T> a, Iterator<? extends T> b, BiPredicate<? super T,? super T> predicate) {
     public static <T> boolean equals(Iterator<? extends T> a, Iterator<? extends T> b, BiPredicate<? super T,? super T> predicate) {
         while(a.hasNext() && b.hasNext()) {
         while(a.hasNext() && b.hasNext()) {
             if( !predicate.test(a.next(), b.next())) {
             if( !predicate.test(a.next(), b.next())) {
@@ -208,11 +469,32 @@ public final class IteratorUtils {
         }
         }
         return !a.hasNext() && !b.hasNext();
         return !a.hasNext() && !b.hasNext();
     }
     }
-    
+
+    /**
+     * Checks if provided iterators contain equal elements.
+     * Order of elements is important.
+     * It is three-value version, which returns +1, 0, -1
+     *
+     * @param a a
+     * @param b b
+     * @param <T> T
+     * @return int
+     */
     public static <T> int compare(Iterator<? extends T> a, Iterator<? extends T> b) {
     public static <T> int compare(Iterator<? extends T> a, Iterator<? extends T> b) {
         return compare(a, b, CompareUtils.comparator());
         return compare(a, b, CompareUtils.comparator());
     }
     }
-    
+
+    /**
+     * Checks if provided iterators contain equal elements using provided comparison function.
+     * Order of elements is important.
+     * It is three-value version, which returns +1, 0, -1
+     *
+     * @param a a
+     * @param b b
+     * @param cmp cmp
+     * @param <T> T
+     * @return int
+     */
     public static <T> int compare(Iterator<? extends T> a, Iterator<? extends T> b, Comparator<? super T> cmp) {
     public static <T> int compare(Iterator<? extends T> a, Iterator<? extends T> b, Comparator<? super T> cmp) {
         while(a.hasNext() && b.hasNext()) {
         while(a.hasNext() && b.hasNext()) {
             int icmp = cmp.compare(a.next(), b.next());
             int icmp = cmp.compare(a.next(), b.next());
@@ -222,7 +504,14 @@ public final class IteratorUtils {
         }
         }
         return a.hasNext() ? +1 : b.hasNext() ? -1 : 0;
         return a.hasNext() ? +1 : b.hasNext() ? -1 : 0;
     }
     }
-    
+
+    /**
+     * Iterates through all values and removes every element which is matched by predicate.
+     *
+     * @param iterator iterator
+     * @param predicate predicate
+     * @param <T> T
+     */
     public static <T> void remove(Iterator<? extends T> iterator, Predicate<? super T> predicate) {
     public static <T> void remove(Iterator<? extends T> iterator, Predicate<? super T> predicate) {
         while(iterator.hasNext()) {
         while(iterator.hasNext()) {
             T v = iterator.next();
             T v = iterator.next();
@@ -232,6 +521,17 @@ public final class IteratorUtils {
         }
         }
     }
     }
 
 
+    /**
+     * Creates new infinite iterator which returns values generated by provided supplier.
+     * Rethrows all unchecked exceptions from generator.
+     * Wraps by RuntimeException all checked exceptions from generator.
+     *
+     * Probably supplier must be statefull.
+     *
+     * @param generator generator
+     * @param <T> T
+     * @return iterator
+     */
     public static <T> Iterator<T> infinite(CheckedSupplier<T, ?> generator) {
     public static <T> Iterator<T> infinite(CheckedSupplier<T, ?> generator) {
         return new Iterator<T>() {
         return new Iterator<T>() {
             @Override
             @Override
@@ -252,6 +552,19 @@ public final class IteratorUtils {
         };
         };
     }
     }
 
 
+    /**
+     * Creates new finite iterator which returns values generated by provided supplier.
+     * Iterator stops when generator returns "Optional.empty"
+     *
+     * Rethrows all unchecked exceptions from generator.
+     * Wraps by RuntimeException all checked exceptions from generator.
+     *
+     * Probably supplier must be statefull.
+     *
+     * @param generator generator
+     * @param <T> T
+     * @return iterator
+     */
     public static <T> Iterator<T> finite(CheckedSupplier<Optional<T>, ?> generator) {
     public static <T> Iterator<T> finite(CheckedSupplier<Optional<T>, ?> generator) {
 	    return new Iterator<T>() {
 	    return new Iterator<T>() {
 
 
@@ -275,26 +588,79 @@ public final class IteratorUtils {
         };
         };
     }
     }
 
 
+    /**
+     * Creates safe iterator which will never throw any exception except NoSuchElementException.
+     * All exceptions are silently ignored.
+     * Behaviour of iterator methods in such case:
+     *  - "hasNext" returns false
+     *  - "next" throws NoSuchElementException
+     *  - "remove" does nothing
+     *
+     * @param iterator iterator
+     * @param <T> T
+     * @return iterator
+     */
     public static <T> Iterator<T> safe(Iterator<T> iterator) {
     public static <T> Iterator<T> safe(Iterator<T> iterator) {
         return safe(iterator, Exception.class, e -> {});
         return safe(iterator, Exception.class, e -> {});
     }
     }
 
 
+    /**
+     * Creates safe iterator which will never throw exception of specified "type".
+     * Exceptions of "type" are silently ignored.
+     * Behaviour of iterator methods in such case:
+     *   - "hasNext" returns false
+     *   - "next" throws NoSuchElementException
+     *   - "remove" does nothing
+     *
+     * Please note, that other exceptions still will be propagated without change.
+     *
+     * Please note, that NoSuchElementException will be thrown as usuall.
+     *
+     * @param iterator iterator
+     * @param type exception to ignore
+     * @param <T> T
+     * @param <E> E
+     * @return iterator
+     */
     public static <T, E extends Throwable> Iterator<T> safe(Iterator<T> iterator, Class<E> type) {
     public static <T, E extends Throwable> Iterator<T> safe(Iterator<T> iterator, Class<E> type) {
         return safe(iterator, type, e -> {});
         return safe(iterator, type, e -> {});
     }
     }
 
 
+    /**
+     * Creates safe iterator which will never throw exception of specified "type".
+     * Exceptions of "type" are sent to handler.
+     *
+     * Behaviour of iterator methods in such case:
+     *   - "hasNext" returns false
+     *   - "next" throws NoSuchElementException
+     *   - "remove" does nothing
+     *
+     * Please note, that other exceptions still will be propagated without change.
+     *
+     * Please note, that NoSuchElementException will be thrown as usuall.
+     *
+     * @param iterator iterator
+     * @param type exception to ignore
+     * @param handler handler
+     * @param <T> T
+     * @param <E> E
+     * @return iterator
+     */
     public static <T, E extends Throwable> Iterator<T> safe(Iterator<T> iterator, Class<E> type, Consumer<E> handler) {
     public static <T, E extends Throwable> Iterator<T> safe(Iterator<T> iterator, Class<E> type, Consumer<E> handler) {
         return new SafeIterator<>(iterator, type, handler);
         return new SafeIterator<>(iterator, type, handler);
     }
     }
 
 
+    /**
+     * Creates iterator with single provided value
+     *
+     * @param value value
+     * @param <T> T
+     * @return iterator
+     */
     public static <T> Iterator<T> singletonIterator(T value) {
     public static <T> Iterator<T> singletonIterator(T value) {
 	    return new SingleIterator<>(value);
 	    return new SingleIterator<>(value);
     }
     }
 
 
-    public static <T> Spliterator<T> singletonSpliterator(T value) {
-        return new SingleSpliterator<>(value);
-    }
-
     private static final class Adapter<S, T> implements Iterator<T> {
     private static final class Adapter<S, T> implements Iterator<T> {
     
     
         protected final Iterator<S> delegate;
         protected final Iterator<S> delegate;
@@ -737,6 +1103,12 @@ public final class IteratorUtils {
 
 
     }
     }
 
 
+    /**
+     * We implement only Iterator, because it is impossible to create correct reversed ListIterator.
+     * Indexing will be invalid and #add operation will insert into wrong place.
+     * Eventually we can implement #set operation, but it is not enough to return interface which is 90% not implemented.
+     * @param <T>
+     */
 	private static class ReverseIterator<T> implements Iterator<T> {
 	private static class ReverseIterator<T> implements Iterator<T> {
 		
 		
 		private final ListIterator<? extends T> iterator;
 		private final ListIterator<? extends T> iterator;
@@ -915,51 +1287,6 @@ public final class IteratorUtils {
         }
         }
     }
     }
 
 
-    private static class SingleSpliterator<T> implements Spliterator<T> {
-
-	    private final T value;
-
-        long est = 1;
-
-        public SingleSpliterator(T value) {
-            this.value = value;
-        }
-
-        @Override
-        public Spliterator<T> trySplit() {
-            return null;
-        }
-
-        @Override
-        public boolean tryAdvance(Consumer<? super T> consumer) {
-            Objects.requireNonNull(consumer);
-            if (est > 0) {
-                est--;
-                consumer.accept(value);
-                return true;
-            }
-            return false;
-        }
-
-        @Override
-        public void forEachRemaining(Consumer<? super T> consumer) {
-            tryAdvance(consumer);
-        }
-
-        @Override
-        public long estimateSize() {
-            return est;
-        }
-
-        @Override
-        public int characteristics() {
-            int out = (value != null) ? Spliterator.NONNULL : 0;
-
-            return out | Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.IMMUTABLE |
-                    Spliterator.DISTINCT | Spliterator.ORDERED;
-        }
-    }
-
     private static class SafeIterator<T, E extends Throwable> implements Iterator<T> {
     private static class SafeIterator<T, E extends Throwable> implements Iterator<T> {
 
 
         private final Iterator<? extends T> iterator;
         private final Iterator<? extends T> iterator;

+ 55 - 0
assira.core/src/main/java/net/ranides/assira/collection/iterators/SpliteratorUtils.java

@@ -33,6 +33,17 @@ public final class SpliteratorUtils {
         return new LimitSpliterator<>(spliterator, p);
         return new LimitSpliterator<>(spliterator, p);
     }
     }
 
 
+    /**
+     * Creates spliterator with single provided value
+     *
+     * @param value value
+     * @param <T> T
+     * @return iterator
+     */
+    public static <T> Spliterator<T> singletonSpliterator(T value) {
+        return new SingleSpliterator<>(value);
+    }
+
     private static class LimitSpliterator<T> extends Spliterators.AbstractSpliterator<T> {
     private static class LimitSpliterator<T> extends Spliterators.AbstractSpliterator<T> {
         private final Spliterator<T> spliterator;
         private final Spliterator<T> spliterator;
         private final Predicate<? super T> condition;
         private final Predicate<? super T> condition;
@@ -142,4 +153,48 @@ public final class SpliteratorUtils {
 
 
     }
     }
 
 
+    private static class SingleSpliterator<T> implements Spliterator<T> {
+
+	    private final T value;
+
+        long est = 1;
+
+        public SingleSpliterator(T value) {
+            this.value = value;
+        }
+
+        @Override
+        public Spliterator<T> trySplit() {
+            return null;
+        }
+
+        @Override
+        public boolean tryAdvance(Consumer<? super T> consumer) {
+            Objects.requireNonNull(consumer);
+            if (est > 0) {
+                est--;
+                consumer.accept(value);
+                return true;
+            }
+            return false;
+        }
+
+        @Override
+        public void forEachRemaining(Consumer<? super T> consumer) {
+            tryAdvance(consumer);
+        }
+
+        @Override
+        public long estimateSize() {
+            return est;
+        }
+
+        @Override
+        public int characteristics() {
+            int out = (value != null) ? Spliterator.NONNULL : 0;
+
+            return out | Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.IMMUTABLE |
+                    Spliterator.DISTINCT | Spliterator.ORDERED;
+        }
+    }
 }
 }

+ 181 - 18
assira.core/src/main/java/net/ranides/assira/collection/lists/IntListUtils.java

@@ -7,6 +7,7 @@
 
 
 package net.ranides.assira.collection.lists;
 package net.ranides.assira.collection.lists;
 
 
+import lombok.experimental.UtilityClass;
 import net.ranides.assira.collection.IntCollectionUtils;
 import net.ranides.assira.collection.IntCollectionUtils;
 import net.ranides.assira.collection.Swapper;
 import net.ranides.assira.collection.Swapper;
 import net.ranides.assira.collection.arrays.NativeArray.NativeComparator;
 import net.ranides.assira.collection.arrays.NativeArray.NativeComparator;
@@ -24,37 +25,82 @@ import java.util.function.IntPredicate;
 import java.util.function.IntUnaryOperator;
 import java.util.function.IntUnaryOperator;
 
 
 /**
 /**
+ * Static methods working with IntList interface.
+ * Generally, empty result is signalled by throwing exception because
+ * we try to avoid boxing operations or OptionalInt wrappers.
  *
  *
  * @author Ranides Atterwim {@literal <ranides@gmail.com>}
  * @author Ranides Atterwim {@literal <ranides@gmail.com>}
  */
  */
+@UtilityClass
 public final class IntListUtils {
 public final class IntListUtils {
-	
-	private IntListUtils() {
-		/* utility class */
-	}
-	
+
+	/**
+	 * Returns first element inside collection, or throws if collection is empty.
+	 *
+	 * @param values values
+	 * @return int
+	 * @throws java.util.NoSuchElementException if no result
+	 */
 	public static int first(IntList values) {
 	public static int first(IntList values) {
 		if(values.isEmpty()) {
 		if(values.isEmpty()) {
 			throw new NoSuchElementException();
 			throw new NoSuchElementException();
 		}
 		}
 		return values.getInt(0);
 		return values.getInt(0);
 	}
 	}
-	
+
+	/**
+	 * Returns first element inside collection which satisfies predicate.
+	 * Throws if collection is empty or no element was accepted by predicate.
+	 *
+	 * @param values values
+	 * @param predicate predicate
+	 * @return int
+	 * @throws java.util.NoSuchElementException if no result
+	 */
 	public static int first(IntList values, IntPredicate predicate) {
 	public static int first(IntList values, IntPredicate predicate) {
 		return IntCollectionUtils.first(values, predicate);
 		return IntCollectionUtils.first(values, predicate);
 	}
 	}
-	
+
+	/**
+	 * Returns first element inside collection which satisfies predicate and is located inside specified range.
+	 * Throws if range is outside collection bounds or no element was accepted by predicate.
+	 *
+	 * @param values values
+	 * @param begin begin
+	 * @param end end
+	 * @param predicate predicate
+	 * @return int
+	 * @throws java.util.NoSuchElementException if no result
+	 */
 	public static int first(IntList values, int begin, int end, IntPredicate predicate) {
 	public static int first(IntList values, int begin, int end, IntPredicate predicate) {
 		return first(values.subList(begin, end), predicate);
 		return first(values.subList(begin, end), predicate);
 	}
 	}
-	
+
+	/**
+	 * Returns last element inside collection, or throws if collection is empty.
+	 *
+	 * @param values values
+	 * @return int
+	 * @throws java.util.NoSuchElementException if no result
+	 */
 	public static int last(IntList values) {
 	public static int last(IntList values) {
 		if(values.isEmpty()) {
 		if(values.isEmpty()) {
 			throw new NoSuchElementException();
 			throw new NoSuchElementException();
 		}
 		}
 		return values.getInt(values.size()-1);
 		return values.getInt(values.size()-1);
 	}
 	}
-	
+
+	/**
+	 * Returns last element inside collection which satisfies predicate.
+	 * Throws if collection is empty or no element was accepted by predicate.
+	 *
+	 * It minimizes number of operations by using backward iterator.
+	 *
+	 * @param values values
+	 * @param predicate predicate
+	 * @return int
+	 * @throws java.util.NoSuchElementException if no result
+	 */
 	public static int last(IntList values, IntPredicate predicate) {
 	public static int last(IntList values, IntPredicate predicate) {
 		IntListIterator iterator = values.listIterator(values.size());
 		IntListIterator iterator = values.listIterator(values.size());
 
 
@@ -66,11 +112,32 @@ public final class IntListUtils {
         }
         }
         throw new NoSuchElementException();
         throw new NoSuchElementException();
 	}
 	}
-	
+
+	/**
+	 * Returns last element inside collection which satisfies predicate and is located inside specified range.
+	 * Throws if range is outside collection bounds or no element was accepted by predicate.
+	 *
+	 * It minimizes number of operations by using backward iterator.
+	 *
+	 * @param values values
+	 * @param begin begin
+	 * @param end end
+	 * @param predicate predicate
+	 * @return int
+	 * @throws java.util.NoSuchElementException if no result
+	 */
 	public static int last(IntList values, int begin, int end, IntPredicate predicate) {
 	public static int last(IntList values, int begin, int end, IntPredicate predicate) {
 		return last(values.subList(begin, end), predicate);
 		return last(values.subList(begin, end), predicate);
 	}
 	}
-	
+
+	/**
+	 * Returns new list filtered by predicate.
+	 * Returned list is a copy, not a view.
+	 *
+	 * @param values values
+	 * @param predicate predicate
+	 * @return new list
+	 */
 	public static IntList filter(IntList values, IntPredicate predicate) {
 	public static IntList filter(IntList values, IntPredicate predicate) {
 		IntList ret = new IntArrayList();
 		IntList ret = new IntArrayList();
 		for(int i=0,n=values.size(); i<n; i++) {
 		for(int i=0,n=values.size(); i<n; i++) {
@@ -81,7 +148,20 @@ public final class IntListUtils {
 		}
 		}
 		return ret;
 		return ret;
 	}
 	}
-	
+
+	/**
+	 * Returns view which maps every element using provided function.
+	 * Changes introduced to source collection are visible in view.
+	 *
+	 * Returned view supports removing, but not set or add operations.
+	 *
+	 * Please note, that it allows mapping to any object.
+	 *
+	 * @param values values
+	 * @param function function
+	 * @param <T> target type
+	 * @return view
+	 */
 	public static <T> List<T> map(IntList values, IntFunction<? extends T> function) {
 	public static <T> List<T> map(IntList values, IntFunction<? extends T> function) {
 		return new VirtualList<T>() {
 		return new VirtualList<T>() {
 			
 			
@@ -103,7 +183,19 @@ public final class IntListUtils {
             }
             }
 		};
 		};
     }
     }
-	
+
+	/**
+	 * Returns view which maps every element using provided function.
+	 * Changes introduced to source collection are visible in view.
+	 *
+	 * Returned view supports removing, but not set or add operations.
+	 *
+	 * Please note, that it allows only mapping preserving type "int".
+	 *
+	 * @param values values
+	 * @param function function
+	 * @return view
+	 */
 	public static IntList map(IntList values, IntUnaryOperator function) {
 	public static IntList map(IntList values, IntUnaryOperator function) {
 		return new AIntList() {
 		return new AIntList() {
 			
 			
@@ -136,7 +228,17 @@ public final class IntListUtils {
 		};
 		};
     }
     }
 
 
-    public static <R> IntList map(IntList values, IntProjectionFunction function) {
+	/**
+	 * Returns mutable view which maps every element using provided projection.
+	 * Changes introduced to source collection are visible in view and vice versa.
+	 *
+	 * Returned view supports all operation: remove, set or add.
+	 *
+	 * @param values values
+	 * @param function function
+	 * @return view
+	 */
+	public static IntList map(IntList values, IntProjectionFunction function) {
 		return new AIntList() {
 		return new AIntList() {
 			
 			
 			private static final long serialVersionUID = 1L;
 			private static final long serialVersionUID = 1L;
@@ -169,7 +271,16 @@ public final class IntListUtils {
 		};
 		};
     }
     }
 
 
-    public static IntList produce(int size, IntUnaryOperator function) {
+	/**
+	 * Returns new virtual list of specified size, which contains elements calculated by "function" at every access.
+	 *
+	 * Virtual list does not support modifications.
+	 *
+	 * @param size size
+	 * @param function function
+	 * @return virtual
+	 */
+	public static IntList produce(int size, IntUnaryOperator function) {
         return new IntVirtualList() {
         return new IntVirtualList() {
 			
 			
 			private static final long serialVersionUID = 1L;
 			private static final long serialVersionUID = 1L;
@@ -183,9 +294,18 @@ public final class IntListUtils {
                 return function.applyAsInt(index);
                 return function.applyAsInt(index);
             }
             }
         };
         };
-    } 
-    
-    public static IntList sublist(IntList list, int begin, int end) {
+    }
+
+	/**
+	 * Returns sublist.
+	 * Returned view is correctly marked as RandomAccess if source was marked by it.
+	 *
+	 * @param list list
+	 * @param begin begin
+	 * @param end end
+	 * @return view
+	 */
+	public static IntList sublist(IntList list, int begin, int end) {
 		NativeArrayAllocator.ensureFromTo(list.size(), begin, end);
 		NativeArrayAllocator.ensureFromTo(list.size(), begin, end);
 		if(list instanceof RandomAccess) {
 		if(list instanceof RandomAccess) {
 			return new RandomSubList(list, begin, end);
 			return new RandomSubList(list, begin, end);
@@ -194,20 +314,63 @@ public final class IntListUtils {
 		}
 		}
 	}
 	}
 
 
+	/**
+	 * Returns swapper for specified list.
+	 *
+	 * Swappers can be used for example by sort algorithms or shuffle algorithms to make swaps in efficient way
+	 * without knowing if they work on list or on array.
+	 *
+	 * @param list list
+	 * @return swapper
+	 */
 	public static Swapper swapper(IntList list) {
 	public static Swapper swapper(IntList list) {
 	    return (a,b) -> swap(list,a,b);
 	    return (a,b) -> swap(list,a,b);
     }
     }
 
 
+	/**
+	 * Swaps elements inside list.
+	 *
+	 * @param list list
+	 * @param a a
+	 * @param b b
+	 */
 	public static void swap(IntList list, int a, int b) {
 	public static void swap(IntList list, int a, int b) {
 		int t = list.getInt(a);
 		int t = list.getInt(a);
 		list.set(a, list.getInt(b));
 		list.set(a, list.getInt(b));
 		list.set(b, t);
 		list.set(b, t);
 	}
 	}
 
 
+	/**
+	 * Binary search operation.
+	 * Returns index of "value", or negative index if not found.
+	 * Negative index can be used as insertion position: -(index-1)
+	 *
+	 * List must be sorted in natural order.
+	 *
+	 * @param list list
+	 * @param value value
+	 * @return int
+	 */
 	public static int binarySearch(IntList list, int value) {
 	public static int binarySearch(IntList list, int value) {
 		return binarySearch(list, 0, list.size(), value);
 		return binarySearch(list, 0, list.size(), value);
 	}
 	}
 
 
+	/**
+	 * Binary search operation inside specified range.
+	 * Returns index of "value", or negative index if not found.
+	 * Negative index can be used as insertion position: -(index-1)
+	 *
+	 * Returned index is not "begin-based" but "0-based" and can be used directly for list access.
+	 * Of course, if begin or end is reached, returned index is clipped to specified range.
+	 *
+	 * List must be sorted in natural order.
+	 *
+	 * @param list list
+	 * @param begin begin
+	 * @param end end
+	 * @param value value
+	 * @return int
+	 */
 	public static int binarySearch(IntList list, int begin, int end, int value) {
 	public static int binarySearch(IntList list, int begin, int end, int value) {
 		NativeComparator cmp = index -> Integer.compare(list.getInt(index), value);
 		NativeComparator cmp = index -> Integer.compare(list.getInt(index), value);
 		return NativeArraySearch.binarySearch(cmp, begin, end);
 		return NativeArraySearch.binarySearch(cmp, begin, end);

+ 263 - 26
assira.core/src/main/java/net/ranides/assira/collection/lists/ListUtils.java

@@ -15,6 +15,7 @@ import java.util.function.IntFunction;
 import java.util.function.Predicate;
 import java.util.function.Predicate;
 import java.util.stream.Collectors;
 import java.util.stream.Collectors;
 
 
+import lombok.experimental.UtilityClass;
 import net.ranides.assira.collection.CollectionUtils;
 import net.ranides.assira.collection.CollectionUtils;
 import net.ranides.assira.collection.Swapper;
 import net.ranides.assira.collection.Swapper;
 import net.ranides.assira.collection.arrays.NativeArray;
 import net.ranides.assira.collection.arrays.NativeArray;
@@ -22,49 +23,99 @@ import net.ranides.assira.collection.arrays.NativeArrayAllocator;
 import net.ranides.assira.collection.arrays.NativeArraySearch;
 import net.ranides.assira.collection.arrays.NativeArraySearch;
 import net.ranides.assira.collection.iterators.IteratorUtils;
 import net.ranides.assira.collection.iterators.IteratorUtils;
 import net.ranides.assira.collection.iterators.RandomAccessIterator;
 import net.ranides.assira.collection.iterators.RandomAccessIterator;
-import net.ranides.assira.functional.Functions;
 import net.ranides.assira.functional.Functions.EachFunction;
 import net.ranides.assira.functional.Functions.EachFunction;
 import net.ranides.assira.functional.covariant.ProjectionFunction;
 import net.ranides.assira.functional.covariant.ProjectionFunction;
 
 
 /**
 /**
+ * Static methods working with List interface.
  *
  *
  * @author Ranides Atterwim {@literal <ranides@gmail.com>}
  * @author Ranides Atterwim {@literal <ranides@gmail.com>}
  */
  */
+@UtilityClass
 public final class ListUtils {
 public final class ListUtils {
-	
-	private ListUtils() {
-		/* utility class */
-	}
 
 
+	/**
+	 * Returns element at specified index, or none if index is out of boundaries.
+	 *
+	 * @param values values
+	 * @param index index
+	 * @param <T> T
+	 * @return optional
+	 */
 	public static <T> Optional<T> at(List<? extends T> values, int index) {
 	public static <T> Optional<T> at(List<? extends T> values, int index) {
 		if(values.size() <= index) {
 		if(values.size() <= index) {
 			return Optional.empty();
 			return Optional.empty();
 		}
 		}
 		return Optional.of(values.get(index));
 		return Optional.of(values.get(index));
 	}
 	}
-	
+
+	/**
+	 * Returns first element inside collection, or none if collection is empty.
+	 *
+	 * @param values values
+	 * @param <T> T
+	 * @return optional
+	 */
 	public static <T> Optional<T> first(List<? extends T> values) {
 	public static <T> Optional<T> first(List<? extends T> values) {
 		if(values.isEmpty()) {
 		if(values.isEmpty()) {
 			return Optional.empty();
 			return Optional.empty();
 		}
 		}
 		return Optional.of(values.get(0));
 		return Optional.of(values.get(0));
 	}
 	}
-	
+
+	/**
+	 * Returns first element inside collection which satisfies predicate.
+	 * Returns none if collection is empty or no element was accepted by predicate.
+	 *
+	 * @param values values
+	 * @param predicate predicate
+	 * @param <T> T
+	 * @return optional
+	 */
 	public static <T> Optional<T> first(List<? extends T> values, Predicate<? super T> predicate) {
 	public static <T> Optional<T> first(List<? extends T> values, Predicate<? super T> predicate) {
 		return CollectionUtils.first(values, predicate);
 		return CollectionUtils.first(values, predicate);
 	}
 	}
-	
+
+	/**
+	 * Returns first element inside collection which satisfies predicate and is located inside specified range.
+	 * Returns none if range is outside collection bounds or no element was accepted by predicate.
+	 *
+	 * @param values values
+	 * @param begin begin
+	 * @param end end
+	 * @param predicate predicate
+	 * @param <T> T
+	 * @return optional
+	 */
 	public static <T> Optional<T> first(List<? extends T> values, int begin, int end, Predicate<? super T> predicate) {
 	public static <T> Optional<T> first(List<? extends T> values, int begin, int end, Predicate<? super T> predicate) {
 		return first(values.subList(begin, end), predicate);
 		return first(values.subList(begin, end), predicate);
 	}
 	}
-	
+
+	/**
+	 * Returns last element inside collection, or none if collection is empty.
+	 *
+	 * @param values values
+	 * @param <T> T
+	 * @return optional
+	 */
 	public static <T> Optional<T> last(List<? extends T> values) {
 	public static <T> Optional<T> last(List<? extends T> values) {
 		if(values.isEmpty()) {
 		if(values.isEmpty()) {
 			return Optional.empty();
 			return Optional.empty();
 		}
 		}
 		return Optional.of(values.get(values.size()-1));
 		return Optional.of(values.get(values.size()-1));
 	}
 	}
-	
+
+	/**
+	 * Returns last element inside collection which satisfies predicate.
+	 * Returns none if collection is empty or no element was accepted by predicate.
+	 *
+	 * It minimizes number of operations by using backward iterator.
+	 *
+	 * @param values values
+	 * @param predicate predicate
+	 * @param <T> T
+	 * @return optional
+	 */
 	public static <T> Optional<T> last(List<? extends T> values, Predicate<? super T> predicate) {
 	public static <T> Optional<T> last(List<? extends T> values, Predicate<? super T> predicate) {
 		ListIterator<? extends T> iterator = values.listIterator(values.size());
 		ListIterator<? extends T> iterator = values.listIterator(values.size());
 
 
@@ -76,19 +127,62 @@ public final class ListUtils {
         }
         }
         return Optional.empty();
         return Optional.empty();
 	}
 	}
-	
+
+	/**
+	 * Returns last element inside collection which satisfies predicate and is located inside specified range.
+	 * Returns none if range is outside collection bounds or no element was accepted by predicate.
+	 *
+	 * It minimizes number of operations by using backward iterator.
+	 *
+	 * @param values values
+	 * @param begin begin
+	 * @param end end
+	 * @param predicate predicate
+	 * @param <T> T
+	 * @return optional
+	 */
 	public static <T> Optional<T> last(List<? extends T> values, int begin, int end, Predicate<? super T> predicate) {
 	public static <T> Optional<T> last(List<? extends T> values, int begin, int end, Predicate<? super T> predicate) {
 		return last(values.subList(begin, end), predicate);
 		return last(values.subList(begin, end), predicate);
 	}
 	}
-	
+
+	/**
+	 * Returns new list filtered by predicate.
+	 * Returned list is a copy, not a view.
+	 *
+	 * @param values values
+	 * @param predicate predicate
+	 * @param <T> T
+	 * @return new list
+	 */
 	public static <T> List<T> filter(List<? extends T> values, Predicate<? super T> predicate) {
 	public static <T> List<T> filter(List<? extends T> values, Predicate<? super T> predicate) {
 		return values.stream().filter(predicate).collect(Collectors.toList());
 		return values.stream().filter(predicate).collect(Collectors.toList());
 	}
 	}
-    
+
+	/**
+	 * Returns new list limited by predicate.
+	 * Limited list contains only begin of the list until predicate failed.
+	 *
+	 * @param values values
+	 * @param predicate predicate
+	 * @param <T> T
+	 * @return new list
+	 */
     public static <T> List<T> limit(List<? extends T> values, Predicate<? super T> predicate) {
     public static <T> List<T> limit(List<? extends T> values, Predicate<? super T> predicate) {
         return IteratorUtils.collect(IteratorUtils.limit(values.iterator(), predicate), new ArrayList<>());
         return IteratorUtils.collect(IteratorUtils.limit(values.iterator(), predicate), new ArrayList<>());
 	}
 	}
-	
+
+	/**
+	 * Returns view which maps every element using provided function.
+	 * Changes introduced to source collection are visible in view.
+	 *
+	 * Returned view supports removing, but not set or add operations.
+	 *
+	 * @param values values
+	 * @param function function
+	 * @param <S> source type
+	 * @param <T> target type
+	 * @return view
+	 */
 	public static <S,T> List<T> map(List<? extends S> values, Function<? super S,? extends T> function) {
 	public static <S,T> List<T> map(List<? extends S> values, Function<? super S,? extends T> function) {
 		return new VirtualList<T>() {
 		return new VirtualList<T>() {
 			
 			
@@ -111,6 +205,18 @@ public final class ListUtils {
 		};
 		};
     }
     }
 
 
+	/**
+	 * Returns view which maps every element using provided function.
+	 * Changes introduced to source collection are visible in view.
+	 *
+	 * Returned view supports removing, but not set or add operations.
+	 *
+	 * @param values values
+	 * @param function function
+	 * @param <S> source type
+	 * @param <T> target type
+	 * @return view
+	 */
 	public static <S,T> List<T> mapEach(List<? extends S> values, EachFunction<? super S,? extends T> function) {
 	public static <S,T> List<T> mapEach(List<? extends S> values, EachFunction<? super S,? extends T> function) {
 		return new VirtualList<T>() {
 		return new VirtualList<T>() {
 
 
@@ -132,8 +238,20 @@ public final class ListUtils {
 			}
 			}
 		};
 		};
 	}
 	}
-    
-    public static <S,T> List<T> map(List<S> values, ProjectionFunction<S,T> function) {
+
+	/**
+	 * Returns mutable view which maps every element using provided projection.
+	 * Changes introduced to source collection are visible in view and vice versa.
+	 *
+	 * Returned view supports all operation: remove, set or add.
+	 *
+	 * @param values values
+	 * @param function function
+	 * @param <S> source type
+	 * @param <T> target type
+	 * @return view
+	 */
+	public static <S,T> List<T> map(List<S> values, ProjectionFunction<S,T> function) {
         return new VirtualList<T>() {
         return new VirtualList<T>() {
 			@Override
 			@Override
 			public T get(int index) {
 			public T get(int index) {
@@ -164,19 +282,39 @@ public final class ListUtils {
 		};
 		};
     }
     }
 
 
-    public static <Q> List<Q> produce(int size, IntFunction<? extends Q> function) {
-        return new VirtualList<Q>() {
+	/**
+	 * Returns new virtual list of specified size, which contains elements calculated by "function" at every access.
+	 *
+	 * Virtual list does not support modifications.
+	 *
+	 * @param size size
+	 * @param function function
+	 * @param <T> T
+	 * @return virtual
+	 */
+    public static <T> List<T> produce(int size, IntFunction<? extends T> function) {
+        return new VirtualList<T>() {
             @Override
             @Override
             public int size() {
             public int size() {
                 return size;
                 return size;
             }
             }
             @Override
             @Override
-            public Q get(int index) {
+            public T get(int index) {
                 return function.apply(index);
                 return function.apply(index);
             }
             }
         };
         };
-    }  
-	
+    }
+
+	/**
+	 * Returns sublist.
+	 * Returned view is correctly marked as RandomAccess if source was marked by it.
+	 *
+	 * @param list list
+	 * @param begin begin
+	 * @param end end
+	 * @param <T> T
+	 * @return view
+	 */
 	public static <T> List<T> sublist(List<T> list, int begin, int end) {
 	public static <T> List<T> sublist(List<T> list, int begin, int end) {
 		NativeArrayAllocator.ensureFromTo(list.size(), begin, end);
 		NativeArrayAllocator.ensureFromTo(list.size(), begin, end);
 		if(list instanceof RandomAccess) {
 		if(list instanceof RandomAccess) {
@@ -185,38 +323,137 @@ public final class ListUtils {
 			return new SubList<>(list, begin, end);
 			return new SubList<>(list, begin, end);
 		}
 		}
 	}
 	}
-    
-    public static <T> boolean equals(List<? extends T> a, List<? extends T> b, BiPredicate<? super T,? super T> predicate) {
+
+	/**
+	 * Checks if provided collections contain equal elements using provided comparison function.
+	 * Order of elements is important.
+	 *
+	 * @param a a
+	 * @param b b
+	 * @param predicate predicate
+	 * @param <T> T
+	 * @return bool
+	 */
+	public static <T> boolean equals(List<? extends T> a, List<? extends T> b, BiPredicate<? super T,? super T> predicate) {
         return (a.size() == b.size()) && IteratorUtils.equals(a.iterator(), b.iterator(), predicate);
         return (a.size() == b.size()) && IteratorUtils.equals(a.iterator(), b.iterator(), predicate);
     }
     }
-    
-    public static <T> int compare(List<? extends T> a, List<? extends T> b, Comparator<? super T> cmp) {
+
+	/**
+	 * Checks if provided collections contain equal elements using provided comparison function.
+	 * Order of elements is important.
+	 * It is three-value version, which returns +1, 0, -1
+	 *
+	 * @param a a
+	 * @param b b
+	 * @param cmp cmp
+	 * @param <T> T
+	 * @return int
+	 */
+	public static <T> int compare(List<? extends T> a, List<? extends T> b, Comparator<? super T> cmp) {
         return IteratorUtils.compare(a.iterator(), b.iterator(), cmp);
         return IteratorUtils.compare(a.iterator(), b.iterator(), cmp);
     }
     }
 
 
+	/**
+	 * Returns swapper for specified list.
+	 *
+	 * Swappers can be used for example by sort algorithms or shuffle algorithms to make swaps in efficient way
+	 * without knowing if they work on list or on array.
+	 *
+	 * @param list list
+	 * @param <T> T
+	 * @return swapper
+	 */
     public static <T> Swapper swapper(List<T> list) {
     public static <T> Swapper swapper(List<T> list) {
         return (a,b) -> swap(list,a,b);
         return (a,b) -> swap(list,a,b);
     }
     }
 
 
+	/**
+	 * Swaps elements inside list.
+	 *
+	 * @param list list
+	 * @param a a
+	 * @param b b
+	 * @param <T> T
+	 */
     public static <T> void swap(List<T> list, int a, int b) {
     public static <T> void swap(List<T> list, int a, int b) {
         T t = list.get(a);
         T t = list.get(a);
         list.set(a, list.get(b));
         list.set(a, list.get(b));
         list.set(b, t);
         list.set(b, t);
     }
     }
 
 
+	/**
+	 * Binary search operation.
+	 * Returns index of "value", or negative index if not found.
+	 * Negative index can be used as insertion position: -(index-1)
+	 *
+	 * List must be sorted in natural order.
+	 *
+	 * @param list list
+	 * @param value value
+	 * @param <T> T
+	 * @return int
+	 */
 	public static <T extends Comparable<T>> int binarySearch(List<T> list, T value) {
 	public static <T extends Comparable<T>> int binarySearch(List<T> list, T value) {
 		return binarySearch(list, 0, list.size(), value);
 		return binarySearch(list, 0, list.size(), value);
 	}
 	}
 
 
+	/**
+	 * Binary search operation inside specified range.
+	 * Returns index of "value", or negative index if not found.
+	 * Negative index can be used as insertion position: -(index-1)
+	 *
+	 * Returned index is not "begin-based" but "0-based" and can be used directly for list access.
+	 * Of course, if begin or end is reached, returned index is clipped to specified range.
+	 *
+	 * List must be sorted in natural order.
+	 *
+	 * @param list list
+	 * @param begin begin
+	 * @param end end
+	 * @param value value
+	 * @param <T> T
+	 * @return int
+	 */
 	public static <T extends Comparable<T>> int binarySearch(List<T> list, int begin, int end, T value) {
 	public static <T extends Comparable<T>> int binarySearch(List<T> list, int begin, int end, T value) {
-		NativeArray.NativeComparator ncmp = index -> value.compareTo(list.get(index));
+		NativeArray.NativeComparator ncmp = index -> -value.compareTo(list.get(index));
 		return NativeArraySearch.binarySearch(ncmp, begin, end);
 		return NativeArraySearch.binarySearch(ncmp, begin, end);
 	}
 	}
 
 
+	/**
+	 * Binary search operation.
+	 * Returns index of "value", or negative index if not found.
+	 * Negative index can be used as insertion position: -(index-1)
+	 *
+	 * List must be in order imposed by "cmp".
+	 *
+	 * @param list list
+	 * @param value value
+	 * @param cmp cmp
+	 * @param <T> T
+	 * @return int
+	 */
 	public static <T> int binarySearch(List<T> list, T value, Comparator<? super T> cmp) {
 	public static <T> int binarySearch(List<T> list, T value, Comparator<? super T> cmp) {
 		return binarySearch(list, 0, list.size(), value, cmp);
 		return binarySearch(list, 0, list.size(), value, cmp);
 	}
 	}
 
 
+	/**
+	 * Binary search operation inside specified range.
+	 * Returns index of "value", or negative index if not found.
+	 * Negative index can be used as insertion position: -(index-1)
+	 *
+	 * Returned index is not "begin-based" but "0-based" and can be used directly for list access.
+	 * Of course, if begin or end is reached, returned index is clipped to specified range.
+	 *
+	 * List must be in order imposed by "cmp".
+	 *
+	 * @param list list
+	 * @param begin begin
+	 * @param end end
+	 * @param value value
+	 * @param cmp cmp
+	 * @param <T> T
+	 * @return int
+	 */
 	public static <T> int binarySearch(List<T> list, int begin, int end, T value, Comparator<? super T> cmp) {
 	public static <T> int binarySearch(List<T> list, int begin, int end, T value, Comparator<? super T> cmp) {
 		NativeArray.NativeComparator ncmp = index -> cmp.compare(list.get(index), value);
 		NativeArray.NativeComparator ncmp = index -> cmp.compare(list.get(index), value);
 		return NativeArraySearch.binarySearch(ncmp, begin, end);
 		return NativeArraySearch.binarySearch(ncmp, begin, end);

+ 2 - 1
assira.core/src/main/java/net/ranides/assira/collection/query/base/CQSingle.java

@@ -3,6 +3,7 @@ package net.ranides.assira.collection.query.base;
 import lombok.RequiredArgsConstructor;
 import lombok.RequiredArgsConstructor;
 
 
 import net.ranides.assira.collection.iterators.IteratorUtils;
 import net.ranides.assira.collection.iterators.IteratorUtils;
+import net.ranides.assira.collection.iterators.SpliteratorUtils;
 import net.ranides.assira.collection.query.CQuery;
 import net.ranides.assira.collection.query.CQuery;
 import net.ranides.assira.collection.query.CQueryAbstract;
 import net.ranides.assira.collection.query.CQueryAbstract;
 import net.ranides.assira.functional.Consumers;
 import net.ranides.assira.functional.Consumers;
@@ -76,7 +77,7 @@ public class CQSingle<T> extends CQueryAbstract<T> {
 
 
     @Override
     @Override
     public Spliterator<T> spliterator() {
     public Spliterator<T> spliterator() {
-        return IteratorUtils.singletonSpliterator(value);
+        return SpliteratorUtils.singletonSpliterator(value);
     }
     }
 
 
     @Override
     @Override

+ 15 - 1
assira.core/src/test/java/net/ranides/assira/collection/lists/ListUtilsTest.java

@@ -181,5 +181,19 @@ public class ListUtilsTest {
 			.run();
 			.run();
 		assertTrue(true);
 		assertTrue(true);
 	}
 	}
-    
+
+	@Test
+	public void binarySearch() {
+		List<Integer> list = Arrays.asList(1, 2, 3, 5, 6, 7, 8);
+
+		assertEquals(4, ListUtils.binarySearch(list, 6));
+		assertEquals(6, ListUtils.binarySearch(list, 8));
+		assertEquals(-1, ListUtils.binarySearch(list, 0));
+		assertEquals(-4, ListUtils.binarySearch(list, 4)); // insertion at 3
+
+		assertEquals(4, ListUtils.binarySearch(list, 1, 6, 6));
+		assertEquals(-7, ListUtils.binarySearch(list, 1, 6, 8)); // insertion at 6, i.e. end
+		assertEquals(-2, ListUtils.binarySearch(list, 1, 6, 0));
+		assertEquals(-4, ListUtils.binarySearch(list, 1, 6, 4)); // insertion at 3
+	}
 }
 }

+ 5 - 5
assira.core/src/test/java/net/ranides/assira/reflection/impl/RMethodTest.java

@@ -57,11 +57,11 @@ public class RMethodTest {
 
 
         // It is not our fault. Compiler generates something wrong and JVM itself can parse it.
         // It is not our fault. Compiler generates something wrong and JVM itself can parse it.
 
 
-        ForRMethod<? super Float> parent2 = new ForRMethod<Float>(){};
-        Object record2 = parent2.new Record<Double>(){};
-        Type type2 = record2.getClass().getGenericSuperclass();
-
-        Assume.assumeThat(type2.toString(), CoreMatchers.equalTo(RECORD_TYPE));
+//        ForRMethod<? super Float> parent2 = new ForRMethod<Float>(){};
+//        Object record2 = parent2.new Record<Double>(){};
+//        Type type2 = record2.getClass().getGenericSuperclass();
+//
+//        Assume.assumeThat(type2.toString(), CoreMatchers.equalTo(RECORD_TYPE));
 
 
     }
     }