changeset 6437:1359dedd5475

- pushed IntSink into Sink (a primitive kitchen sink :-) ). - cleaned up functional SAMs. - merged IntForEachOp into ForEachOp. - re-jigged methods on Primitives to be in sync with style and use as that on Streams.
author psandoz
date Mon, 19 Nov 2012 17:18:19 +0100
parents 1440e2129616
children 76facba329a1
files src/share/classes/java/util/Arrays.java src/share/classes/java/util/concurrent/atomic/AtomicInteger.java src/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java src/share/classes/java/util/concurrent/atomic/AtomicLong.java src/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java src/share/classes/java/util/function/DoubleBinaryOperator.java src/share/classes/java/util/function/DoubleUnaryOperator.java src/share/classes/java/util/function/IntBinaryOperator.java src/share/classes/java/util/function/IntBlock.java src/share/classes/java/util/function/IntUnaryOperator.java src/share/classes/java/util/function/LongBinaryOperator.java src/share/classes/java/util/function/LongUnaryOperator.java src/share/classes/java/util/stream/Sink.java src/share/classes/java/util/stream/Streams.java src/share/classes/java/util/stream/TerminalSink.java src/share/classes/java/util/stream/op/ConcatOp.java src/share/classes/java/util/stream/op/FilterOp.java src/share/classes/java/util/stream/op/FlatMapOp.java src/share/classes/java/util/stream/op/FoldOp.java src/share/classes/java/util/stream/op/ForEachOp.java src/share/classes/java/util/stream/op/GroupByOp.java src/share/classes/java/util/stream/op/MapOp.java src/share/classes/java/util/stream/op/NodeBuilder.java src/share/classes/java/util/stream/op/ReduceByOp.java src/share/classes/java/util/stream/op/SliceOp.java src/share/classes/java/util/stream/op/SortedOp.java src/share/classes/java/util/stream/op/TeeOp.java src/share/classes/java/util/stream/op/UniqOp.java src/share/classes/java/util/stream/primitive/IntBlock.java src/share/classes/java/util/stream/primitive/IntFilterOp.java src/share/classes/java/util/stream/primitive/IntForEachOp.java src/share/classes/java/util/stream/primitive/IntIterable.java src/share/classes/java/util/stream/primitive/IntIterator.java src/share/classes/java/util/stream/primitive/IntLimitOp.java src/share/classes/java/util/stream/primitive/IntMapOp.java src/share/classes/java/util/stream/primitive/IntNodeBuilder.java src/share/classes/java/util/stream/primitive/IntNodes.java src/share/classes/java/util/stream/primitive/IntPipeline.java src/share/classes/java/util/stream/primitive/IntSink.java src/share/classes/java/util/stream/primitive/IntSortedOp.java src/share/classes/java/util/stream/primitive/IntSpliterator.java src/share/classes/java/util/stream/primitive/IntStream.java src/share/classes/java/util/stream/primitive/IntSumOp.java src/share/classes/java/util/stream/primitive/IntTeeOp.java src/share/classes/java/util/stream/primitive/IntTerminalSink.java src/share/classes/java/util/stream/primitive/IntToIntegerOp.java src/share/classes/java/util/stream/primitive/IntUnaryOperator.java src/share/classes/java/util/stream/primitive/Primitives.java src/share/classes/java/util/stream/primitive/RefToIntMapOp.java test-ng/tests/org/openjdk/tests/java/lang/PrimitiveSumMinMaxTest.java test-ng/tests/org/openjdk/tests/java/util/LambdaTestHelpers.java test-ng/tests/org/openjdk/tests/java/util/function/DoubleUnaryOperatorTest.java test-ng/tests/org/openjdk/tests/java/util/function/IntUnaryOperatorTest.java test-ng/tests/org/openjdk/tests/java/util/function/LongUnaryOperatorTest.java test-ng/tests/org/openjdk/tests/java/util/stream/OpTestCase.java test-ng/tests/org/openjdk/tests/java/util/stream/op/ForEachOpTest.java test-ng/tests/org/openjdk/tests/java/util/stream/op/IntNodeTest.java test-ng/tests/org/openjdk/tests/java/util/stream/op/NodeBuilderTest.java test-ng/tests/org/openjdk/tests/java/util/stream/primitive/IntStreamTestScenario.java
diffstat 59 files changed, 528 insertions(+), 733 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/java/util/Arrays.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/src/share/classes/java/util/Arrays.java	Mon Nov 19 17:18:19 2012 +0100
@@ -3798,7 +3798,7 @@
         }
     }
 
-    private static class ArraySink<T> implements Sink.OfValue<T> {
+    private static class ArraySink<T> implements Sink.OfReference<T> {
         private final T[] array;
         private final int offset;
         private final int length;
--- a/src/share/classes/java/util/concurrent/atomic/AtomicInteger.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/src/share/classes/java/util/concurrent/atomic/AtomicInteger.java	Mon Nov 19 17:18:19 2012 +0100
@@ -150,7 +150,7 @@
         int oldValue, newValue;
         do {
             oldValue = get();
-            newValue = op.operate(oldValue);
+            newValue = op.operateAsInt(oldValue);
         } while (!compareAndSet(oldValue, newValue));
         return oldValue;
     }
@@ -169,7 +169,7 @@
         int oldValue, newValue;
         do {
             oldValue = get();
-            newValue = op.operate(oldValue);
+            newValue = op.operateAsInt(oldValue);
         } while (!compareAndSet(oldValue, newValue));
         return newValue;
     }
--- a/src/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/src/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java	Mon Nov 19 17:18:19 2012 +0100
@@ -41,7 +41,6 @@
 import java.security.PrivilegedExceptionAction;
 import java.security.PrivilegedActionException;
 import java.util.function.IntUnaryOperator;
-import java.util.function.UnaryOperator;
 
 /**
  * A reflection-based utility that enables atomic updates to
@@ -281,7 +280,7 @@
         int oldValue, newValue;
         do {
             oldValue = get(obj);
-            newValue = op.operate(oldValue);
+            newValue = op.operateAsInt(oldValue);
         } while (!compareAndSet(obj, oldValue, newValue));
         return newValue;
     }
@@ -301,7 +300,7 @@
         int oldValue, newValue;
         do {
             oldValue = get(obj);
-            newValue = op.operate(oldValue);
+            newValue = op.operateAsInt(oldValue);
         } while (!compareAndSet(obj, oldValue, newValue));
         return oldValue;
     }
--- a/src/share/classes/java/util/concurrent/atomic/AtomicLong.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/src/share/classes/java/util/concurrent/atomic/AtomicLong.java	Mon Nov 19 17:18:19 2012 +0100
@@ -164,7 +164,7 @@
         long oldValue, newValue;
         do {
             oldValue = get();
-            newValue = op.operate(oldValue);
+            newValue = op.operateAsLong(oldValue);
         } while (!compareAndSet(oldValue, newValue));
         return newValue;
     }
@@ -183,7 +183,7 @@
         long oldValue, newValue;
         do {
             oldValue = get();
-            newValue = op.operate(oldValue);
+            newValue = op.operateAsLong(oldValue);
         } while (!compareAndSet(oldValue, newValue));
         return oldValue;
     }
--- a/src/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/src/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java	Mon Nov 19 17:18:19 2012 +0100
@@ -40,7 +40,6 @@
 import java.security.AccessController;
 import java.security.PrivilegedExceptionAction;
 import java.security.PrivilegedActionException;
-import java.util.function.IntUnaryOperator;
 import java.util.function.LongUnaryOperator;
 
 /**
@@ -284,7 +283,7 @@
         long oldValue, newValue;
         do {
             oldValue = get(obj);
-            newValue = op.operate(oldValue);
+            newValue = op.operateAsLong(oldValue);
         } while (!compareAndSet(obj, oldValue, newValue));
         return newValue;
     }
@@ -304,7 +303,7 @@
         long oldValue, newValue;
         do {
             oldValue = get(obj);
-            newValue = op.operate(oldValue);
+            newValue = op.operateAsLong(oldValue);
         } while (!compareAndSet(obj, oldValue, newValue));
         return oldValue;
     }
--- a/src/share/classes/java/util/function/DoubleBinaryOperator.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/src/share/classes/java/util/function/DoubleBinaryOperator.java	Mon Nov 19 17:18:19 2012 +0100
@@ -40,7 +40,7 @@
      * @param right the right operand
      * @return result of the operation
      */
-    public default Double operate(Double left, Double right) { return operate((double) left, (double) right); }
+    public default Double operate(Double left, Double right) { return operateAsDouble((double) left, (double) right); }
 
     /**
      * Returns the result of some binary operation upon the operands. The
@@ -51,5 +51,5 @@
      * @param rightvalue used as the right operand
      * @return result value of the operation
      */
-    public double operate(double left, double right);
+    public double operateAsDouble(double left, double right);
 }
--- a/src/share/classes/java/util/function/DoubleUnaryOperator.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/src/share/classes/java/util/function/DoubleUnaryOperator.java	Mon Nov 19 17:18:19 2012 +0100
@@ -38,7 +38,7 @@
      * @return the computed result
      */
     @Override
-    public default Double operate(Double operand) { return operate((double) operand); }
+    public default Double operate(Double operand) { return operateAsDouble((double) operand); }
 
     /**
      * Returns a {@code double} value computed from the {@code double} operand.
@@ -46,5 +46,5 @@
      * @param operand the operand value
      * @return the computed result
      */
-    public double operate(double operand);
+    public double operateAsDouble(double operand);
 }
