// Path: ImagingKit_Core/src/main/java/hageldave/imagingkit/core/PixelConvertingSpliterator.java
// public static interface PixelConverter<P extends PixelBase, T> {
// 	/**
// 	 * Allocates a new element for the PixelConvertingSpliterator
// 	 * (will be called once per split)
// 	 * @return element, probably in uninitialized state
// 	 */
// 	public T allocateElement();
// 		
// 	/**
// 	 * converts the specified pixel to the specified element
// 	 * (initiliazation of previously allocated element).
// 	 * <br><b>NOT ALLOCATION, ONLY SETUP OF THE ELEMENT</b>
// 	 * @param px to used for setting up the element
// 	 * @param element to be set up
// 	 */
// 	public void convertPixelToElement(P px, T element);
// 		
// 	/**
// 	 * converts the specified element back to the specified pixel
// 	 * (set pixel value according to element).
// 	 * <br><b>NOT ALLOCATION, ONLY SETTING THE PIXEL VALUE ACCORDINGLY</b>
// 	 * @param element to be used for setting the pixel value
// 	 * @param px to be set
// 	 */
// 	public void convertElementToPixel(T element, P px);
// 
// 	/**
// 	 * Creates a new PixelConverter from the specified functions.
// 	 * @param allocator a supplier that allocates a new object of the element type (see {@link #allocateElement()})
// 	 * @param pixelToElement a consumer that sets the contents of the element according to a pixel (see {@link #convertPixelToElement(PixelBase, Object)})
// 	 * @param elementToPixel a consumer that sets the content of a pixel according to the element (see {@link #convertElementToPixel(Object, PixelBase)})
// 	 * @return a new PixelConverter
// 	 */
// 	public static <P extends PixelBase, T> PixelConverter<P,T> fromFunctions(
// 			Supplier<T> allocator,
// 			BiConsumer<P,T> pixelToElement,
// 			BiConsumer<T,P> elementToPixel)
// 	{
// 		Objects.requireNonNull(allocator);
// 		BiConsumer<P,T> px_2_el = pixelToElement==null ? (px,e)->{}:pixelToElement;
// 		BiConsumer<T,P> el_2_px = elementToPixel==null ? (e,px)->{}:elementToPixel;
// 
// 		return new PixelConverter<P,T>(){
// 			@Override
// 			public T allocateElement() {return allocator.get();}
// 			@Override
// 			public void convertPixelToElement(P px, T element) {px_2_el.accept(px, element);}
// 			@Override
// 			public void convertElementToPixel(T element, P px) {el_2_px.accept(element, px);}
// 
// 		};
// 	}
// }