--- a/src/share/classes/java/util/function/IntBinaryOperator.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/src/share/classes/java/util/function/IntBinaryOperator.java	Mon Nov 19 17:18:19 2012 +0100
@@ -41,7 +41,7 @@
      * @return result of the operation
      */
     @Override
-    public default Integer operate(Integer left, Integer right) { return operate((int) left, (int) right); }
+    public default Integer operate(Integer left, Integer right) { return operateAsInt((int) left, (int) right); }
 
     /**
      * Returns the result of some binary operation upon the operands. The
@@ -52,5 +52,5 @@
      * @param right value used as the right operand
      * @return result value of the operation
      */
-    public int operate(int left, int right);
+    public int operateAsInt(int left, int right);
 }
--- a/src/share/classes/java/util/function/IntBlock.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/src/share/classes/java/util/function/IntBlock.java	Mon Nov 19 17:18:19 2012 +0100
@@ -24,6 +24,9 @@
  */
 package java.util.function;
 
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
 /**
  * Performs operations upon an input object which may modify that object and/or
  * external state (other objects).
@@ -41,7 +44,11 @@
      * @param t the input
      */
     @Override
-    public default void accept(Integer t) { apply((int) t); }
+    public default void accept(Integer t) {
+        // @@@ temporary tripwire
+        Logger.getLogger(getClass().getName()).log(Level.WARNING, "{0} using boxed int", getClass().getName());
+        accept((int) t);
+    }
 
     /**
      * Performs operations upon the provided object which may modify that object
@@ -49,5 +56,5 @@
      *
      * @param t the input value
      */
-    public void apply(int t);
+    public void accept(int t);
 }
--- a/src/share/classes/java/util/function/IntUnaryOperator.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/src/share/classes/java/util/function/IntUnaryOperator.java	Mon Nov 19 17:18:19 2012 +0100
@@ -24,6 +24,9 @@
  */
 package java.util.function;
 
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
 /**
  * Operator on a single {@code int} operand.
  *
@@ -38,7 +41,10 @@
      * @return the computed result
      */
     @Override
-    public default Integer operate(Integer operand) { return operate((int) operand); }
+    public default Integer operate(Integer operand) {
+        Logger.getLogger(getClass().getName()).log(Level.WARNING, "{0} using boxed int", getClass().getName());
+        return operateAsInt((int) operand);
+    }
 
     /**
      * Returns an {@code int} value computed from the {@code int} operand.
@@ -46,5 +52,5 @@
      * @param operand the operand value
      * @return the computed result
      */
-    public int operate(int operand);
+    public int operateAsInt(int operand);
 }
--- a/src/share/classes/java/util/function/LongBinaryOperator.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/src/share/classes/java/util/function/LongBinaryOperator.java	Mon Nov 19 17:18:19 2012 +0100
@@ -41,7 +41,7 @@
      * @return result of the operation
      */
     @Override
-    public default Long operate(Long left, Long right) { return operate((long) left, (long) right); }
+    public default Long operate(Long left, Long right) { return operateAsLong((long) left, (long) right); }
 
     /**
      * Returns the result of some binary operation upon the operands. The
@@ -52,5 +52,5 @@
      * @param right value used as the right operand
      * @return result value of the operation
      */
-    public long operate(long left, long right);
+    public long operateAsLong(long left, long right);
 }
--- a/src/share/classes/java/util/function/LongUnaryOperator.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/src/share/classes/java/util/function/LongUnaryOperator.java	Mon Nov 19 17:18:19 2012 +0100
@@ -38,7 +38,7 @@
      * @return the computed result
      */
     @Override
-    public default Long operate(Long operand) { return operate((long) operand); }
+    public default Long operate(Long operand) { return operateAsLong((long) operand); }
 
     /**
      * Returns a {@code long} value computed from the {@code long} operand.
@@ -46,5 +46,5 @@
      * @param operand the operand value
      * @return the computed result
      */
-    public long operate(long operand);
+    public long operateAsLong(long operand);
 }
--- a/src/share/classes/java/util/stream/Sink.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/src/share/classes/java/util/stream/Sink.java	Mon Nov 19 17:18:19 2012 +0100
@@ -25,8 +25,9 @@
 package java.util.stream;
 
 import java.util.Objects;
-import java.util.function.BiBlock;
 import java.util.function.Block;
+import java.util.function.IntBlock;
+import java.util.logging.Level;
 import java.util.logging.Logger;
 
 /**
@@ -43,7 +44,7 @@
      * @param size The exact size of the data to be pushed downstream, if
      * known or {@code -1} if unknown or infinite.
      */
-    void begin(int size);
+    default void begin(int size) {}
 
     /**
      * Indicate that all elements have been pushed. Chained sinks should dump
@@ -51,15 +52,46 @@
      */
     default void end() {}
 
-    public interface OfValue<T> extends Sink<T> {
-        @Override
-        default void begin(int size) {}
+    default void accept(int value) {
+        throw new IllegalStateException();
     }
 
-    public static abstract class ChainedValue<T> implements OfValue<T> {
+    public interface OfReference<T> extends Sink<T> {
+    }
+
+    public interface OfInt extends Sink<Integer>, IntBlock {
+        @Override
+        void accept(int value);
+
+        @Override
+        default void accept(Integer i) {
+            Logger.getLogger(getClass().getName()).log(Level.WARNING, "{0} using boxed int", getClass().getName());
+            accept(i.intValue());
+        }
+    }
+
+    public static abstract class ChainedReference<T> implements Sink.OfReference<T> {
         protected final Sink downstream;
 
-        public ChainedValue(Sink downstream) {
+        public ChainedReference(Sink downstream) {
+            this.downstream = Objects.requireNonNull(downstream);
+        }
+
+        @Override
+        public void begin(int size) {
+            downstream.begin(size);
+        }
+
+        @Override
+        public void end() {
+            downstream.end();
+        }
+    }
+
+    public static abstract class ChainedInt implements Sink.OfInt {
+        protected final Sink downstream;
+
+        public ChainedInt(Sink downstream) {
             this.downstream = Objects.requireNonNull(downstream);
         }
 
--- a/src/share/classes/java/util/stream/Streams.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/src/share/classes/java/util/stream/Streams.java	Mon Nov 19 17:18:19 2012 +0100
@@ -263,7 +263,7 @@
             if (iterator == null) {
                 iterable.forEach(block);
                 iterator = Collections.emptyIterator();
-                size = (sizeProvider != null) ? sizeProvider.size() : -1;
+                size = 0;
             }
             else
                 iterator.forEach(block);
--- a/src/share/classes/java/util/stream/TerminalSink.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/src/share/classes/java/util/stream/TerminalSink.java	Mon Nov 19 17:18:19 2012 +0100
@@ -34,17 +34,6 @@
  * @author Brian Goetz
  */
 public interface TerminalSink<T, R> extends Sink<T> {
-
-    /**
-     * @@@ consider removing default
-     * @param size
-     */
-    @Override
-    default void begin(int size) { }
-
-    @Override
-    default void end() { }
-
     /**
      * Retrieve, and clear, the current state of the sink.
      */
--- a/src/share/classes/java/util/stream/op/ConcatOp.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/src/share/classes/java/util/stream/op/ConcatOp.java	Mon Nov 19 17:18:19 2012 +0100
@@ -59,7 +59,7 @@
     public Sink<T> wrapSink(int flags, Sink<T> sink) {
         Objects.requireNonNull(sink);
 
-        return new Sink.ChainedValue<T>(sink) {
+        return new Sink.ChainedReference<T>(sink) {
             @Override
             public void accept(T t) {
                 downstream.accept(t);
--- a/src/share/classes/java/util/stream/op/FilterOp.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/src/share/classes/java/util/stream/op/FilterOp.java	Mon Nov 19 17:18:19 2012 +0100
@@ -56,7 +56,7 @@
     @Override
     public Sink<T> wrapSink(int flags, final Sink sink) {
         Objects.requireNonNull(sink);
-        return new Sink.ChainedValue<T>(sink) {
+        return new Sink.ChainedReference<T>(sink) {
             @Override
             public void accept(T t) {
                 if (predicate.test(t))
--- a/src/share/classes/java/util/stream/op/FlatMapOp.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/src/share/classes/java/util/stream/op/FlatMapOp.java	Mon Nov 19 17:18:19 2012 +0100
@@ -60,7 +60,7 @@
     @Override
     public Sink<T> wrapSink(int flags, final Sink sink) {
         Objects.requireNonNull(sink);
-        return new Sink.ChainedValue<T>(sink) {
+        return new Sink.ChainedReference<T>(sink) {
             public void accept(T t) {
                 mapper.flatMapInto(downstream, t);
             }
--- a/src/share/classes/java/util/stream/op/FoldOp.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/src/share/classes/java/util/stream/op/FoldOp.java	Mon Nov 19 17:18:19 2012 +0100
@@ -29,6 +29,7 @@
 import java.util.function.Supplier;
 import java.util.stream.ParallelPipelineHelper;
 import java.util.stream.PipelineHelper;
+import java.util.stream.Sink;
 
 /**
  * FoldOp
@@ -59,7 +60,7 @@
         return OpUtils.parallelReduce(helper, () -> new FoldingSink());
     }
 
-    /* private */ class FoldingSink implements OpUtils.AccumulatingSink<T, U, FoldingSink> {
+    /* private */ class FoldingSink implements OpUtils.AccumulatingSink<T, U, FoldingSink>, Sink.OfReference<T> {
         U state;
 
         @Override
--- a/src/share/classes/java/util/stream/op/ForEachOp.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/src/share/classes/java/util/stream/op/ForEachOp.java	Mon Nov 19 17:18:19 2012 +0100
@@ -26,7 +26,7 @@
 
 import java.util.Objects;
 import java.util.function.Block;
-import java.util.logging.Logger;
+import java.util.function.IntBlock;
 import java.util.stream.*;
 
 /**
@@ -35,7 +35,6 @@
  * @author Brian Goetz
  */
 public class ForEachOp<T> implements TerminalOp<T, Void> {
-    private static final Logger LOGGER = Logger.getLogger(ForEachOp.class.getName());
     private final TerminalSink<T, Void> sink;
     private final StreamShape shape;
 
@@ -44,10 +43,10 @@
         this.sink = Objects.requireNonNull(sink);
     }
 
-    public static<T> ForEachOp<T> make(final Block<? super T> block) {
+    public static <T> ForEachOp<T> make(final Block<? super T> block) {
         Objects.requireNonNull(block);
         return new ForEachOp<>(new TerminalSink<T, Void>() {
-         @Override
+            @Override
             public void accept(T t) {
                 block.accept(t);
             }
@@ -59,6 +58,11 @@
         }, StreamShapeFactory.REFERENCE);
     }
 
+    public static ForEachOp make(final IntBlock block) {
+        Objects.requireNonNull(block);
+        return new ForEachOp(new IntForEachTerminalSink(block), StreamShapeFactory.INT_VALUE);
+    }
+
     @Override
     public StreamShape inputShape() {
         return shape;
@@ -74,4 +78,22 @@
         OpUtils.parallelForEach(helper, helper.wrapSink(sink));
         return null;
     }
+
+    private static class IntForEachTerminalSink implements TerminalSink<Integer, Void>, Sink.OfInt {
+        private final IntBlock block;
+
+        public IntForEachTerminalSink(IntBlock block) {
+            this.block = block;
+        }
+
+        @Override
+        public void accept(int i) {
+            block.accept(i);
+        }
+
+        @Override
+        public Void getAndClearState() {
+            return null;
+        }
+    }
 }
--- a/src/share/classes/java/util/stream/op/GroupByOp.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/src/share/classes/java/util/stream/op/GroupByOp.java	Mon Nov 19 17:18:19 2012 +0100
@@ -75,7 +75,7 @@
             final ConcurrentHashMap<K, Collection<T>> map = new ConcurrentHashMap<>();
 
             // Cache the sink chain, so it can be reused by all F/J leaf tasks
-            Sink<S> sinkChain = helper.wrapSink(new Sink.OfValue<T>() {
+            Sink<S> sinkChain = helper.wrapSink(new Sink.OfReference<T>() {
                 @Override
                 public void accept(T t) {
                     final Collection<T> sb = map.computeIfAbsent(mapper.apply(t), (k) -> valueFactory.get());
--- a/src/share/classes/java/util/stream/op/MapOp.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/src/share/classes/java/util/stream/op/MapOp.java	Mon Nov 19 17:18:19 2012 +0100
@@ -55,7 +55,7 @@
 
     @Override
     public Sink<T> wrapSink(int flags, Sink sink) {
-        return new Sink.ChainedValue<T>(sink) {
+        return new Sink.ChainedReference<T>(sink) {
             @Override
             public void accept(T t) {
                 downstream.accept(mapper.apply(t));
--- a/src/share/classes/java/util/stream/op/NodeBuilder.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/src/share/classes/java/util/stream/op/NodeBuilder.java	Mon Nov 19 17:18:19 2012 +0100
@@ -34,7 +34,7 @@
  * @author Brian Goetz
  */
 // @@@ Implement Stream.Destination for bulk adding with addAll ? (see Nodes.node(Stream ) )
-public interface NodeBuilder<T> extends Iterable<T>, Sized, Sink.OfValue<T> {
+public interface NodeBuilder<T> extends Iterable<T>, Sized, Sink.OfReference<T> {
 
     /**
      * Build the node.
--- a/src/share/classes/java/util/stream/op/ReduceByOp.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/src/share/classes/java/util/stream/op/ReduceByOp.java	Mon Nov 19 17:18:19 2012 +0100
@@ -101,7 +101,7 @@
             final ConcurrentHashMap.Fun<? super U, ? extends W> seedFactoryAsCHMFun = (k) -> seedFactory.get();
 
             // Cache the sink chain, so it can be reused by all F/J leaf tasks
-            Sink<S> sinkChain = helper.wrapSink(new Sink.OfValue<T>() {
+            Sink<S> sinkChain = helper.wrapSink(new Sink.OfReference<T>() {
                 @Override
                 public void accept(T t) {
                     U key = classifier.apply(t);
--- a/src/share/classes/java/util/stream/op/SliceOp.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/src/share/classes/java/util/stream/op/SliceOp.java	Mon Nov 19 17:18:19 2012 +0100
@@ -76,7 +76,7 @@
     public Sink<T> wrapSink(int flags, Sink sink) {
         Objects.requireNonNull(sink);
         if (limit == -1) {
-            return new Sink.ChainedValue<T>(sink) {
+            return new Sink.ChainedReference<T>(sink) {
                 int n = skip;
 
                 @Override
--- a/src/share/classes/java/util/stream/op/SortedOp.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/src/share/classes/java/util/stream/op/SortedOp.java	Mon Nov 19 17:18:19 2012 +0100
@@ -76,7 +76,7 @@
         }
         else if (StreamOpFlags.SIZED.isKnown(flags)) {
             // Optimized version if we know the size
-            return new Sink.ChainedValue<T>(sink) {
+            return new Sink.ChainedReference<T>(sink) {
                 T[] array;
                 int offset;
 
@@ -102,7 +102,7 @@
             };
         }
         else {
-            return new Sink.ChainedValue<T>(sink) {
+            return new Sink.ChainedReference<T>(sink) {
                 ArrayList<T> list;
 
                 @Override
--- a/src/share/classes/java/util/stream/op/TeeOp.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/src/share/classes/java/util/stream/op/TeeOp.java	Mon Nov 19 17:18:19 2012 +0100
@@ -46,7 +46,7 @@
 
     @Override
     public Sink<T> wrapSink(int flags, Sink sink) {
-        return new Sink.ChainedValue<T>(sink) {
+        return new Sink.ChainedReference<T>(sink) {
             @Override
             public void accept(T t) {
                 tee.accept(t);
--- a/src/share/classes/java/util/stream/op/UniqOp.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/src/share/classes/java/util/stream/op/UniqOp.java	Mon Nov 19 17:18:19 2012 +0100
@@ -61,7 +61,7 @@
             return sink;
         }
         else if (StreamOpFlags.SORTED.isKnown(flags)) {
-            return new Sink.ChainedValue<T>(sink) {
+            return new Sink.ChainedReference<T>(sink) {
                 T lastSeen;
 
                 @Override
@@ -85,7 +85,7 @@
             };
         }
         else {
-            return new Sink.ChainedValue<T>(sink) {
+            return new Sink.ChainedReference<T>(sink) {
                 Set<T> seen;
 
                 @Override
@@ -203,7 +203,7 @@
                 final ConcurrentHashMap<T, Boolean> map = new ConcurrentHashMap<>();
 
                 // Cache the sink chain, so it can be reused by all F/J leaf tasks
-                Sink<S> sinkChain = helper.wrapSink(new Sink.OfValue<T>() {
+                Sink<S> sinkChain = helper.wrapSink(new Sink.OfReference<T>() {
                     @Override
                     public void accept(T t) {
                         map.putIfAbsent(t, Boolean.TRUE);
--- a/src/share/classes/java/util/stream/primitive/IntBlock.java	Mon Nov 19 15:19:28 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package java.util.stream.primitive;
-
-import java.util.function.Block;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-public interface IntBlock extends Block<Integer> {
-
-    @Override
-    default void accept(Integer i) {
-        Logger.getLogger(getClass().getName()).log(Level.WARNING, "{0} using boxed int", getClass().getName());
-        applyInt(i.intValue());
-    }
-
-    void applyInt(int i);
-}
--- a/src/share/classes/java/util/stream/primitive/IntFilterOp.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/src/share/classes/java/util/stream/primitive/IntFilterOp.java	Mon Nov 19 17:18:19 2012 +0100
@@ -57,15 +57,13 @@
     }
 
     @Override
-    public IntSink wrapSink(int flags, Sink sink) {
+    public Sink<Integer> wrapSink(int flags, Sink sink) {
         Objects.requireNonNull(sink);
-
-        IntSink intSink = Primitives.adapt(sink);
-        return new IntSink.ChainedValue(intSink) {
+        return new Sink.ChainedInt(sink) {
             @Override
-            public void applyInt(int t) {
+            public void accept(int t) {
                 if (predicate.testInt(t))
-                    downstream.applyInt(t);
+                    downstream.accept(t);
             }
         };
     }
--- a/src/share/classes/java/util/stream/primitive/IntForEachOp.java	Mon Nov 19 15:19:28 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package java.util.stream.primitive;
-
-import java.util.Objects;
-import java.util.stream.StreamShape;
-import java.util.stream.StreamShapeFactory;
-import java.util.stream.op.ForEachOp;
-
-public class IntForEachOp extends ForEachOp<Integer> {
-
-    protected IntForEachOp(IntTerminalSink<Void> sink, StreamShape shape) {
-        super(sink, shape);
-    }
-
-    public static IntForEachOp make(final IntBlock block) {
-        Objects.requireNonNull(block);
-        return new IntForEachOp(new IntTerminalSink<Void>() {
-
-            @Override
-            public void applyInt(int i) {
-                block.applyInt(i);
-            }
-
-            @Override
-            public Void getAndClearState() {
-                return null;
-            }
-        }, StreamShapeFactory.INT_VALUE);
-    }
-}
-
--- a/src/share/classes/java/util/stream/primitive/IntIterable.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/src/share/classes/java/util/stream/primitive/IntIterable.java	Mon Nov 19 17:18:19 2012 +0100
@@ -25,6 +25,7 @@
 package java.util.stream.primitive;
 
 import java.util.function.Block;
+import java.util.function.IntBlock;
 
 public interface IntIterable extends Iterable<Integer> {
 
@@ -49,7 +50,7 @@
     default void forEach(IntBlock sink) {
         IntIterator remaining = iterator();
         while (remaining.hasNext()) {
-            sink.applyInt(remaining.nextInt());
+            sink.accept(remaining.nextInt());
         }
     }
 }
--- a/src/share/classes/java/util/stream/primitive/IntIterator.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/src/share/classes/java/util/stream/primitive/IntIterator.java	Mon Nov 19 17:18:19 2012 +0100
@@ -26,6 +26,7 @@
 
 import java.util.Iterator;
 import java.util.function.Block;
+import java.util.function.IntBlock;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -58,7 +59,7 @@
 
     default void forEach(IntBlock sink) {
         while (hasNext()) {
-            sink.applyInt(nextInt());
+            sink.accept(nextInt());
         }
     }
 }
--- a/src/share/classes/java/util/stream/primitive/IntLimitOp.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/src/share/classes/java/util/stream/primitive/IntLimitOp.java	Mon Nov 19 17:18:19 2012 +0100
@@ -58,7 +58,7 @@
     }
 
     @Override
-    public IntSink wrapSink(int flags, Sink sink) {
+    public Sink wrapSink(int flags, Sink sink) {
         // @@@ Cannot short circuit the sink
         // @@@ This smells somewhat
         throw new UnsupportedOperationException();
--- a/src/share/classes/java/util/stream/primitive/IntMapOp.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/src/share/classes/java/util/stream/primitive/IntMapOp.java	Mon Nov 19 17:18:19 2012 +0100
@@ -26,6 +26,7 @@
 
 import java.util.Iterator;
 import java.util.Objects;
+import java.util.function.IntUnaryOperator;
 import java.util.stream.Sink;
 import java.util.stream.StreamOpFlags;
 import java.util.stream.StreamShape;
@@ -56,13 +57,11 @@
     }
 
     @Override
-    public IntSink wrapSink(int flags, Sink<Integer> sink) {
-        IntSink intSink = Primitives.adapt(Objects.requireNonNull(sink));
-
-        return new IntSink.ChainedValue(intSink) {
+    public Sink<Integer> wrapSink(int flags, Sink<Integer> sink) {
+        return new Sink.ChainedInt(sink) {
             @Override
-            public void applyInt(int t) {
-                downstream.applyInt(mapper.operateInt(t));
+            public void accept(int t) {
+                downstream.accept(mapper.operateAsInt(t));
             }
         };
     }
@@ -79,7 +78,7 @@
 
             @Override
             public int nextInt() {
-                return mapper.operateInt(intSource.nextInt());
+                return mapper.operateAsInt(intSource.nextInt());
             }
         };
     }
--- a/src/share/classes/java/util/stream/primitive/IntNodeBuilder.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/src/share/classes/java/util/stream/primitive/IntNodeBuilder.java	Mon Nov 19 17:18:19 2012 +0100
@@ -24,10 +24,12 @@
  */
 package java.util.stream.primitive;
 
+import java.util.function.IntUnaryOperator;
 import java.util.function.UnaryOperator;
+import java.util.stream.Sink;
 import java.util.stream.op.NodeBuilder;
 
-public interface IntNodeBuilder extends NodeBuilder<Integer>, IntIterable, IntSink {
+public interface IntNodeBuilder extends NodeBuilder<Integer>, IntIterable, Sink.OfInt {
 
     @Override
     IntNode build();
--- a/src/share/classes/java/util/stream/primitive/IntNodes.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/src/share/classes/java/util/stream/primitive/IntNodes.java	Mon Nov 19 17:18:19 2012 +0100
@@ -26,6 +26,10 @@
 
 import java.util.*;
 import java.util.function.Block;
+import java.util.function.IntBlock;
+import java.util.function.IntUnaryOperator;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 import java.util.stream.*;
 
 public class IntNodes {
@@ -79,7 +83,7 @@
         @Override
         public void forEach(IntBlock sink) {
             for (int i = 0; i < curSize; i++) {
-                sink.applyInt(array[i]);
+                sink.accept(array[i]);
             }
         }
 
@@ -327,7 +331,7 @@
                 }
                 else {
                     while (iterator.hasNext())
-                        block.applyInt(iterator.nextInt());
+                        block.accept(iterator.nextInt());
                 }
             }
 
@@ -401,7 +405,7 @@
         @Override
         public void forEachUpdate(IntUnaryOperator f) {
             for (int i = 0; i < curSize; i++) {
-                array[i] = f.operateInt(array[i]);
+                array[i] = f.operateAsInt(array[i]);
             }
         }
 
@@ -417,7 +421,7 @@
         }
 
         @Override
-        public void applyInt(int i) {
+        public void accept(int i) {
             if (curSize < array.length) {
                 array[curSize++] = i;
             } else {
@@ -548,7 +552,7 @@
         }
 
         @Override
-        public void applyInt(int i) {
+        public void accept(int i) {
             if (chunkIndex == chunk.length) {
                 increaseCapacity();
             }
@@ -661,7 +665,7 @@
                     iterator().forEach(block);
                 } else {
                     for (int i = offset; i < endOffset; i++) {
-                        block.applyInt(elements[i]);
+                        block.accept(elements[i]);
                     }
                     // update only once; reduce heap write traffic
                     offset = endOffset;
@@ -765,13 +769,13 @@
             for (int ci = 0; ci < spineIndex; ci++) {
                 int[] chunk = spine[ci];
                 for (int i = 0; i < chunk.length; i++) {
-                    block.applyInt(chunk[i]);
+                    block.accept(chunk[i]);
                 }
             }
 
             // current chunk
             for (int i = 0; i < chunkIndex; i++) {
-                block.applyInt(chunk[i]);
+                block.accept(chunk[i]);
             }
         }
 
@@ -781,7 +785,7 @@
                 int[] aChunk = spine[eachChunk];
                 int bounds = (eachChunk != spineIndex) ? aChunk.length : chunkIndex;
                 for (int element = 0; element < bounds; element++) {
-                    aChunk[element] = f.operateInt(aChunk[element]);
+                    aChunk[element] = f.operateAsInt(aChunk[element]);
                 }
             }
         }
@@ -796,8 +800,8 @@
         }
 
         @Override
-        public void applyInt(int i) {
-            super.applyInt(i);
+        public void accept(int i) {
+            super.accept(i);
         }
 
         @Override
--- a/src/share/classes/java/util/stream/primitive/IntPipeline.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/src/share/classes/java/util/stream/primitive/IntPipeline.java	Mon Nov 19 17:18:19 2012 +0100
@@ -26,9 +26,12 @@
 
 import java.util.Optional;
 import java.util.function.IntBinaryOperator;
+import java.util.function.IntBlock;
+import java.util.function.IntUnaryOperator;
 import java.util.stream.AbstractPipeline;
 import java.util.stream.Stream;
 import java.util.stream.StreamShapeFactory;
+import java.util.stream.op.ForEachOp;
 import java.util.stream.op.IntermediateOp;
 
 public class IntPipeline<E_IN> extends AbstractPipeline<E_IN, Integer> implements IntStream {
@@ -77,7 +80,7 @@
 
     @Override
     public void forEach(IntBlock block) {
-        pipeline(IntForEachOp.make(block));
+        pipeline(ForEachOp.make(block));
     }
 
     @Override
--- a/src/share/classes/java/util/stream/primitive/IntSink.java	Mon Nov 19 15:19:28 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package java.util.stream.primitive;
-
-import java.util.Objects;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import java.util.stream.Sink;
-
-public interface IntSink extends Sink<Integer>, IntBlock {
-
-    public static abstract class ChainedValue implements IntSink {
-        protected final IntSink downstream;
-
-        public ChainedValue(IntSink downstream) {
-            this.downstream = Objects.requireNonNull(downstream);
-        }
-
-        @Override
-        public void begin(int size) {
-            downstream.begin(size);
-        }
-
-        @Override
-        public void end() {
-            downstream.end();
-        }
-    }
-
-}
--- a/src/share/classes/java/util/stream/primitive/IntSortedOp.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/src/share/classes/java/util/stream/primitive/IntSortedOp.java	Mon Nov 19 17:18:19 2012 +0100
@@ -43,9 +43,9 @@
     }
 
     @Override
-    public IntSink wrapSink(int flags, Sink sink) {
-        IntSink intSink = Primitives.adapt(sink);
-        return new IntSink.ChainedValue(intSink) {
+    public Sink<Integer> wrapSink(int flags, Sink sink) {
+        Objects.requireNonNull(sink);
+        return new Sink.ChainedInt(sink) {
             IntNodeBuilder nb;
 
             @Override
@@ -59,14 +59,14 @@
                 Arrays.sort(ints);
                 downstream.begin(ints.length);
                 for (int i = 0; i < ints.length; i++) {
-                    downstream.applyInt(ints[i]);
+                    downstream.accept(ints[i]);
                 }
                 downstream.end();
             }
 
             @Override
-            public void applyInt(int t) {
-                nb.applyInt(t);
+            public void accept(int t) {
+                nb.accept(t);
             }
         };
     }
--- a/src/share/classes/java/util/stream/primitive/IntSpliterator.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/src/share/classes/java/util/stream/primitive/IntSpliterator.java	Mon Nov 19 17:18:19 2012 +0100
@@ -25,6 +25,7 @@
 package java.util.stream.primitive;
 
 import java.util.function.Block;
+import java.util.function.IntBlock;
 import java.util.stream.Spliterator;
 
 public interface IntSpliterator extends Spliterator<Integer> {
@@ -55,7 +56,7 @@
     default void forEach(IntBlock sink) {
         IntIterator remaining = iterator();
         while (remaining.hasNext()) {
-            sink.applyInt(remaining.nextInt());
+            sink.accept(remaining.nextInt());
         }
     }
 
--- a/src/share/classes/java/util/stream/primitive/IntStream.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/src/share/classes/java/util/stream/primitive/IntStream.java	Mon Nov 19 17:18:19 2012 +0100
@@ -25,6 +25,8 @@
 package java.util.stream.primitive;
 
 import java.util.function.IntBinaryOperator;
+import java.util.function.IntBlock;
+import java.util.function.IntUnaryOperator;
 import java.util.Collection;
 import java.util.Comparator;
 import java.util.Map;
--- a/src/share/classes/java/util/stream/primitive/IntSumOp.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/src/share/classes/java/util/stream/primitive/IntSumOp.java	Mon Nov 19 17:18:19 2012 +0100
@@ -24,10 +24,7 @@
  */
 package java.util.stream.primitive;
 
-import java.util.stream.ParallelPipelineHelper;
-import java.util.stream.PipelineHelper;
-import java.util.stream.StreamShape;
-import java.util.stream.StreamShapeFactory;
+import java.util.stream.*;
 import java.util.stream.op.OpUtils;
 import java.util.stream.op.TerminalOp;
 
@@ -48,7 +45,7 @@
         return OpUtils.parallelReduce(helper, () -> new SumIntSink());
     }
 
-    private class SumIntSink implements OpUtils.AccumulatingSink<Integer, Integer, SumIntSink>, IntSink {
+    private class SumIntSink implements OpUtils.AccumulatingSink<Integer, Integer, SumIntSink>, Sink.OfInt {
         int sum;
 
         @Override
@@ -69,7 +66,7 @@
         }
 
         @Override
-        public void applyInt(int t) {
+        public void accept(int t) {
             sum += t;
         }
 
--- a/src/share/classes/java/util/stream/primitive/IntTeeOp.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/src/share/classes/java/util/stream/primitive/IntTeeOp.java	Mon Nov 19 17:18:19 2012 +0100
@@ -24,6 +24,7 @@
  */
 package java.util.stream.primitive;
 
+import java.util.function.IntBlock;
 import java.util.Iterator;
 import java.util.Objects;
 import java.util.stream.Sink;
@@ -50,15 +51,13 @@
     }
 
     @Override
-    public IntSink wrapSink(int flags, Sink sink) {
+    public Sink<Integer> wrapSink(int flags, Sink sink) {
         Objects.requireNonNull(sink);
-
-        IntSink intSink = Primitives.adapt(sink);
-        return new IntSink.ChainedValue(intSink) {
+        return new Sink.ChainedInt(sink) {
             @Override
-            public void applyInt(int t) {
-                tee.applyInt(t);
-                downstream.applyInt(t);
+            public void accept(int t) {
+                tee.accept(t);
+                downstream.accept(t);
             }
         };
     }
@@ -77,7 +76,7 @@
             @Override
             public int nextInt() {
                 int next = intSource.next();
-                tee.applyInt(next);
+                tee.accept(next);
                 return next;
             }
         };
--- a/src/share/classes/java/util/stream/primitive/IntTerminalSink.java	Mon Nov 19 15:19:28 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-package java.util.stream.primitive;/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.util.stream.TerminalSink;
-
-public interface IntTerminalSink<T> extends TerminalSink<Integer, T>, IntSink {
-}
--- a/src/share/classes/java/util/stream/primitive/IntToIntegerOp.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/src/share/classes/java/util/stream/primitive/IntToIntegerOp.java	Mon Nov 19 17:18:19 2012 +0100
@@ -44,23 +44,13 @@
     }
 
     @Override
-    public IntSink wrapSink(int flags, final Sink sink) {
+    public Sink wrapSink(int flags, final Sink sink) {
         Objects.requireNonNull(sink);
 
-        return new IntSink() {
+        return new Sink.ChainedInt(sink) {
             @Override
-            public void begin(int size) {
-                sink.begin(size);
-            }
-
-            @Override
-            public void applyInt(int t) {
-                sink.accept(t);
-            }
-
-            @Override
-            public void end() {
-                sink.end();
+            public void accept(int t) {
+                downstream.accept(Integer.valueOf(t));
             }
         };
     }
--- a/src/share/classes/java/util/stream/primitive/IntUnaryOperator.java	Mon Nov 19 15:19:28 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package java.util.stream.primitive;
-
-import java.util.function.UnaryOperator;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-public interface IntUnaryOperator extends UnaryOperator<Integer> {
-
-    @Override
-    default Integer operate(Integer operand) {
-        Logger.getLogger(getClass().getName()).log(Level.WARNING, "{0} using boxed int", getClass().getName());
-        return operateInt(operand);
-    }
-
-    int operateInt(int operand);
-}
--- a/src/share/classes/java/util/stream/primitive/Primitives.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/src/share/classes/java/util/stream/primitive/Primitives.java	Mon Nov 19 17:18:19 2012 +0100
@@ -24,9 +24,12 @@
  */
 package java.util.stream.primitive;
 
+import java.util.function.IntBlock;
 import java.util.function.IntSupplier;
+import java.util.function.IntUnaryOperator;
 import java.util.*;
 import java.util.function.Block;
+import java.util.logging.Level;
 import java.util.logging.Logger;
 import java.util.stream.*;
 
@@ -41,6 +44,7 @@
             return (IntIterator) i;
         }
         else {
+            Logger.getLogger(Primitives.class.getName()).log(Level.WARNING, "Using Primitives.adapt(Iterator)");
             // @@@ throw UOE?
             return new IntIterator() {
                 @Override
@@ -61,107 +65,12 @@
         }
     }
 
-    // Adapt sink to int sink
-
-    public static IntSink adapt(final Sink<Integer> s) {
-        if (s instanceof IntSink) {
-            return (IntSink) s;
-        }
-        else {
-            // @@@ throw UOE?
-            return new IntSink() {
-                @Override
-                public void begin(int size) {
-                    s.begin(size);
-                }
-
-                @Override
-                public void applyInt(int i) {
-                    s.accept(i);
-                }
-
-                @Override
-                public void end() {
-                    s.end();
-                }
-            };
-        }
-    }
-
-    // Adapt block to int block
-
-    public static IntBlock adapt(final Block<Integer> b) {
-        if (b instanceof IntBlock) {
-            return (IntBlock) b;
-        }
-        else {
-            // @@@ throw UOE?
-            return new IntBlock() {
-                @Override
-                public void applyInt(int i) {
-                    b.accept(i);
-                }
-            };
-        }
-    }
-
-    //
+    // IntIterator
 
     public static IntIterator emptyIntIterator() {
         return EMPTY_INT_ITERATOR;
     }
 
-    private static final IntIterator EMPTY_INT_ITERATOR = new IntIterator() {
-        @Override
-        public int nextInt() {
-            throw new NoSuchElementException();
-        }
-
-        @Override
-        public boolean hasNext() {
-            return false;
-        }
-
-        @Override
-        public void forEach(IntBlock sink) {
-        }
-    };
-
-    public static IntSpliterator emptyIntSpliterator() {
-        return EMPTY_INT_SPLITERATOR;
-    }
-
-    private static final IntSpliterator EMPTY_INT_SPLITERATOR = new IntSpliterator() {
-        @Override
-        public int getNaturalSplits() {
-            return 0;
-        }
-
-        @Override
-        public IntSpliterator split() {
-            return EMPTY_INT_SPLITERATOR;
-        }
-
-        @Override
-        public IntIterator iterator() {
-            return EMPTY_INT_ITERATOR;
-        }
-
-        @Override
-        public void forEach(IntBlock sink) {
-        }
-
-        @Override
-        public int getSizeIfKnown() {
-            return 0;
-        }
-
-        @Override
-        public boolean isPredictableSplits() {
-            return true;
-        }
-    };
-
     public static IntIterator iterator(int[] array) {
         return iterator(array, 0, array.length);
     }
@@ -171,109 +80,91 @@
         return new IntArrayIterator(array, offset, length);
     }
 
-    private static class IntArrayIterator implements IntIterator {
-        final int[] array;
-        int o;
-        final int e;
+    // IntSpliterator
 
-        private IntArrayIterator(int[] array, int offset, int length) {
-            this.array = array;
-            this.o = offset;
-            this.e = offset + length;
-        }
-
-        @Override
-        public boolean hasNext() {
-            return o < e;
-        }
-
-        @Override
-        public int nextInt() {
-            if (!hasNext()) {
-                throw new NoSuchElementException();
-            }
-
-            return array[o++];
-        }
-
-        @Override
-        public void forEach(IntBlock sink) {
-            if (hasNext()) {
-                for (int i = o; i < e; i++) {
-                    sink.applyInt(array[i]);
-                }
-                o = e;
-            }
-        }
-
-        @Override
-        public void forEach(Block<? super Integer> sink) {
-            IntIterator.super.forEach(sink);
-        }
+    public static IntSpliterator emptyIntSpliterator() {
+        return EMPTY_INT_SPLITERATOR;
     }
 
-    public static IntIterator concat(final IntIterator i1, final IntIterator i2) {
-        Objects.requireNonNull(i1);
-        Objects.requireNonNull(i2);
-
-        return concat(Arrays.asList(i1, i2).iterator());
+    public static<T extends Sized & IntIterable> IntSpliterator sequentialSpliterator(T entity) {
+        Objects.requireNonNull(entity);
+        return new IntIterableSequentialSpliterator(entity, entity);
     }
 
-    public static IntIterator concat(final Iterator<IntIterator> iterators) {
-        Objects.requireNonNull(iterators);
-
-        if (!iterators.hasNext())
-            return EMPTY_INT_ITERATOR;
-
-        return new IntIterator() {
-            private IntIterator it = Objects.requireNonNull(iterators.next());
-            // Need to retain a reference to the last iterator used with next()
-            // so that remove() can use that reference for deferral and check for two or more calls,
-            // and because hasNext() may update "it" to the next iterator
-            private IntIterator itForRemove = null;
-
-            @Override
-            public boolean hasNext() {
-                while (!it.hasNext()) {
-                    if (!iterators.hasNext()) {
-                        return false;
-                    }
-                    it = Objects.requireNonNull(iterators.next());
-                }
-
-                return true;
-            }
-
-            public int nextInt() {
-                if (!hasNext()) {
-                    throw new NoSuchElementException();
-                }
-
-                itForRemove = it;
-                return it.nextInt();
-            }
-
-            @Override
-            public void remove() {
-                if (itForRemove == null) {
-                    throw new IllegalStateException();
-                }
-
-                itForRemove.remove();
-                itForRemove = null;
-            }
-        };
+    public static<T extends IntIterable> IntSpliterator sequentialSpliterator(T entity, Sized sizeProvider) {
+        Objects.requireNonNull(entity);
+        Objects.requireNonNull(sizeProvider);
+        return new IntIterableSequentialSpliterator(entity, sizeProvider);
     }
 
-    // Infinite int streams
+    public static<T extends IntIterable> IntSpliterator sequentialSpliterator(T entity) {
+        Objects.requireNonNull(entity);
+        return new IntIterableSequentialSpliterator(entity);
+    }
 
-    private static interface IntInfiniteIterator extends IntIterator {
-        @Override
-        default boolean hasNext() {
-            return true;
-        }
+    public static<T extends IntIterator> IntSpliterator sequentialSpliterator(T iterator) {
+        Objects.requireNonNull(iterator);
+        return (IntSpliterator.Sequential) () -> iterator;
     }
 
+    public static IntSpliterator spliterator(int[] array) {
+        return spliterator(array, 0, array.length);
+    }
+
+    public static IntSpliterator spliterator(int[] array, int offset, int length) {
+        return new IntArraySpliterator(array, offset, length);
+    }
+
+    // IntStream
+
+    public static IntStream emptyIntStream() {
+        return stream(emptyIntSpliterator(), 0);
+    }
+
+    public static<T extends Sized & IntIterable> IntStream stream(T entity, int flags) {
+        return stream(sequentialSpliterator(entity), flags);
+    }
+
+    public static IntStream stream(IntIterable entity, Sized sizeProvider, int flags) {
+        return stream(sequentialSpliterator(entity, sizeProvider), flags);
+    }
+
+    public static IntStream stream(IntIterable entity, int flags) {
+        return stream(sequentialSpliterator(entity), flags);
+    }
+
+    public static IntStream stream(IntIterator entity, int flags) {
+        return stream(sequentialSpliterator(entity), flags);
+    }
+
+    public static IntStream stream(int[] source) {
+        return stream(source, 0, source.length);
+    }
+
+    public static IntStream stream(int[] source, int offset, int length) {
+        return stream(spliterator(source, offset, length),
+                      StreamOpFlags.IS_SIZED | StreamOpFlags.IS_ORDERED);
+    }
+
+    public static IntStream parallel(int[] source) {
+        return parallel(source, 0, source.length);
+    }
+
+    public static IntStream parallel(int[] source, int offset, int length) {
+        return parallel(spliterator(source, offset, length),
+                        StreamOpFlags.IS_SIZED | StreamOpFlags.IS_ORDERED);
+    }
+
+    public static IntStream stream(IntSpliterator spliterator, int flags) {
+        return new IntPipeline<>(spliterator, flags & ~StreamOpFlags.IS_PARALLEL);
+    }
+
+    public static IntStream parallel(IntSpliterator spliterator, int flags) {
+        return new IntPipeline<>(spliterator, flags | StreamOpFlags.IS_PARALLEL);
+    }
+
+    // Infinite Intstream
+
     public static IntStream iterate(final int seed, final IntUnaryOperator f) {
         Objects.requireNonNull(f);
         final IntInfiniteIterator iterator = new IntInfiniteIterator() {
@@ -282,7 +173,7 @@
             @Override
             public int nextInt() {
                 int v = t;
-                t = f.operateInt(t);
+                t = f.operateAsInt(t);
                 return v;
             }
         };
@@ -356,8 +247,187 @@
         return stream(cycle, StreamOpFlags.IS_ORDERED);
     }
 
+    // Range IntStream
 
-    //
+    public static IntStream range(final int from, final int upTo) {
+        return range(from, upTo, 1);
+    }
+
+    public static IntStream range(final int from, final int upTo, final int step) {
+        IntSpliterator s = new RangeIntSpliterator(from, upTo, step);
+        return stream(s, StreamOpFlags.IS_SIZED | StreamOpFlags.IS_ORDERED);
+    }
+
+    public static IntStream parRange(final int from, final int upTo) {
+        return parRange(from, upTo, 1);
+    }
+
+    public static IntStream parRange(final int from, final int upTo, final int step) {
+        IntSpliterator s = new RangeIntSpliterator(from, upTo, step);
+        return parallel(s, StreamOpFlags.IS_SIZED | StreamOpFlags.IS_ORDERED);
+    }
+
+    // Create Sink from arrays
+
+    public static Sink sink(int[] array) {
+        return sink(array, 0, array.length);
+    }
+
+    public static Sink sink(int[] array, int offset, int length) {
+        return new IntArraySink(array, offset, length);
+    }
+
+    // Concat
+
+    public static IntIterator concat(final IntIterator i1, final IntIterator i2) {
+        Objects.requireNonNull(i1);
+        Objects.requireNonNull(i2);
+
+        return concat(Arrays.asList(i1, i2).iterator());
+    }
+
+    public static IntIterator concat(final Iterator<IntIterator> iterators) {
+        Objects.requireNonNull(iterators);
+
+        if (!iterators.hasNext())
+            return EMPTY_INT_ITERATOR;
+
+        return new IntIterator() {
+            private IntIterator it = Objects.requireNonNull(iterators.next());
+            // Need to retain a reference to the last iterator used with next()
+            // so that remove() can use that reference for deferral and check for two or more calls,
+            // and because hasNext() may update "it" to the next iterator
+            private IntIterator itForRemove = null;
+
+            @Override
+            public boolean hasNext() {
+                while (!it.hasNext()) {
+                    if (!iterators.hasNext()) {
+                        return false;
+                    }
+                    it = Objects.requireNonNull(iterators.next());
+                }
+
+                return true;
+            }
+
+            public int nextInt() {
+                if (!hasNext()) {
+                    throw new NoSuchElementException();
+                }
+
+                itForRemove = it;
+                return it.nextInt();
+            }
+
+            @Override
+            public void remove() {
+                if (itForRemove == null) {
+                    throw new IllegalStateException();
+                }
+
+                itForRemove.remove();
+                itForRemove = null;
+            }
+        };
+    }
+
+    // Implementations
+
+    private static final IntIterator EMPTY_INT_ITERATOR = new IntIterator() {
+        @Override
+        public int nextInt() {
+            throw new NoSuchElementException();
+        }
+
+        @Override
+        public boolean hasNext() {
+            return false;
+        }
+
+        @Override
+        public void forEach(IntBlock sink) {
+        }
+    };
+
+    private static final IntSpliterator EMPTY_INT_SPLITERATOR = new IntSpliterator() {
+        @Override
+        public int getNaturalSplits() {
+            return 0;
+        }
+
+        @Override
+        public IntSpliterator split() {
+            return EMPTY_INT_SPLITERATOR;
+        }
+
+        @Override
+        public IntIterator iterator() {
+            return EMPTY_INT_ITERATOR;
+        }
+
+        @Override
+        public void forEach(IntBlock sink) {
+        }
+
+        @Override
+        public int getSizeIfKnown() {
+            return 0;
+        }
+
+        @Override
+        public boolean isPredictableSplits() {
+            return true;
+        }
+    };
+
+    private static class IntArrayIterator implements IntIterator {
+        final int[] array;
+        int o;
+        final int e;
+
+        private IntArrayIterator(int[] array, int offset, int length) {
+            this.array = array;
+            this.o = offset;
+            this.e = offset + length;
+        }
+
+        @Override
+        public boolean hasNext() {
+            return o < e;
+        }
+
+        @Override
+        public int nextInt() {
+            if (!hasNext()) {
+                throw new NoSuchElementException();
+            }
+
+            return array[o++];
+        }
+
+        @Override
+        public void forEach(IntBlock sink) {
+            if (hasNext()) {
+                for (int i = o; i < e; i++) {
+                    sink.accept(array[i]);
+                }
+                o = e;
+            }
+        }
+
+        @Override
+        public void forEach(Block<? super Integer> sink) {
+            IntIterator.super.forEach(sink);
+        }
+    }
+
+    private static interface IntInfiniteIterator extends IntIterator {
+        @Override
+        default boolean hasNext() {
+            return true;
+        }
+    }
 
     private static class IntArraySpliterator extends IntArrayIterator implements IntSpliterator {
         private boolean traversing = false;
@@ -412,17 +482,17 @@
         }
     }
 
-    private static class ArrayIntSink implements IntSink {
+    private static class IntArraySink implements Sink.OfInt {
         private final int[] array;
         private final int offset;
         private int o;
         private final int e;
 
-        ArrayIntSink(int[] array) {
+        IntArraySink(int[] array) {
             this(array, 0, array.length);
         }
 
-        ArrayIntSink(int[] array, int offset, int length) {
+        IntArraySink(int[] array, int offset, int length) {
             this.array = Objects.requireNonNull(array);
             this.offset = offset;
             this.o = offset;
@@ -439,7 +509,7 @@
         }
 
         @Override
-        public void applyInt(int t) {
+        public void accept(int t) {
             if (o >= e) {
                 throw new IndexOutOfBoundsException(Integer.toString(o));
             }
@@ -555,166 +625,50 @@
         }
     }
 
-    // Create IntStream from range
+    private static class IntIterableSequentialSpliterator implements IntSpliterator.Sequential {
+        private final IntIterable iterable;
+        private final Sized sizeProvider;
 
-    public static IntStream range(final int from, final int upTo) {
-        return range(from, upTo, 1);
-    }
+        private IntIterator iterator;
+        private int size;
 
-    public static IntStream range(final int from, final int upTo, final int step) {
-        IntSpliterator s = new RangeIntSpliterator(from, upTo, step);
-        return stream(s, StreamOpFlags.IS_SIZED | StreamOpFlags.IS_ORDERED);
-    }
+        private IntIterableSequentialSpliterator(IntIterable iterable) {
+            this(iterable, null);
+        }
 
-    // Create parallel IntStream from range
+        private IntIterableSequentialSpliterator(IntIterable iterable, Sized sizeProvider) {
+            this.iterable = iterable;
+            this.sizeProvider = sizeProvider;
+        }
 
-    public static IntStream parRange(final int from, final int upTo) {
-        return parRange(from, upTo, 1);
-    }
+        private void initiate() {
+            if (iterator == null) {
+                iterator = iterable.iterator();
+                size = (sizeProvider != null) ? sizeProvider.size() : -1;
+            }
+        }
 
-    public static IntStream parRange(final int from, final int upTo, final int step) {
-        IntSpliterator s = new RangeIntSpliterator(from, upTo, step);
-        return stream(s, StreamOpFlags.IS_SIZED | StreamOpFlags.IS_ORDERED | StreamOpFlags.IS_PARALLEL);
-    }
+        @Override
+        public IntIterator iterator() {
+            initiate();
+            return iterator;
+        }
 
-    // Create Spliterator from arrays
+        @Override
+        public int getSizeIfKnown() {
+            initiate();
+            return size;
+        }
 
-    public static IntSpliterator spliterator(int[] array) {
-        return spliterator(array, 0, array.length);
-    }
-
-    public static IntSpliterator spliterator(int[] array, int offset, int length) {
-        return new IntArraySpliterator(array, offset, length);
-    }
-
-    // Create Sink from arrays
-
-    public static IntSink sink(int[] array) {
-        return sink(array, 0, array.length);
-    }
-
-    public static IntSink sink(int[] array, int offset, int length) {
-        return new ArrayIntSink(array, offset, length);
-    }
-
-    // Create IntStream from IntIterable and IntIterator
-
-    public static<T extends Sized & IntIterable> IntStream stream(T entity, int flags) {
-        return toStream(new IntSpliterator.Sequential() {
-            @Override
-            public IntIterator iterator() {
-                return entity.iterator();
+        @Override
+        public void forEach(IntBlock block) {
+            if (iterator == null) {
+                iterable.forEach(block);
+                iterator = emptyIntIterator();
+                size = 0;
             }
-
-            @Override
-            public void forEach(IntBlock block) {
-                entity.forEach(block);
-            }
-
-            @Override
-            public int getSizeIfKnown() {
-                return entity.size();
-            }
-        }, StreamOpFlags.IS_SIZED | flags);
-    }
-
-    public static IntStream stream(IntIterable entity, Sized sizeProvider, int flags) {
-        return toStream(new IntSpliterator.Sequential() {
-            @Override
-            public IntIterator iterator() {
-                return entity.iterator();
-            }
-
-            @Override
-            public void forEach(IntBlock block) {
-                entity.forEach(block);
-            }
-
-            @Override
-            public int getSizeIfKnown() {
-                return sizeProvider.size();
-            }
-        }, StreamOpFlags.IS_SIZED | flags);
-    }
-
-    public static IntStream stream(IntIterable entity, int flags) {
-        return toStream(new IntSpliterator.Sequential() {
-            @Override
-            public IntIterator iterator() {
-                return entity.iterator();
-            }
-
-            @Override
-            public void forEach(IntBlock block) {
-                entity.forEach(block);
-            }
-            // @@@ Mask off sized if set ?
-        }, flags);
-    }
-
-    public static IntStream stream(IntIterator entity, int flags) {
-        return toStream(new IntSpliterator.Sequential() {
-            @Override
-            public IntIterator iterator() {
-                return entity;
-            }
-
-            @Override
-            public void forEach(IntBlock block) {
-                entity.forEach(block);
-            }
-            // @@@ Mask off sized if set ?
-        }, flags);
-    }
-
-    // Create IntStream from array
-
-    public static IntStream stream(int[] source) {
-        return stream(source, 0, source.length);
-    }
-
-    public static IntStream stream(int[] source, int offset, int length) {
-        // Note use of full-service Spliterator here -- harmless because PARALLEL flag is not set
-        return toStream(spliterator(source, offset, length),
-                        StreamOpFlags.IS_SIZED | StreamOpFlags.IS_ORDERED);
-    }
-
-    // Create IntStream from IntSpliterator
-
-    public static IntStream stream(IntSpliterator spliterator, int flags) {
-        if (spliterator.getSizeIfKnown() >= 0)
-            flags |= StreamOpFlags.IS_SIZED;
-        return toStream(spliterator, flags);
-    }
-
-    // Create parallel IntStream from array
-
-    public static IntStream parallel(int[] source) {
-        return parallel(source, 0, source.length);
-    }
-
-    public static IntStream parallel(int[] source, int offset, int length) {
-        return toStream(spliterator(source, offset, length),
-                        StreamOpFlags.IS_SIZED | StreamOpFlags.IS_ORDERED | StreamOpFlags.IS_PARALLEL);
-    }
-
-    // Create parallel IntStream from IntSpliterator
-
-    public static IntStream parallel(IntSpliterator spliterator, int flags) {
-        if (spliterator.getSizeIfKnown() >= 0)
-            flags |= StreamOpFlags.IS_SIZED;
-        return toStream(spliterator, flags | StreamOpFlags.IS_PARALLEL);
-    }
-
-    //
-
-    public static IntStream emptyIntStream() {
-        return stream(emptyIntSpliterator(), 0);
-    }
-
-    //
-
-    private static IntStream toStream(IntSpliterator sp, int flags) {
-        return new IntPipeline<>(sp, flags);
+            else
+                iterator.forEach(block);
+        }
     }
 }
--- a/src/share/classes/java/util/stream/primitive/RefToIntMapOp.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/src/share/classes/java/util/stream/primitive/RefToIntMapOp.java	Mon Nov 19 17:18:19 2012 +0100
@@ -61,21 +61,10 @@
     public Sink<T> wrapSink(int flags, Sink sink) {
         Objects.requireNonNull(sink);
 
-        IntSink intSink = Primitives.adapt(sink);
-        return new Sink<T>() {
-            @Override
-            public void begin(int size) {
-                intSink.begin(size);
-            }
-
+        return new Sink.ChainedReference<T>(sink) {
             @Override
             public void accept(T t) {
-                intSink.applyInt(mapper.apply(t));
-            }
-
-            @Override
-            public void end() {
-                intSink.end();
+                downstream.accept(mapper.applyAsInt(t));
             }
         };
     }
--- a/test-ng/tests/org/openjdk/tests/java/lang/PrimitiveSumMinMaxTest.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/test-ng/tests/org/openjdk/tests/java/lang/PrimitiveSumMinMaxTest.java	Mon Nov 19 17:18:19 2012 +0100
@@ -52,11 +52,11 @@
         for (int i : numbers) {
             for (int j : numbers) {
                 assertEquals(i+j, (int) sum1.operate(i, j));
-                assertEquals(i+j, sum2.operate(i, j));
+                assertEquals(i+j, sum2.operateAsInt(i, j));
                 assertEquals(Math.max(i,j), (int) max1.operate(i, j));
-                assertEquals(Math.max(i,j), max2.operate(i, j));
+                assertEquals(Math.max(i,j), max2.operateAsInt(i, j));
                 assertEquals(Math.min(i,j), (int) min1.operate(i, j));
-                assertEquals(Math.min(i,j), min2.operate(i, j));
+                assertEquals(Math.min(i,j), min2.operateAsInt(i, j));
                 assertEquals(((Integer) i).compareTo(j), cmp.compare(i, j));
             }
         }
--- a/test-ng/tests/org/openjdk/tests/java/util/LambdaTestHelpers.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/test-ng/tests/org/openjdk/tests/java/util/LambdaTestHelpers.java	Mon Nov 19 17:18:19 2012 +0100
@@ -42,6 +42,8 @@
     @SuppressWarnings("rawtypes")
     public static final Block bEmpty = x -> {  };
     @SuppressWarnings("rawtypes")
+    public static final IntBlock bIntEmpty = x -> {  };
+    @SuppressWarnings("rawtypes")
     public static final BiBlock bBiEmpty = (x,y) -> { };
     @SuppressWarnings("rawtypes")
     public static final Block bHashCode = x -> { Objects.hashCode(x); };
--- a/test-ng/tests/org/openjdk/tests/java/util/function/DoubleUnaryOperatorTest.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/test-ng/tests/org/openjdk/tests/java/util/function/DoubleUnaryOperatorTest.java	Mon Nov 19 17:18:19 2012 +0100
@@ -25,11 +25,7 @@
 package org.openjdk.tests.java.util.function;
 
 import java.util.function.DoubleUnaryOperator;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.AfterClass;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Test;
+
 import static org.testng.Assert.*;
 
 /**
@@ -45,13 +41,13 @@
         double operand = 2D;
         DoubleUnaryOperator instance = new DoubleUnaryOperatorImpl();
         double expResult = 10D;
-        double result = instance.operate(operand);
+        double result = instance.operateAsDouble(operand);
         assertEquals(result, expResult, 0.1D /* delta for equality test */ );
     }
 
     public class DoubleUnaryOperatorImpl implements DoubleUnaryOperator {
 
-        public double operate(double operand) {
+        public double operateAsDouble(double operand) {
             // multiply by 5
             return operand * 5D;
         }
--- a/test-ng/tests/org/openjdk/tests/java/util/function/IntUnaryOperatorTest.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/test-ng/tests/org/openjdk/tests/java/util/function/IntUnaryOperatorTest.java	Mon Nov 19 17:18:19 2012 +0100
@@ -43,10 +43,10 @@
      * Test of operate method, of class IntUnaryOperator.
      */
     public void testOperate() {
-        Integer operand = 3;
+        int operand = 3;
         IntUnaryOperator instance = new IncByTwo();
         int expResult = 5;
-        int result = instance.operate(operand);
+        int result = instance.operateAsInt(operand);
         assertEquals(result, expResult);
     }
 
@@ -56,7 +56,7 @@
         assertEquals( op.operate(operand), op.operate(operand));
         assertEquals( operand.intValue(), 7 );
     }
-    
+
     public void testUpdateOps() {
         AtomicInteger atomInt = new AtomicInteger(3);
         // make sure we the updated value is returned
@@ -70,7 +70,7 @@
     public class IncByTwo implements IntUnaryOperator {
 
         @Override
-        public int operate(int operand) {
+        public int operateAsInt(int operand) {
             return operand+2;
         }
     }
--- a/test-ng/tests/org/openjdk/tests/java/util/function/LongUnaryOperatorTest.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/test-ng/tests/org/openjdk/tests/java/util/function/LongUnaryOperatorTest.java	Mon Nov 19 17:18:19 2012 +0100
@@ -26,10 +26,7 @@
 
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.function.LongUnaryOperator;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.AfterClass;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.BeforeClass;
+
 import org.testng.annotations.Test;
 import static org.testng.Assert.*;
 
@@ -51,7 +48,7 @@
         long operand = 0L;
         LongUnaryOperator instance = new LongUnaryOperatorImpl();
         long expResult = 3L;
-        long result = instance.operate(operand);
+        long result = instance.operateAsLong(operand);
         assertEquals(result, expResult);
     }
     
@@ -67,7 +64,7 @@
     
     public class LongUnaryOperatorImpl implements LongUnaryOperator {
 
-        public long operate(long operand) {
+        public long operateAsLong(long operand) {
             // inc by 3
             return operand + 3L;
         }
--- a/test-ng/tests/org/openjdk/tests/java/util/stream/OpTestCase.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/test-ng/tests/org/openjdk/tests/java/util/stream/OpTestCase.java	Mon Nov 19 17:18:19 2012 +0100
@@ -481,5 +481,15 @@
         public int getOpFlags() {
             return StreamOpFlags.IS_SHORT_CIRCUIT;
         }
+
+        @Override
+        public StreamShape outputShape() {
+            return shape;
+        }
+
+        @Override
+        public StreamShape inputShape() {
+            return shape;
+        }
     }
 }
--- a/test-ng/tests/org/openjdk/tests/java/util/stream/op/ForEachOpTest.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/test-ng/tests/org/openjdk/tests/java/util/stream/op/ForEachOpTest.java	Mon Nov 19 17:18:19 2012 +0100
@@ -32,6 +32,8 @@
 import org.openjdk.tests.java.util.stream.OpTestCase;
 import org.openjdk.tests.java.util.stream.StreamTestData;
 import org.openjdk.tests.java.util.stream.StreamTestDataProvider;
+import org.openjdk.tests.java.util.stream.primitive.IntStreamTestData;
+import org.openjdk.tests.java.util.stream.primitive.IntStreamTestDataProvider;
 import org.testng.annotations.Test;
 
 import static org.openjdk.tests.java.util.LambdaTestHelpers.*;
@@ -63,4 +65,13 @@
        // @@@ assert contents, unordered or parallel evaluation
        exerciseTerminalOps(data, s -> { s.forEach(bEmpty); return null; });
     }
+
+    // @@@ Move out into separate test class
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    @SuppressWarnings("unchecked")
+    public void testIntOps(String name, IntStreamTestData data) {
+        // @@@ assert contents, unordered or parallel evaluation
+        exerciseTerminalOps(data, s -> { s.forEach(bIntEmpty); return null; });
+    }
 }
--- a/test-ng/tests/org/openjdk/tests/java/util/stream/op/IntNodeTest.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/test-ng/tests/org/openjdk/tests/java/util/stream/op/IntNodeTest.java	Mon Nov 19 17:18:19 2012 +0100
@@ -91,9 +91,8 @@
 
     IntNode fill(int[] array, IntNodeBuilder nb) {
         nb.begin(array.length);
-        for (Integer i : array) {
-            nb.applyInt(i);
-        }
+        for (int i : array)
+            nb.accept(i);
         nb.end();
         return nb.build();
     }
--- a/test-ng/tests/org/openjdk/tests/java/util/stream/op/NodeBuilderTest.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/test-ng/tests/org/openjdk/tests/java/util/stream/op/NodeBuilderTest.java	Mon Nov 19 17:18:19 2012 +0100
@@ -74,7 +74,7 @@
     public void testIteration(List<Integer> l, Function<Integer, NodeBuilder<Integer>> m) {
         NodeBuilder<Integer> nb = m.apply(l.size());
         nb.begin(l.size());
-        for (int i : l) {
+        for (Integer i : l) {
             nb.accept(i);
         }
         nb.end();
@@ -104,7 +104,7 @@
     public void testUpdate(List<Integer> l, Function<Integer, NodeBuilder<Integer>> m) {
         NodeBuilder<Integer> nb = m.apply(l.size());
         nb.begin(l.size());
-        for (int i : l) {
+        for (Integer i : l) {
             nb.accept(i);
         }
         nb.end();
--- a/test-ng/tests/org/openjdk/tests/java/util/stream/primitive/IntStreamTestScenario.java	Mon Nov 19 15:19:28 2012 +0100
+++ b/test-ng/tests/org/openjdk/tests/java/util/stream/primitive/IntStreamTestScenario.java	Mon Nov 19 17:18:19 2012 +0100
@@ -28,11 +28,11 @@
 
 import java.util.Iterator;
 import java.util.function.Block;
+import java.util.function.IntBlock;
 import java.util.function.Function;
 import java.util.stream.*;
 import java.util.stream.op.FlagDeclaringOp;
 import java.util.stream.op.IntermediateOp;
-import java.util.stream.primitive.IntBlock;
 import java.util.stream.primitive.IntIterator;
 import java.util.stream.primitive.IntStream;
 
@@ -48,7 +48,7 @@
     STREAM_TO_ARRAY(false) {
         <T, S_IN extends BaseStream<T>> void _run(OpTestCase.TestData<T, S_IN> data, IntBlock b, Function<S_IN, IntStream> m) {
             for (int t : m.apply(data.stream()).toArray()) {
-                b.applyInt(t);
+                b.accept(t);
             }
         }
     },
@@ -56,7 +56,7 @@
     STREAM_ITERATOR(false) {
         <T, S_IN extends BaseStream<T>> void _run(OpTestCase.TestData<T, S_IN> data, IntBlock b, Function<S_IN, IntStream> m) {
             for (IntIterator seqIter = m.apply(data.stream()).iterator(); seqIter.hasNext(); )
-                b.applyInt(seqIter.nextInt());
+                b.accept(seqIter.nextInt());
         }
     },
 
@@ -69,7 +69,7 @@
     PAR_STREAM_TO_ARRAY(true) {
         <T, S_IN extends BaseStream<T>> void _run(OpTestCase.TestData<T, S_IN> data, IntBlock b, Function<S_IN, IntStream> m) {
             for (int t : m.apply(data.parallel()).toArray())
-                b.applyInt(t);
+                b.accept(t);
         }
     },
 
@@ -89,7 +89,7 @@
             IntStream pipe2 = m.apply((S_IN) pipe1);
 
             for (int t : pipe2.toArray())
-                b.applyInt(t);
+                b.accept(t);
         }
     },