import static org.junit.Assert.*;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Spliterator;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import org.junit.Test;
import hageldave.imagingkit.core.PixelConvertingSpliterator.PixelConverter;
				assertEquals((x+1)%2, img.getValue(x, y));
			}
			img.fill(0);
			img.stream(100,200,1000,1000).filter(px->{return px.getX() % 2 == 0;}).forEach(px->{px.setValue(1);});
			for(int y = 0; y < 2000; y++)
			for(int x = 0; x < 3000; x++){
				if(x < 100 || y < 200 || x >=100+1000 || y >= 200+1000){
					assertEquals(0, img.getValue(x, y));
				} else {
					assertEquals((x+1)%2, img.getValue(x, y));
				}
			}
			img.fill(0);
			img.stream(true, 100,200,1000,1000).filter(px->{return px.getX() % 2 == 0;}).forEach(px->{px.setValue(1);});
			for(int y = 0; y < 2000; y++)
			for(int x = 0; x < 3000; x++){
				if(x < 100 || y < 200 || x >=100+1000 || y >= 200+1000){
					assertEquals(0, img.getValue(x, y));
				} else {
					assertEquals((x+1)%2, img.getValue(x, y));
				}
			}

		}
		
		
		// forEach/stream with manipulator/converter
		{
			PixelManipulator<PixelBase,Color[]> colorManip = new PixelManipulator<PixelBase,Color[]>() {
				@Override
// Path: ImagingKit_Core/src/main/java/hageldave/imagingkit/core/PixelConvertingSpliterator.java
// public static interface PixelConverter<P extends PixelBase, T> {
// 	/**
// 	 * Allocates a new element for the PixelConvertingSpliterator
// 	 * (will be called once per split)
// 	 * @return element, probably in uninitialized state
// 	 */
// 	public T allocateElement();
// 		
// 	/**
// 	 * converts the specified pixel to the specified element
// 	 * (initiliazation of previously allocated element).
// 	 * <br><b>NOT ALLOCATION, ONLY SETUP OF THE ELEMENT</b>
// 	 * @param px to used for setting up the element
// 	 * @param element to be set up
// 	 */
// 	public void convertPixelToElement(P px, T element);
// 		
// 	/**
// 	 * converts the specified element back to the specified pixel
// 	 * (set pixel value according to element).
// 	 * <br><b>NOT ALLOCATION, ONLY SETTING THE PIXEL VALUE ACCORDINGLY</b>
// 	 * @param element to be used for setting the pixel value
// 	 * @param px to be set
// 	 */
// 	public void convertElementToPixel(T element, P px);
// 
// 	/**
// 	 * Creates a new PixelConverter from the specified functions.
// 	 * @param allocator a supplier that allocates a new object of the element type (see {@link #allocateElement()})
// 	 * @param pixelToElement a consumer that sets the contents of the element according to a pixel (see {@link #convertPixelToElement(PixelBase, Object)})
// 	 * @param elementToPixel a consumer that sets the content of a pixel according to the element (see {@link #convertElementToPixel(Object, PixelBase)})
// 	 * @return a new PixelConverter
// 	 */
// 	public static <P extends PixelBase, T> PixelConverter<P,T> fromFunctions(
// 			Supplier<T> allocator,
// 			BiConsumer<P,T> pixelToElement,
// 			BiConsumer<T,P> elementToPixel)
// 	{
// 		Objects.requireNonNull(allocator);
// 		BiConsumer<P,T> px_2_el = pixelToElement==null ? (px,e)->{}:pixelToElement;
// 		BiConsumer<T,P> el_2_px = elementToPixel==null ? (e,px)->{}:elementToPixel;
// 
// 		return new PixelConverter<P,T>(){
// 			@Override
// 			public T allocateElement() {return allocator.get();}
// 			@Override
// 			public void convertPixelToElement(P px, T element) {px_2_el.accept(px, element);}
// 			@Override
// 			public void convertElementToPixel(T element, P px) {el_2_px.accept(element, px);}
// 
// 		};
// 	}
// }


// Path: ImagingKit_Core/src/test/java/hageldave/imagingkit/core/ImgTest.java
import static org.junit.Assert.*;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Spliterator;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import org.junit.Test;
import hageldave.imagingkit.core.PixelConvertingSpliterator.PixelConverter;

				assertEquals((x+1)%2, img.getValue(x, y));
			}
			img.fill(0);
			img.stream(100,200,1000,1000).filter(px->{return px.getX() % 2 == 0;}).forEach(px->{px.setValue(1);});
			for(int y = 0; y < 2000; y++)
			for(int x = 0; x < 3000; x++){
				if(x < 100 || y < 200 || x >=100+1000 || y >= 200+1000){
					assertEquals(0, img.getValue(x, y));
				} else {
					assertEquals((x+1)%2, img.getValue(x, y));
				}
			}
			img.fill(0);
			img.stream(true, 100,200,1000,1000).filter(px->{return px.getX() % 2 == 0;}).forEach(px->{px.setValue(1);});
			for(int y = 0; y < 2000; y++)
			for(int x = 0; x < 3000; x++){
				if(x < 100 || y < 200 || x >=100+1000 || y >= 200+1000){
					assertEquals(0, img.getValue(x, y));
				} else {
					assertEquals((x+1)%2, img.getValue(x, y));
				}
			}

		}
		
		
		// forEach/stream with manipulator/converter
		{
			PixelManipulator<PixelBase,Color[]> colorManip = new PixelManipulator<PixelBase,Color[]>() {
				@Override
				public PixelConverter<PixelBase, Color[]> getConverter() {